aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalle Valo <kvalo@codeaurora.org>2016-07-18 15:50:44 -0400
committerKalle Valo <kvalo@codeaurora.org>2016-07-18 15:50:44 -0400
commitcf8c581a0081364ab50e9d93678a778cc0fb1a0a (patch)
tree41e04933e433ca7de70124f7afde9bd85514ed38
parent643d09f4618196d05ecf9b6987c890280ffac9d8 (diff)
parentc11e99396d0f77b5a6adc25f7c7bd84750194724 (diff)
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for 4.8. Major changes: ath10k * enable support for QCA9888
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c28
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h9
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c19
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.h11
-rw-r--r--drivers/net/wireless/ath/ath10k/debugfs_sta.c74
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c10
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c22
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.c15
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h33
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c43
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c24
-rw-r--r--drivers/net/wireless/ath/ath10k/spectral.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c6
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c67
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c240
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/dynack.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c54
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c54
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c73
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c2
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.c31
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.h7
-rw-r--r--drivers/net/wireless/ath/wcn36xx/hal.h4
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c67
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.c44
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.h4
-rw-r--r--drivers/net/wireless/ath/wcn36xx/wcn36xx.h10
-rw-r--r--include/linux/ath9k_platform.h1
36 files changed, 626 insertions, 367 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index dfb3db0ee5d1..e88982921aa3 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -207,6 +207,28 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
207 }, 207 },
208 }, 208 },
209 { 209 {
210 .id = QCA9888_HW_2_0_DEV_VERSION,
211 .dev_id = QCA9888_2_0_DEVICE_ID,
212 .name = "qca9888 hw2.0",
213 .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
214 .uart_pin = 7,
215 .otp_exe_param = 0x00000700,
216 .continuous_frag_desc = true,
217 .channel_counters_freq_hz = 150000,
218 .max_probe_resp_desc_thres = 24,
219 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
220 .tx_chain_mask = 3,
221 .rx_chain_mask = 3,
222 .max_spatial_stream = 2,
223 .cal_data_len = 12064,
224 .fw = {
225 .dir = QCA9888_HW_2_0_FW_DIR,
226 .board = QCA9888_HW_2_0_BOARD_DATA_FILE,
227 .board_size = QCA99X0_BOARD_DATA_SZ,
228 .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
229 },
230 },
231 {
210 .id = QCA9377_HW_1_0_DEV_VERSION, 232 .id = QCA9377_HW_1_0_DEV_VERSION,
211 .dev_id = QCA9377_1_0_DEVICE_ID, 233 .dev_id = QCA9377_1_0_DEVICE_ID,
212 .name = "qca9377 hw1.0", 234 .name = "qca9377 hw1.0",
@@ -1675,7 +1697,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
1675 case ATH10K_FW_WMI_OP_VERSION_10_4: 1697 case ATH10K_FW_WMI_OP_VERSION_10_4:
1676 case ATH10K_FW_WMI_OP_VERSION_UNSET: 1698 case ATH10K_FW_WMI_OP_VERSION_UNSET:
1677 case ATH10K_FW_WMI_OP_VERSION_MAX: 1699 case ATH10K_FW_WMI_OP_VERSION_MAX:
1678 WARN_ON(1); 1700 ath10k_err(ar, "htt op version not found from fw meta data");
1679 return -EINVAL; 1701 return -EINVAL;
1680 } 1702 }
1681 } 1703 }
@@ -2171,6 +2193,10 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
2171 ar->regs = &qca99x0_regs; 2193 ar->regs = &qca99x0_regs;
2172 ar->hw_values = &qca99x0_values; 2194 ar->hw_values = &qca99x0_values;
2173 break; 2195 break;
2196 case ATH10K_HW_QCA9888:
2197 ar->regs = &qca99x0_regs;
2198 ar->hw_values = &qca9888_values;
2199 break;
2174 case ATH10K_HW_QCA4019: 2200 case ATH10K_HW_QCA4019:
2175 ar->regs = &qca4019_regs; 2201 ar->regs = &qca4019_regs;
2176 ar->hw_values = &qca4019_values; 2202 ar->hw_values = &qca4019_values;
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 3da18c9dbd7a..9374bcde3d35 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -165,6 +165,13 @@ struct ath10k_fw_stats_peer {
165 u32 rx_duration; 165 u32 rx_duration;
166}; 166};
167 167
168struct ath10k_fw_extd_stats_peer {
169 struct list_head list;
170
171 u8 peer_macaddr[ETH_ALEN];
172 u32 rx_duration;
173};
174
168struct ath10k_fw_stats_vdev { 175struct ath10k_fw_stats_vdev {
169 struct list_head list; 176 struct list_head list;
170 177
@@ -256,9 +263,11 @@ struct ath10k_fw_stats_pdev {
256}; 263};
257 264
258struct ath10k_fw_stats { 265struct ath10k_fw_stats {
266 bool extended;
259 struct list_head pdevs; 267 struct list_head pdevs;
260 struct list_head vdevs; 268 struct list_head vdevs;
261 struct list_head peers; 269 struct list_head peers;
270 struct list_head peers_extd;
262}; 271};
263 272
264#define ATH10K_TPC_TABLE_TYPE_FLAG 1 273#define ATH10K_TPC_TABLE_TYPE_FLAG 1
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 8fbb8f2c7828..355e1ae665f9 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -313,13 +313,25 @@ static void ath10k_fw_stats_peers_free(struct list_head *head)
313 } 313 }
314} 314}
315 315
316static void ath10k_fw_extd_stats_peers_free(struct list_head *head)
317{
318 struct ath10k_fw_extd_stats_peer *i, *tmp;
319
320 list_for_each_entry_safe(i, tmp, head, list) {
321 list_del(&i->list);
322 kfree(i);
323 }
324}
325
316static void ath10k_debug_fw_stats_reset(struct ath10k *ar) 326static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
317{ 327{
318 spin_lock_bh(&ar->data_lock); 328 spin_lock_bh(&ar->data_lock);
319 ar->debug.fw_stats_done = false; 329 ar->debug.fw_stats_done = false;
330 ar->debug.fw_stats.extended = false;
320 ath10k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); 331 ath10k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
321 ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs); 332 ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
322 ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers); 333 ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
334 ath10k_fw_extd_stats_peers_free(&ar->debug.fw_stats.peers_extd);
323 spin_unlock_bh(&ar->data_lock); 335 spin_unlock_bh(&ar->data_lock);
324} 336}
325 337
@@ -334,6 +346,7 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
334 INIT_LIST_HEAD(&stats.pdevs); 346 INIT_LIST_HEAD(&stats.pdevs);
335 INIT_LIST_HEAD(&stats.vdevs); 347 INIT_LIST_HEAD(&stats.vdevs);
336 INIT_LIST_HEAD(&stats.peers); 348 INIT_LIST_HEAD(&stats.peers);
349 INIT_LIST_HEAD(&stats.peers_extd);
337 350
338 spin_lock_bh(&ar->data_lock); 351 spin_lock_bh(&ar->data_lock);
339 ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats); 352 ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats);
@@ -354,7 +367,7 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
354 * delivered which is treated as end-of-data and is itself discarded 367 * delivered which is treated as end-of-data and is itself discarded
355 */ 368 */
356 if (ath10k_peer_stats_enabled(ar)) 369 if (ath10k_peer_stats_enabled(ar))
357 ath10k_sta_update_rx_duration(ar, &stats.peers); 370 ath10k_sta_update_rx_duration(ar, &stats);
358 371
359 if (ar->debug.fw_stats_done) { 372 if (ar->debug.fw_stats_done) {
360 if (!ath10k_peer_stats_enabled(ar)) 373 if (!ath10k_peer_stats_enabled(ar))
@@ -396,6 +409,8 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
396 409
397 list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers); 410 list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers);
398 list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs); 411 list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs);
412 list_splice_tail_init(&stats.peers_extd,
413 &ar->debug.fw_stats.peers_extd);
399 } 414 }
400 415
401 complete(&ar->debug.fw_stats_complete); 416 complete(&ar->debug.fw_stats_complete);
@@ -407,6 +422,7 @@ free:
407 ath10k_fw_stats_pdevs_free(&stats.pdevs); 422 ath10k_fw_stats_pdevs_free(&stats.pdevs);
408 ath10k_fw_stats_vdevs_free(&stats.vdevs); 423 ath10k_fw_stats_vdevs_free(&stats.vdevs);
409 ath10k_fw_stats_peers_free(&stats.peers); 424 ath10k_fw_stats_peers_free(&stats.peers);
425 ath10k_fw_extd_stats_peers_free(&stats.peers_extd);
410 426
411 spin_unlock_bh(&ar->data_lock); 427 spin_unlock_bh(&ar->data_lock);
412} 428}
@@ -2330,6 +2346,7 @@ int ath10k_debug_create(struct ath10k *ar)
2330 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); 2346 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
2331 INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs); 2347 INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
2332 INIT_LIST_HEAD(&ar->debug.fw_stats.peers); 2348 INIT_LIST_HEAD(&ar->debug.fw_stats.peers);
2349 INIT_LIST_HEAD(&ar->debug.fw_stats.peers_extd);
2333 2350
2334 return 0; 2351 return 0;
2335} 2352}
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h
index 75c89e3625ef..c458fa96a6d4 100644
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@ -154,10 +154,15 @@ ath10k_debug_get_new_fw_crash_data(struct ath10k *ar)
154#ifdef CONFIG_MAC80211_DEBUGFS 154#ifdef CONFIG_MAC80211_DEBUGFS
155void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 155void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
156 struct ieee80211_sta *sta, struct dentry *dir); 156 struct ieee80211_sta *sta, struct dentry *dir);
157void ath10k_sta_update_rx_duration(struct ath10k *ar, struct list_head *peer); 157void ath10k_sta_update_rx_duration(struct ath10k *ar,
158 struct ath10k_fw_stats *stats);
159void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
160 struct ieee80211_sta *sta,
161 struct station_info *sinfo);
158#else 162#else
159static inline void ath10k_sta_update_rx_duration(struct ath10k *ar, 163static inline
160 struct list_head *peer) 164void ath10k_sta_update_rx_duration(struct ath10k *ar,
165 struct ath10k_fw_stats *stats)
161{ 166{
162} 167}
163#endif /* CONFIG_MAC80211_DEBUGFS */ 168#endif /* CONFIG_MAC80211_DEBUGFS */
diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
index 67ef75b60567..9955fea0802a 100644
--- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
@@ -18,13 +18,34 @@
18#include "wmi-ops.h" 18#include "wmi-ops.h"
19#include "debug.h" 19#include "debug.h"
20 20
21void ath10k_sta_update_rx_duration(struct ath10k *ar, struct list_head *head) 21static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar,
22{ struct ieee80211_sta *sta; 22 struct ath10k_fw_stats *stats)
23{
24 struct ath10k_fw_extd_stats_peer *peer;
25 struct ieee80211_sta *sta;
26 struct ath10k_sta *arsta;
27
28 rcu_read_lock();
29 list_for_each_entry(peer, &stats->peers_extd, list) {
30 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
31 NULL);
32 if (!sta)
33 continue;
34 arsta = (struct ath10k_sta *)sta->drv_priv;
35 arsta->rx_duration += (u64)peer->rx_duration;
36 }
37 rcu_read_unlock();
38}
39
40static void ath10k_sta_update_stats_rx_duration(struct ath10k *ar,
41 struct ath10k_fw_stats *stats)
42{
23 struct ath10k_fw_stats_peer *peer; 43 struct ath10k_fw_stats_peer *peer;
44 struct ieee80211_sta *sta;
24 struct ath10k_sta *arsta; 45 struct ath10k_sta *arsta;
25 46
26 rcu_read_lock(); 47 rcu_read_lock();
27 list_for_each_entry(peer, head, list) { 48 list_for_each_entry(peer, &stats->peers, list) {
28 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr, 49 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
29 NULL); 50 NULL);
30 if (!sta) 51 if (!sta)
@@ -35,6 +56,29 @@ void ath10k_sta_update_rx_duration(struct ath10k *ar, struct list_head *head)
35 rcu_read_unlock(); 56 rcu_read_unlock();
36} 57}
37 58
59void ath10k_sta_update_rx_duration(struct ath10k *ar,
60 struct ath10k_fw_stats *stats)
61{
62 if (stats->extended)
63 ath10k_sta_update_extd_stats_rx_duration(ar, stats);
64 else
65 ath10k_sta_update_stats_rx_duration(ar, stats);
66}
67
68void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
69 struct ieee80211_sta *sta,
70 struct station_info *sinfo)
71{
72 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
73 struct ath10k *ar = arsta->arvif->ar;
74
75 if (!ath10k_peer_stats_enabled(ar))
76 return;
77
78 sinfo->rx_duration = arsta->rx_duration;
79 sinfo->filled |= 1ULL << NL80211_STA_INFO_RX_DURATION;
80}
81
38static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file, 82static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file,
39 char __user *user_buf, 83 char __user *user_buf,
40 size_t count, loff_t *ppos) 84 size_t count, loff_t *ppos)
@@ -249,28 +293,6 @@ static const struct file_operations fops_delba = {
249 .llseek = default_llseek, 293 .llseek = default_llseek,
250}; 294};
251 295
252static ssize_t ath10k_dbg_sta_read_rx_duration(struct file *file,
253 char __user *user_buf,
254 size_t count, loff_t *ppos)
255{
256 struct ieee80211_sta *sta = file->private_data;
257 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
258 char buf[100];
259 int len = 0;
260
261 len = scnprintf(buf, sizeof(buf),
262 "%llu usecs\n", arsta->rx_duration);
263
264 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
265}
266
267static const struct file_operations fops_rx_duration = {
268 .read = ath10k_dbg_sta_read_rx_duration,
269 .open = simple_open,
270 .owner = THIS_MODULE,
271 .llseek = default_llseek,
272};
273
274void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 296void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
275 struct ieee80211_sta *sta, struct dentry *dir) 297 struct ieee80211_sta *sta, struct dentry *dir)
276{ 298{
@@ -279,6 +301,4 @@ void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
279 debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba); 301 debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba);
280 debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp); 302 debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp);
281 debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba); 303 debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba);
282 debugfs_create_file("rx_duration", S_IRUGO, dir, sta,
283 &fops_rx_duration);
284} 304}
diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h
index cc827185d3e9..0c55cd92a951 100644
--- a/drivers/net/wireless/ath/ath10k/htc.h
+++ b/drivers/net/wireless/ath/ath10k/htc.h
@@ -22,7 +22,6 @@
22#include <linux/list.h> 22#include <linux/list.h>
23#include <linux/bug.h> 23#include <linux/bug.h>
24#include <linux/skbuff.h> 24#include <linux/skbuff.h>
25#include <linux/semaphore.h>
26#include <linux/timer.h> 25#include <linux/timer.h>
27 26
28struct ath10k; 27struct ath10k;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 80e645302b54..78db5d679f19 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -748,7 +748,7 @@ ath10k_htt_rx_h_peer_channel(struct ath10k *ar, struct htt_rx_desc *rxd)
748 if (WARN_ON_ONCE(!arvif)) 748 if (WARN_ON_ONCE(!arvif))
749 return NULL; 749 return NULL;
750 750
751 if (WARN_ON_ONCE(ath10k_mac_vif_chan(arvif->vif, &def))) 751 if (ath10k_mac_vif_chan(arvif->vif, &def))
752 return NULL; 752 return NULL;
753 753
754 return def.chan; 754 return def.chan;
@@ -2307,12 +2307,10 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
2307 ath10k_htt_rx_delba(ar, resp); 2307 ath10k_htt_rx_delba(ar, resp);
2308 break; 2308 break;
2309 case HTT_T2H_MSG_TYPE_PKTLOG: { 2309 case HTT_T2H_MSG_TYPE_PKTLOG: {
2310 struct ath10k_pktlog_hdr *hdr =
2311 (struct ath10k_pktlog_hdr *)resp->pktlog_msg.payload;
2312
2313 trace_ath10k_htt_pktlog(ar, resp->pktlog_msg.payload, 2310 trace_ath10k_htt_pktlog(ar, resp->pktlog_msg.payload,
2314 sizeof(*hdr) + 2311 skb->len -
2315 __le16_to_cpu(hdr->size)); 2312 offsetof(struct htt_resp,
2313 pktlog_msg.payload));
2316 break; 2314 break;
2317 } 2315 }
2318 case HTT_T2H_MSG_TYPE_RX_FLUSH: { 2316 case HTT_T2H_MSG_TYPE_RX_FLUSH: {
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 6269c610b0a3..7c072b605bc7 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -49,7 +49,7 @@ static void __ath10k_htt_tx_txq_recalc(struct ieee80211_hw *hw,
49 struct ieee80211_txq *txq) 49 struct ieee80211_txq *txq)
50{ 50{
51 struct ath10k *ar = hw->priv; 51 struct ath10k *ar = hw->priv;
52 struct ath10k_sta *arsta = (void *)txq->sta->drv_priv; 52 struct ath10k_sta *arsta;
53 struct ath10k_vif *arvif = (void *)txq->vif->drv_priv; 53 struct ath10k_vif *arvif = (void *)txq->vif->drv_priv;
54 unsigned long frame_cnt; 54 unsigned long frame_cnt;
55 unsigned long byte_cnt; 55 unsigned long byte_cnt;
@@ -67,10 +67,12 @@ static void __ath10k_htt_tx_txq_recalc(struct ieee80211_hw *hw,
67 if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH_PULL) 67 if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH_PULL)
68 return; 68 return;
69 69
70 if (txq->sta) 70 if (txq->sta) {
71 arsta = (void *)txq->sta->drv_priv;
71 peer_id = arsta->peer_id; 72 peer_id = arsta->peer_id;
72 else 73 } else {
73 peer_id = arvif->peer_id; 74 peer_id = arvif->peer_id;
75 }
74 76
75 tid = txq->tid; 77 tid = txq->tid;
76 bit = BIT(peer_id % 32); 78 bit = BIT(peer_id % 32);
@@ -388,6 +390,8 @@ void ath10k_htt_tx_free(struct ath10k_htt *htt)
388{ 390{
389 int size; 391 int size;
390 392
393 tasklet_kill(&htt->txrx_compl_task);
394
391 idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar); 395 idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
392 idr_destroy(&htt->pending_tx); 396 idr_destroy(&htt->pending_tx);
393 397
@@ -733,16 +737,18 @@ static u8 ath10k_htt_tx_get_vdev_id(struct ath10k *ar, struct sk_buff *skb)
733{ 737{
734 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 738 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
735 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb); 739 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
736 struct ath10k_vif *arvif = (void *)cb->vif->drv_priv; 740 struct ath10k_vif *arvif;
737 741
738 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) 742 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
739 return ar->scan.vdev_id; 743 return ar->scan.vdev_id;
740 else if (cb->vif) 744 } else if (cb->vif) {
745 arvif = (void *)cb->vif->drv_priv;
741 return arvif->vdev_id; 746 return arvif->vdev_id;
742 else if (ar->monitor_started) 747 } else if (ar->monitor_started) {
743 return ar->monitor_vdev_id; 748 return ar->monitor_vdev_id;
744 else 749 } else {
745 return 0; 750 return 0;
751 }
746} 752}
747 753
748static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb, bool is_eth) 754static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb, bool is_eth)
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c
index bd86e7a38db9..f903d468dbe6 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -19,7 +19,6 @@
19#include "hw.h" 19#include "hw.h"
20 20
21const struct ath10k_hw_regs qca988x_regs = { 21const struct ath10k_hw_regs qca988x_regs = {
22 .rtc_state_cold_reset_mask = 0x00000400,
23 .rtc_soc_base_address = 0x00004000, 22 .rtc_soc_base_address = 0x00004000,
24 .rtc_wmac_base_address = 0x00005000, 23 .rtc_wmac_base_address = 0x00005000,
25 .soc_core_base_address = 0x00009000, 24 .soc_core_base_address = 0x00009000,
@@ -46,7 +45,6 @@ const struct ath10k_hw_regs qca988x_regs = {
46}; 45};
47 46
48const struct ath10k_hw_regs qca6174_regs = { 47const struct ath10k_hw_regs qca6174_regs = {
49 .rtc_state_cold_reset_mask = 0x00002000,
50 .rtc_soc_base_address = 0x00000800, 48 .rtc_soc_base_address = 0x00000800,
51 .rtc_wmac_base_address = 0x00001000, 49 .rtc_wmac_base_address = 0x00001000,
52 .soc_core_base_address = 0x0003a000, 50 .soc_core_base_address = 0x0003a000,
@@ -73,7 +71,6 @@ const struct ath10k_hw_regs qca6174_regs = {
73}; 71};
74 72
75const struct ath10k_hw_regs qca99x0_regs = { 73const struct ath10k_hw_regs qca99x0_regs = {
76 .rtc_state_cold_reset_mask = 0x00000400,
77 .rtc_soc_base_address = 0x00080000, 74 .rtc_soc_base_address = 0x00080000,
78 .rtc_wmac_base_address = 0x00000000, 75 .rtc_wmac_base_address = 0x00000000,
79 .soc_core_base_address = 0x00082000, 76 .soc_core_base_address = 0x00082000,
@@ -168,6 +165,15 @@ const struct ath10k_hw_values qca99x0_values = {
168 .ce_desc_meta_data_lsb = 4, 165 .ce_desc_meta_data_lsb = 4,
169}; 166};
170 167
168const struct ath10k_hw_values qca9888_values = {
169 .rtc_state_val_on = 3,
170 .ce_count = 12,
171 .msi_assign_ce_max = 12,
172 .num_target_ce_config_wlan = 10,
173 .ce_desc_meta_data_mask = 0xFFF0,
174 .ce_desc_meta_data_lsb = 4,
175};
176
171const struct ath10k_hw_values qca4019_values = { 177const struct ath10k_hw_values qca4019_values = {
172 .ce_count = 12, 178 .ce_count = 12,
173 .num_target_ce_config_wlan = 10, 179 .num_target_ce_config_wlan = 10,
@@ -198,7 +204,8 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
198 case ATH10K_HW_CC_WRAP_SHIFTED_EACH: 204 case ATH10K_HW_CC_WRAP_SHIFTED_EACH:
199 if (cc < cc_prev) 205 if (cc < cc_prev)
200 cc_fix = 0x7fffffff; 206 cc_fix = 0x7fffffff;
201 else 207
208 if (rcc < rcc_prev)
202 rcc_fix = 0x7fffffff; 209 rcc_fix = 0x7fffffff;
203 break; 210 break;
204 case ATH10K_HW_CC_WRAP_DISABLED: 211 case ATH10K_HW_CC_WRAP_DISABLED:
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index f31d3ce42470..e014cd732a0d 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -26,6 +26,7 @@
26#define QCA6164_2_1_DEVICE_ID (0x0041) 26#define QCA6164_2_1_DEVICE_ID (0x0041)
27#define QCA6174_2_1_DEVICE_ID (0x003e) 27#define QCA6174_2_1_DEVICE_ID (0x003e)
28#define QCA99X0_2_0_DEVICE_ID (0x0040) 28#define QCA99X0_2_0_DEVICE_ID (0x0040)
29#define QCA9888_2_0_DEVICE_ID (0x0056)
29#define QCA9984_1_0_DEVICE_ID (0x0046) 30#define QCA9984_1_0_DEVICE_ID (0x0046)
30#define QCA9377_1_0_DEVICE_ID (0x0042) 31#define QCA9377_1_0_DEVICE_ID (0x0042)
31#define QCA9887_1_0_DEVICE_ID (0x0050) 32#define QCA9887_1_0_DEVICE_ID (0x0050)
@@ -108,6 +109,14 @@ enum qca9377_chip_id_rev {
108#define QCA9984_HW_1_0_BOARD_DATA_FILE "board.bin" 109#define QCA9984_HW_1_0_BOARD_DATA_FILE "board.bin"
109#define QCA9984_HW_1_0_PATCH_LOAD_ADDR 0x1234 110#define QCA9984_HW_1_0_PATCH_LOAD_ADDR 0x1234
110 111
112/* QCA9888 2.0 defines */
113#define QCA9888_HW_2_0_DEV_VERSION 0x1000000
114#define QCA9888_HW_DEV_TYPE 0xc
115#define QCA9888_HW_2_0_CHIP_ID_REV 0x0
116#define QCA9888_HW_2_0_FW_DIR ATH10K_FW_DIR "/QCA9888/hw2.0"
117#define QCA9888_HW_2_0_BOARD_DATA_FILE "board.bin"
118#define QCA9888_HW_2_0_PATCH_LOAD_ADDR 0x1234
119
111/* QCA9377 1.0 definitions */ 120/* QCA9377 1.0 definitions */
112#define QCA9377_HW_1_0_FW_DIR ATH10K_FW_DIR "/QCA9377/hw1.0" 121#define QCA9377_HW_1_0_FW_DIR ATH10K_FW_DIR "/QCA9377/hw1.0"
113#define QCA9377_HW_1_0_BOARD_DATA_FILE "board.bin" 122#define QCA9377_HW_1_0_BOARD_DATA_FILE "board.bin"
@@ -210,6 +219,7 @@ enum ath10k_hw_rev {
210 ATH10K_HW_QCA988X, 219 ATH10K_HW_QCA988X,
211 ATH10K_HW_QCA6174, 220 ATH10K_HW_QCA6174,
212 ATH10K_HW_QCA99X0, 221 ATH10K_HW_QCA99X0,
222 ATH10K_HW_QCA9888,
213 ATH10K_HW_QCA9984, 223 ATH10K_HW_QCA9984,
214 ATH10K_HW_QCA9377, 224 ATH10K_HW_QCA9377,
215 ATH10K_HW_QCA4019, 225 ATH10K_HW_QCA4019,
@@ -217,7 +227,6 @@ enum ath10k_hw_rev {
217}; 227};
218 228
219struct ath10k_hw_regs { 229struct ath10k_hw_regs {
220 u32 rtc_state_cold_reset_mask;
221 u32 rtc_soc_base_address; 230 u32 rtc_soc_base_address;
222 u32 rtc_wmac_base_address; 231 u32 rtc_wmac_base_address;
223 u32 soc_core_base_address; 232 u32 soc_core_base_address;
@@ -260,6 +269,7 @@ struct ath10k_hw_values {
260extern const struct ath10k_hw_values qca988x_values; 269extern const struct ath10k_hw_values qca988x_values;
261extern const struct ath10k_hw_values qca6174_values; 270extern const struct ath10k_hw_values qca6174_values;
262extern const struct ath10k_hw_values qca99x0_values; 271extern const struct ath10k_hw_values qca99x0_values;
272extern const struct ath10k_hw_values qca9888_values;
263extern const struct ath10k_hw_values qca4019_values; 273extern const struct ath10k_hw_values qca4019_values;
264 274
265void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey, 275void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
@@ -269,6 +279,7 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
269#define QCA_REV_9887(ar) ((ar)->hw_rev == ATH10K_HW_QCA9887) 279#define QCA_REV_9887(ar) ((ar)->hw_rev == ATH10K_HW_QCA9887)
270#define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174) 280#define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174)
271#define QCA_REV_99X0(ar) ((ar)->hw_rev == ATH10K_HW_QCA99X0) 281#define QCA_REV_99X0(ar) ((ar)->hw_rev == ATH10K_HW_QCA99X0)
282#define QCA_REV_9888(ar) ((ar)->hw_rev == ATH10K_HW_QCA9888)
272#define QCA_REV_9984(ar) ((ar)->hw_rev == ATH10K_HW_QCA9984) 283#define QCA_REV_9984(ar) ((ar)->hw_rev == ATH10K_HW_QCA9984)
273#define QCA_REV_9377(ar) ((ar)->hw_rev == ATH10K_HW_QCA9377) 284#define QCA_REV_9377(ar) ((ar)->hw_rev == ATH10K_HW_QCA9377)
274#define QCA_REV_40XX(ar) ((ar)->hw_rev == ATH10K_HW_QCA4019) 285#define QCA_REV_40XX(ar) ((ar)->hw_rev == ATH10K_HW_QCA4019)
@@ -296,25 +307,6 @@ enum ath10k_mcast2ucast_mode {
296 ATH10K_MCAST2UCAST_ENABLED = 1, 307 ATH10K_MCAST2UCAST_ENABLED = 1,
297}; 308};
298 309
299struct ath10k_pktlog_hdr {
300 __le16 flags;
301 __le16 missed_cnt;
302 __le16 log_type;
303 __le16 size;
304 __le32 timestamp;
305 u8 payload[0];
306} __packed;
307
308struct ath10k_pktlog_10_4_hdr {
309 __le16 flags;
310 __le16 missed_cnt;
311 __le16 log_type;
312 __le16 size;
313 __le32 timestamp;
314 __le32 type_specific_data;
315 u8 payload[0];
316} __packed;
317
318enum ath10k_hw_rate_ofdm { 310enum ath10k_hw_rate_ofdm {
319 ATH10K_HW_RATE_OFDM_48M = 0, 311 ATH10K_HW_RATE_OFDM_48M = 0,
320 ATH10K_HW_RATE_OFDM_24M, 312 ATH10K_HW_RATE_OFDM_24M,
@@ -535,7 +527,6 @@ enum ath10k_hw_cc_wraparound_type {
535/* as of IP3.7.1 */ 527/* as of IP3.7.1 */
536#define RTC_STATE_V_ON ar->hw_values->rtc_state_val_on 528#define RTC_STATE_V_ON ar->hw_values->rtc_state_val_on
537 529
538#define RTC_STATE_COLD_RESET_MASK ar->regs->rtc_state_cold_reset_mask
539#define RTC_STATE_V_LSB 0 530#define RTC_STATE_V_LSB 0
540#define RTC_STATE_V_MASK 0x00000007 531#define RTC_STATE_V_MASK 0x00000007
541#define RTC_STATE_ADDRESS 0x0000 532#define RTC_STATE_ADDRESS 0x0000
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index ebc12c521fe0..55c823f983c7 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -802,6 +802,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
802{ 802{
803 struct ath10k_peer *peer, *tmp; 803 struct ath10k_peer *peer, *tmp;
804 int peer_id; 804 int peer_id;
805 int i;
805 806
806 lockdep_assert_held(&ar->conf_mutex); 807 lockdep_assert_held(&ar->conf_mutex);
807 808
@@ -818,6 +819,17 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
818 ar->peer_map[peer_id] = NULL; 819 ar->peer_map[peer_id] = NULL;
819 } 820 }
820 821
822 /* Double check that peer is properly un-referenced from
823 * the peer_map
824 */
825 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
826 if (ar->peer_map[i] == peer) {
827 ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %p idx %d)\n",
828 peer->addr, peer, i);
829 ar->peer_map[i] = NULL;
830 }
831 }
832
821 list_del(&peer->list); 833 list_del(&peer->list);
822 kfree(peer); 834 kfree(peer);
823 ar->num_peers--; 835 ar->num_peers--;
@@ -828,6 +840,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
828static void ath10k_peer_cleanup_all(struct ath10k *ar) 840static void ath10k_peer_cleanup_all(struct ath10k *ar)
829{ 841{
830 struct ath10k_peer *peer, *tmp; 842 struct ath10k_peer *peer, *tmp;
843 int i;
831 844
832 lockdep_assert_held(&ar->conf_mutex); 845 lockdep_assert_held(&ar->conf_mutex);
833 846
@@ -836,6 +849,10 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar)
836 list_del(&peer->list); 849 list_del(&peer->list);
837 kfree(peer); 850 kfree(peer);
838 } 851 }
852
853 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
854 ar->peer_map[i] = NULL;
855
839 spin_unlock_bh(&ar->data_lock); 856 spin_unlock_bh(&ar->data_lock);
840 857
841 ar->num_peers = 0; 858 ar->num_peers = 0;
@@ -2939,7 +2956,7 @@ static int ath10k_update_channel_list(struct ath10k *ar)
2939 if (channel->flags & IEEE80211_CHAN_DISABLED) 2956 if (channel->flags & IEEE80211_CHAN_DISABLED)
2940 continue; 2957 continue;
2941 2958
2942 ch->allow_ht = true; 2959 ch->allow_ht = true;
2943 2960
2944 /* FIXME: when should we really allow VHT? */ 2961 /* FIXME: when should we really allow VHT? */
2945 ch->allow_vht = true; 2962 ch->allow_vht = true;
@@ -3675,17 +3692,18 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3675 3692
3676static void ath10k_mac_txq_init(struct ieee80211_txq *txq) 3693static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3677{ 3694{
3678 struct ath10k_txq *artxq = (void *)txq->drv_priv; 3695 struct ath10k_txq *artxq;
3679 3696
3680 if (!txq) 3697 if (!txq)
3681 return; 3698 return;
3682 3699
3700 artxq = (void *)txq->drv_priv;
3683 INIT_LIST_HEAD(&artxq->list); 3701 INIT_LIST_HEAD(&artxq->list);
3684} 3702}
3685 3703
3686static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq) 3704static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3687{ 3705{
3688 struct ath10k_txq *artxq = (void *)txq->drv_priv; 3706 struct ath10k_txq *artxq;
3689 struct ath10k_skb_cb *cb; 3707 struct ath10k_skb_cb *cb;
3690 struct sk_buff *msdu; 3708 struct sk_buff *msdu;
3691 int msdu_id; 3709 int msdu_id;
@@ -3693,6 +3711,7 @@ static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3693 if (!txq) 3711 if (!txq)
3694 return; 3712 return;
3695 3713
3714 artxq = (void *)txq->drv_priv;
3696 spin_lock_bh(&ar->txqs_lock); 3715 spin_lock_bh(&ar->txqs_lock);
3697 if (!list_empty(&artxq->list)) 3716 if (!list_empty(&artxq->list))
3698 list_del_init(&artxq->list); 3717 list_del_init(&artxq->list);
@@ -4228,6 +4247,9 @@ static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4228 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); 4247 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4229 } 4248 }
4230 4249
4250 if (ar->cfg_tx_chainmask <= 1)
4251 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4252
4231 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); 4253 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4232 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); 4254 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4233 4255
@@ -4265,7 +4287,7 @@ static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4265 ht_cap.cap |= smps; 4287 ht_cap.cap |= smps;
4266 } 4288 }
4267 4289
4268 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC) 4290 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
4269 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; 4291 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4270 4292
4271 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) { 4293 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
@@ -5979,9 +6001,17 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
5979 continue; 6001 continue;
5980 6002
5981 if (peer->sta == sta) { 6003 if (peer->sta == sta) {
5982 ath10k_warn(ar, "found sta peer %pM entry on vdev %i after it was supposedly removed\n", 6004 ath10k_warn(ar, "found sta peer %pM (ptr %p id %d) entry on vdev %i after it was supposedly removed\n",
5983 sta->addr, arvif->vdev_id); 6005 sta->addr, peer, i, arvif->vdev_id);
5984 peer->sta = NULL; 6006 peer->sta = NULL;
6007
6008 /* Clean up the peer object as well since we
6009 * must have failed to do this above.
6010 */
6011 list_del(&peer->list);
6012 ar->peer_map[i] = NULL;
6013 kfree(peer);
6014 ar->num_peers--;
5985 } 6015 }
5986 } 6016 }
5987 spin_unlock_bh(&ar->data_lock); 6017 spin_unlock_bh(&ar->data_lock);
@@ -7406,6 +7436,7 @@ static const struct ieee80211_ops ath10k_ops = {
7406#endif 7436#endif
7407#ifdef CONFIG_MAC80211_DEBUGFS 7437#ifdef CONFIG_MAC80211_DEBUGFS
7408 .sta_add_debugfs = ath10k_sta_add_debugfs, 7438 .sta_add_debugfs = ath10k_sta_add_debugfs,
7439 .sta_statistics = ath10k_sta_statistics,
7409#endif 7440#endif
7410}; 7441};
7411 7442
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index f06dd3941bac..9a22c478dd1b 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -56,6 +56,7 @@ static const struct pci_device_id ath10k_pci_id_table[] = {
56 { PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */ 56 { PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */
57 { PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */ 57 { PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */
58 { PCI_VDEVICE(ATHEROS, QCA99X0_2_0_DEVICE_ID) }, /* PCI-E QCA99X0 V2 */ 58 { PCI_VDEVICE(ATHEROS, QCA99X0_2_0_DEVICE_ID) }, /* PCI-E QCA99X0 V2 */
59 { PCI_VDEVICE(ATHEROS, QCA9888_2_0_DEVICE_ID) }, /* PCI-E QCA9888 V2 */
59 { PCI_VDEVICE(ATHEROS, QCA9984_1_0_DEVICE_ID) }, /* PCI-E QCA9984 V1 */ 60 { PCI_VDEVICE(ATHEROS, QCA9984_1_0_DEVICE_ID) }, /* PCI-E QCA9984 V1 */
60 { PCI_VDEVICE(ATHEROS, QCA9377_1_0_DEVICE_ID) }, /* PCI-E QCA9377 V1 */ 61 { PCI_VDEVICE(ATHEROS, QCA9377_1_0_DEVICE_ID) }, /* PCI-E QCA9377 V1 */
61 { PCI_VDEVICE(ATHEROS, QCA9887_1_0_DEVICE_ID) }, /* PCI-E QCA9887 */ 62 { PCI_VDEVICE(ATHEROS, QCA9887_1_0_DEVICE_ID) }, /* PCI-E QCA9887 */
@@ -85,6 +86,8 @@ static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = {
85 86
86 { QCA9984_1_0_DEVICE_ID, QCA9984_HW_1_0_CHIP_ID_REV }, 87 { QCA9984_1_0_DEVICE_ID, QCA9984_HW_1_0_CHIP_ID_REV },
87 88
89 { QCA9888_2_0_DEVICE_ID, QCA9888_HW_2_0_CHIP_ID_REV },
90
88 { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_0_CHIP_ID_REV }, 91 { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_0_CHIP_ID_REV },
89 { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_1_CHIP_ID_REV }, 92 { QCA9377_1_0_DEVICE_ID, QCA9377_HW_1_1_CHIP_ID_REV },
90 93
@@ -850,6 +853,7 @@ static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
850 CORE_CTRL_ADDRESS) & 853 CORE_CTRL_ADDRESS) &
851 0x7ff) << 21; 854 0x7ff) << 21;
852 break; 855 break;
856 case ATH10K_HW_QCA9888:
853 case ATH10K_HW_QCA99X0: 857 case ATH10K_HW_QCA99X0:
854 case ATH10K_HW_QCA9984: 858 case ATH10K_HW_QCA9984:
855 case ATH10K_HW_QCA4019: 859 case ATH10K_HW_QCA4019:
@@ -1583,6 +1587,7 @@ static void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar)
1583 break; 1587 break;
1584 case ATH10K_HW_QCA99X0: 1588 case ATH10K_HW_QCA99X0:
1585 case ATH10K_HW_QCA9984: 1589 case ATH10K_HW_QCA9984:
1590 case ATH10K_HW_QCA9888:
1586 case ATH10K_HW_QCA4019: 1591 case ATH10K_HW_QCA4019:
1587 /* TODO: Find appropriate register configuration for QCA99X0 1592 /* TODO: Find appropriate register configuration for QCA99X0
1588 * to mask irq/MSI. 1593 * to mask irq/MSI.
@@ -1608,6 +1613,7 @@ static void ath10k_pci_irq_msi_fw_unmask(struct ath10k *ar)
1608 break; 1613 break;
1609 case ATH10K_HW_QCA99X0: 1614 case ATH10K_HW_QCA99X0:
1610 case ATH10K_HW_QCA9984: 1615 case ATH10K_HW_QCA9984:
1616 case ATH10K_HW_QCA9888:
1611 case ATH10K_HW_QCA4019: 1617 case ATH10K_HW_QCA4019:
1612 /* TODO: Find appropriate register configuration for QCA99X0 1618 /* TODO: Find appropriate register configuration for QCA99X0
1613 * to unmask irq/MSI. 1619 * to unmask irq/MSI.
@@ -1948,6 +1954,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar)
1948 switch (ar_pci->pdev->device) { 1954 switch (ar_pci->pdev->device) {
1949 case QCA988X_2_0_DEVICE_ID: 1955 case QCA988X_2_0_DEVICE_ID:
1950 case QCA99X0_2_0_DEVICE_ID: 1956 case QCA99X0_2_0_DEVICE_ID:
1957 case QCA9888_2_0_DEVICE_ID:
1951 case QCA9984_1_0_DEVICE_ID: 1958 case QCA9984_1_0_DEVICE_ID:
1952 case QCA9887_1_0_DEVICE_ID: 1959 case QCA9887_1_0_DEVICE_ID:
1953 return 1; 1960 return 1;
@@ -2216,6 +2223,14 @@ static void ath10k_pci_fw_crashed_clear(struct ath10k *ar)
2216 ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, val); 2223 ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, val);
2217} 2224}
2218 2225
2226static bool ath10k_pci_has_device_gone(struct ath10k *ar)
2227{
2228 u32 val;
2229
2230 val = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS);
2231 return (val == 0xffffffff);
2232}
2233
2219/* this function effectively clears target memory controller assert line */ 2234/* this function effectively clears target memory controller assert line */
2220static void ath10k_pci_warm_reset_si0(struct ath10k *ar) 2235static void ath10k_pci_warm_reset_si0(struct ath10k *ar)
2221{ 2236{
@@ -2748,6 +2763,9 @@ static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg)
2748 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2763 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2749 int ret; 2764 int ret;
2750 2765
2766 if (ath10k_pci_has_device_gone(ar))
2767 return IRQ_NONE;
2768
2751 ret = ath10k_pci_force_wake(ar); 2769 ret = ath10k_pci_force_wake(ar);
2752 if (ret) { 2770 if (ret) {
2753 ath10k_warn(ar, "failed to wake device up on irq: %d\n", ret); 2771 ath10k_warn(ar, "failed to wake device up on irq: %d\n", ret);
@@ -3169,6 +3187,12 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
3169 pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset; 3187 pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset;
3170 pci_hard_reset = ath10k_pci_qca99x0_chip_reset; 3188 pci_hard_reset = ath10k_pci_qca99x0_chip_reset;
3171 break; 3189 break;
3190 case QCA9888_2_0_DEVICE_ID:
3191 hw_rev = ATH10K_HW_QCA9888;
3192 pci_ps = false;
3193 pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset;
3194 pci_hard_reset = ath10k_pci_qca99x0_chip_reset;
3195 break;
3172 case QCA9377_1_0_DEVICE_ID: 3196 case QCA9377_1_0_DEVICE_ID:
3173 hw_rev = ATH10K_HW_QCA9377; 3197 hw_rev = ATH10K_HW_QCA9377;
3174 pci_ps = true; 3198 pci_ps = true;
diff --git a/drivers/net/wireless/ath/ath10k/spectral.c b/drivers/net/wireless/ath/ath10k/spectral.c
index 4671cfbcd8f7..7d9b0da1b010 100644
--- a/drivers/net/wireless/ath/ath10k/spectral.c
+++ b/drivers/net/wireless/ath/ath10k/spectral.c
@@ -101,9 +101,9 @@ int ath10k_spectral_process_fft(struct ath10k *ar,
101 break; 101 break;
102 case 80: 102 case 80:
103 /* TODO: As experiments with an analogue sender and various 103 /* TODO: As experiments with an analogue sender and various
104 * configuaritions (fft-sizes of 64/128/256 and 20/40/80 Mhz) 104 * configurations (fft-sizes of 64/128/256 and 20/40/80 Mhz)
105 * show, the particular configuration of 80 MHz/64 bins does 105 * show, the particular configuration of 80 MHz/64 bins does
106 * not match with the other smaples at all. Until the reason 106 * not match with the other samples at all. Until the reason
107 * for that is found, don't report these samples. 107 * for that is found, don't report these samples.
108 */ 108 */
109 if (bin_len == 64) 109 if (bin_len == 64)
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 1966c787998b..b29a86a26c13 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -81,10 +81,11 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
81 81
82 skb_cb = ATH10K_SKB_CB(msdu); 82 skb_cb = ATH10K_SKB_CB(msdu);
83 txq = skb_cb->txq; 83 txq = skb_cb->txq;
84 artxq = (void *)txq->drv_priv;
85 84
86 if (txq) 85 if (txq) {
86 artxq = (void *)txq->drv_priv;
87 artxq->num_fw_queued--; 87 artxq->num_fw_queued--;
88 }
88 89
89 ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id); 90 ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id);
90 ath10k_htt_tx_dec_pending(htt); 91 ath10k_htt_tx_dec_pending(htt);
@@ -216,6 +217,7 @@ void ath10k_peer_map_event(struct ath10k_htt *htt,
216 ath10k_dbg(ar, ATH10K_DBG_HTT, "htt peer map vdev %d peer %pM id %d\n", 217 ath10k_dbg(ar, ATH10K_DBG_HTT, "htt peer map vdev %d peer %pM id %d\n",
217 ev->vdev_id, ev->addr, ev->peer_id); 218 ev->vdev_id, ev->addr, ev->peer_id);
218 219
220 WARN_ON(ar->peer_map[ev->peer_id] && (ar->peer_map[ev->peer_id] != peer));
219 ar->peer_map[ev->peer_id] = peer; 221 ar->peer_map[ev->peer_id] = peer;
220 set_bit(ev->peer_id, peer->peer_ids); 222 set_bit(ev->peer_id, peer->peer_ids);
221exit: 223exit:
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 6279ab4a760e..169cd2e783eb 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1826,7 +1826,7 @@ static struct sk_buff *
1826ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) 1826ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
1827{ 1827{
1828 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); 1828 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
1829 struct ath10k_vif *arvif = (void *)cb->vif->drv_priv; 1829 struct ath10k_vif *arvif;
1830 struct wmi_mgmt_tx_cmd *cmd; 1830 struct wmi_mgmt_tx_cmd *cmd;
1831 struct ieee80211_hdr *hdr; 1831 struct ieee80211_hdr *hdr;
1832 struct sk_buff *skb; 1832 struct sk_buff *skb;
@@ -1838,10 +1838,12 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
1838 hdr = (struct ieee80211_hdr *)msdu->data; 1838 hdr = (struct ieee80211_hdr *)msdu->data;
1839 fc = le16_to_cpu(hdr->frame_control); 1839 fc = le16_to_cpu(hdr->frame_control);
1840 1840
1841 if (cb->vif) 1841 if (cb->vif) {
1842 arvif = (void *)cb->vif->drv_priv;
1842 vdev_id = arvif->vdev_id; 1843 vdev_id = arvif->vdev_id;
1843 else 1844 } else {
1844 vdev_id = 0; 1845 vdev_id = 0;
1846 }
1845 1847
1846 if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control))) 1848 if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
1847 return ERR_PTR(-EINVAL); 1849 return ERR_PTR(-EINVAL);
@@ -2924,6 +2926,7 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar,
2924 u32 num_pdev_ext_stats; 2926 u32 num_pdev_ext_stats;
2925 u32 num_vdev_stats; 2927 u32 num_vdev_stats;
2926 u32 num_peer_stats; 2928 u32 num_peer_stats;
2929 u32 num_bcnflt_stats;
2927 u32 stats_id; 2930 u32 stats_id;
2928 int i; 2931 int i;
2929 2932
@@ -2934,6 +2937,7 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar,
2934 num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats); 2937 num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats);
2935 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); 2938 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
2936 num_peer_stats = __le32_to_cpu(ev->num_peer_stats); 2939 num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
2940 num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats);
2937 stats_id = __le32_to_cpu(ev->stats_id); 2941 stats_id = __le32_to_cpu(ev->stats_id);
2938 2942
2939 for (i = 0; i < num_pdev_stats; i++) { 2943 for (i = 0; i < num_pdev_stats; i++) {
@@ -2974,32 +2978,57 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar,
2974 /* fw doesn't implement vdev stats */ 2978 /* fw doesn't implement vdev stats */
2975 2979
2976 for (i = 0; i < num_peer_stats; i++) { 2980 for (i = 0; i < num_peer_stats; i++) {
2977 const struct wmi_10_4_peer_extd_stats *src; 2981 const struct wmi_10_4_peer_stats *src;
2978 struct ath10k_fw_stats_peer *dst; 2982 struct ath10k_fw_stats_peer *dst;
2979 int stats_len;
2980 bool extd_peer_stats = !!(stats_id & WMI_10_4_STAT_PEER_EXTD);
2981
2982 if (extd_peer_stats)
2983 stats_len = sizeof(struct wmi_10_4_peer_extd_stats);
2984 else
2985 stats_len = sizeof(struct wmi_10_4_peer_stats);
2986 2983
2987 src = (void *)skb->data; 2984 src = (void *)skb->data;
2988 if (!skb_pull(skb, stats_len)) 2985 if (!skb_pull(skb, sizeof(*src)))
2989 return -EPROTO; 2986 return -EPROTO;
2990 2987
2991 dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 2988 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
2992 if (!dst) 2989 if (!dst)
2993 continue; 2990 continue;
2994 2991
2995 ath10k_wmi_10_4_pull_peer_stats(&src->common, dst); 2992 ath10k_wmi_10_4_pull_peer_stats(src, dst);
2996 /* FIXME: expose 10.4 specific values */
2997 if (extd_peer_stats)
2998 dst->rx_duration = __le32_to_cpu(src->rx_duration);
2999
3000 list_add_tail(&dst->list, &stats->peers); 2993 list_add_tail(&dst->list, &stats->peers);
3001 } 2994 }
3002 2995
2996 for (i = 0; i < num_bcnflt_stats; i++) {
2997 const struct wmi_10_4_bss_bcn_filter_stats *src;
2998
2999 src = (void *)skb->data;
3000 if (!skb_pull(skb, sizeof(*src)))
3001 return -EPROTO;
3002
3003 /* FIXME: expose values to userspace
3004 *
3005 * Note: Even though this loop seems to do nothing it is
3006 * required to parse following sub-structures properly.
3007 */
3008 }
3009
3010 if ((stats_id & WMI_10_4_STAT_PEER_EXTD) == 0)
3011 return 0;
3012
3013 stats->extended = true;
3014
3015 for (i = 0; i < num_peer_stats; i++) {
3016 const struct wmi_10_4_peer_extd_stats *src;
3017 struct ath10k_fw_extd_stats_peer *dst;
3018
3019 src = (void *)skb->data;
3020 if (!skb_pull(skb, sizeof(*src)))
3021 return -EPROTO;
3022
3023 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3024 if (!dst)
3025 continue;
3026
3027 ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr);
3028 dst->rx_duration = __le32_to_cpu(src->rx_duration);
3029 list_add_tail(&dst->list, &stats->peers_extd);
3030 }
3031
3003 return 0; 3032 return 0;
3004} 3033}
3005 3034
@@ -5257,6 +5286,9 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb)
5257 case WMI_10_4_PEER_STA_KICKOUT_EVENTID: 5286 case WMI_10_4_PEER_STA_KICKOUT_EVENTID:
5258 ath10k_wmi_event_peer_sta_kickout(ar, skb); 5287 ath10k_wmi_event_peer_sta_kickout(ar, skb);
5259 break; 5288 break;
5289 case WMI_10_4_ROAM_EVENTID:
5290 ath10k_wmi_event_roam(ar, skb);
5291 break;
5260 case WMI_10_4_HOST_SWBA_EVENTID: 5292 case WMI_10_4_HOST_SWBA_EVENTID:
5261 ath10k_wmi_event_host_swba(ar, skb); 5293 ath10k_wmi_event_host_swba(ar, skb);
5262 break; 5294 break;
@@ -7903,6 +7935,7 @@ static const struct wmi_ops wmi_10_4_ops = {
7903 .pull_phyerr = ath10k_wmi_10_4_op_pull_phyerr_ev, 7935 .pull_phyerr = ath10k_wmi_10_4_op_pull_phyerr_ev,
7904 .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev, 7936 .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev,
7905 .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 7937 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
7938 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
7906 .get_txbf_conf_scheme = ath10k_wmi_10_4_txbf_conf_scheme, 7939 .get_txbf_conf_scheme = ath10k_wmi_10_4_txbf_conf_scheme,
7907 7940
7908 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 7941 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 90f594e89f94..3ef468893b3f 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4340,7 +4340,6 @@ struct wmi_10_4_peer_stats {
4340} __packed; 4340} __packed;
4341 4341
4342struct wmi_10_4_peer_extd_stats { 4342struct wmi_10_4_peer_extd_stats {
4343 struct wmi_10_4_peer_stats common;
4344 struct wmi_mac_addr peer_macaddr; 4343 struct wmi_mac_addr peer_macaddr;
4345 __le32 inactive_time; 4344 __le32 inactive_time;
4346 __le32 peer_chain_rssi; 4345 __le32 peer_chain_rssi;
@@ -4348,6 +4347,19 @@ struct wmi_10_4_peer_extd_stats {
4348 __le32 reserved[10]; 4347 __le32 reserved[10];
4349} __packed; 4348} __packed;
4350 4349
4350struct wmi_10_4_bss_bcn_stats {
4351 __le32 vdev_id;
4352 __le32 bss_bcns_dropped;
4353 __le32 bss_bcn_delivered;
4354} __packed;
4355
4356struct wmi_10_4_bss_bcn_filter_stats {
4357 __le32 bcns_dropped;
4358 __le32 bcns_delivered;
4359 __le32 active_filters;
4360 struct wmi_10_4_bss_bcn_stats bss_stats;
4361} __packed;
4362
4351struct wmi_10_2_pdev_ext_stats { 4363struct wmi_10_2_pdev_ext_stats {
4352 __le32 rx_rssi_comb; 4364 __le32 rx_rssi_comb;
4353 __le32 rx_rssi[4]; 4365 __le32 rx_rssi[4];
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index d0224fc58e78..5bd2cbaf582d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4175,7 +4175,7 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
4175 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah)) 4175 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah))
4176 ar9003_hw_internal_regulator_apply(ah); 4176 ar9003_hw_internal_regulator_apply(ah);
4177 ar9003_hw_apply_tuning_caps(ah); 4177 ar9003_hw_apply_tuning_caps(ah);
4178 ar9003_hw_apply_minccapwr_thresh(ah, chan); 4178 ar9003_hw_apply_minccapwr_thresh(ah, is2ghz);
4179 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz); 4179 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
4180 ar9003_hw_thermometer_apply(ah); 4180 ar9003_hw_thermometer_apply(ah);
4181 ar9003_hw_thermo_cal_apply(ah); 4181 ar9003_hw_thermo_cal_apply(ah);
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 93b3793cce2f..26fc8ecfe8c4 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -637,6 +637,8 @@ struct ath9k_vif_iter_data {
637 int nwds; /* number of WDS vifs */ 637 int nwds; /* number of WDS vifs */
638 int nadhocs; /* number of adhoc vifs */ 638 int nadhocs; /* number of adhoc vifs */
639 int nocbs; /* number of OCB vifs */ 639 int nocbs; /* number of OCB vifs */
640 int nbcnvifs; /* number of beaconing vifs */
641 struct ieee80211_vif *primary_beacon_vif;
640 struct ieee80211_vif *primary_sta; 642 struct ieee80211_vif *primary_sta;
641}; 643};
642 644
@@ -685,10 +687,11 @@ struct ath_beacon {
685}; 687};
686 688
687void ath9k_beacon_tasklet(unsigned long data); 689void ath9k_beacon_tasklet(unsigned long data);
688void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, 690void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *main_vif,
689 u32 changed); 691 bool beacons);
690void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif); 692void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
691void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); 693void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
694void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc);
692void ath9k_set_beacon(struct ath_softc *sc); 695void ath9k_set_beacon(struct ath_softc *sc);
693bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif); 696bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif);
694void ath9k_csa_update(struct ath_softc *sc); 697void ath9k_csa_update(struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 5cf0cd7cb2d1..e36f947e19fc 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -50,7 +50,7 @@ static void ath9k_beaconq_config(struct ath_softc *sc)
50 txq = sc->tx.txq_map[IEEE80211_AC_BE]; 50 txq = sc->tx.txq_map[IEEE80211_AC_BE];
51 ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); 51 ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be);
52 qi.tqi_aifs = qi_be.tqi_aifs; 52 qi.tqi_aifs = qi_be.tqi_aifs;
53 if (ah->slottime == ATH9K_SLOT_TIME_20) 53 if (ah->slottime == 20)
54 qi.tqi_cwmin = 2*qi_be.tqi_cwmin; 54 qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
55 else 55 else
56 qi.tqi_cwmin = 4*qi_be.tqi_cwmin; 56 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
@@ -209,7 +209,6 @@ void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif)
209 } 209 }
210 210
211 sc->beacon.bslot[avp->av_bslot] = vif; 211 sc->beacon.bslot[avp->av_bslot] = vif;
212 sc->nbcnvifs++;
213 212
214 ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n", 213 ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n",
215 avp->av_bslot); 214 avp->av_bslot);
@@ -220,15 +219,12 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif)
220 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 219 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
221 struct ath_vif *avp = (void *)vif->drv_priv; 220 struct ath_vif *avp = (void *)vif->drv_priv;
222 struct ath_buf *bf = avp->av_bcbuf; 221 struct ath_buf *bf = avp->av_bcbuf;
223 struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
224 222
225 ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n", 223 ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n",
226 avp->av_bslot); 224 avp->av_bslot);
227 225
228 tasklet_disable(&sc->bcon_tasklet); 226 tasklet_disable(&sc->bcon_tasklet);
229 227
230 cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
231
232 if (bf && bf->bf_mpdu) { 228 if (bf && bf->bf_mpdu) {
233 struct sk_buff *skb = bf->bf_mpdu; 229 struct sk_buff *skb = bf->bf_mpdu;
234 dma_unmap_single(sc->dev, bf->bf_buf_addr, 230 dma_unmap_single(sc->dev, bf->bf_buf_addr,
@@ -240,12 +236,73 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif)
240 236
241 avp->av_bcbuf = NULL; 237 avp->av_bcbuf = NULL;
242 sc->beacon.bslot[avp->av_bslot] = NULL; 238 sc->beacon.bslot[avp->av_bslot] = NULL;
243 sc->nbcnvifs--;
244 list_add_tail(&bf->list, &sc->beacon.bbuf); 239 list_add_tail(&bf->list, &sc->beacon.bbuf);
245 240
246 tasklet_enable(&sc->bcon_tasklet); 241 tasklet_enable(&sc->bcon_tasklet);
247} 242}
248 243
244void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc)
245{
246 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
247 struct ieee80211_vif *vif;
248 struct ath_vif *avp;
249 s64 tsfadjust;
250 u32 offset;
251 int first_slot = ATH_BCBUF;
252 int slot;
253
254 tasklet_disable(&sc->bcon_tasklet);
255
256 /* Find first taken slot. */
257 for (slot = 0; slot < ATH_BCBUF; slot++) {
258 if (sc->beacon.bslot[slot]) {
259 first_slot = slot;
260 break;
261 }
262 }
263 if (first_slot == 0)
264 goto out;
265
266 /* Re-enumarate all slots, moving them forward. */
267 for (slot = 0; slot < ATH_BCBUF; slot++) {
268 if (slot + first_slot < ATH_BCBUF) {
269 vif = sc->beacon.bslot[slot + first_slot];
270 sc->beacon.bslot[slot] = vif;
271
272 if (vif) {
273 avp = (void *)vif->drv_priv;
274 avp->av_bslot = slot;
275 }
276 } else {
277 sc->beacon.bslot[slot] = NULL;
278 }
279 }
280
281 vif = sc->beacon.bslot[0];
282 if (WARN_ON(!vif))
283 goto out;
284
285 /* Get the tsf_adjust value for the new first slot. */
286 avp = (void *)vif->drv_priv;
287 tsfadjust = le64_to_cpu(avp->tsf_adjust);
288
289 ath_dbg(common, CONFIG,
290 "Adjusting global TSF after beacon slot reassignment: %lld\n",
291 (signed long long)tsfadjust);
292
293 /* Modify TSF as required and update the HW. */
294 avp->chanctx->tsf_val += tsfadjust;
295 if (sc->cur_chan == avp->chanctx) {
296 offset = ath9k_hw_get_tsf_offset(&avp->chanctx->tsf_ts, NULL);
297 ath9k_hw_settsf64(sc->sc_ah, avp->chanctx->tsf_val + offset);
298 }
299
300 /* The slots tsf_adjust will be updated by ath9k_beacon_config later. */
301
302out:
303 tasklet_enable(&sc->bcon_tasklet);
304}
305
249static int ath9k_beacon_choose_slot(struct ath_softc *sc) 306static int ath9k_beacon_choose_slot(struct ath_softc *sc)
250{ 307{
251 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 308 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -274,22 +331,33 @@ static int ath9k_beacon_choose_slot(struct ath_softc *sc)
274 return slot; 331 return slot;
275} 332}
276 333
277static void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif) 334static void ath9k_set_tsfadjust(struct ath_softc *sc,
335 struct ath_beacon_config *cur_conf)
278{ 336{
279 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 337 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
280 struct ath_vif *avp = (void *)vif->drv_priv; 338 s64 tsfadjust;
281 struct ath_beacon_config *cur_conf = &avp->chanctx->beacon; 339 int slot;
282 u32 tsfadjust;
283 340
284 if (avp->av_bslot == 0) 341 for (slot = 0; slot < ATH_BCBUF; slot++) {
285 return; 342 struct ath_vif *avp;
286 343
287 tsfadjust = cur_conf->beacon_interval * avp->av_bslot; 344 if (!sc->beacon.bslot[slot])
288 tsfadjust = TU_TO_USEC(tsfadjust) / ATH_BCBUF; 345 continue;
289 avp->tsf_adjust = cpu_to_le64(tsfadjust);
290 346
291 ath_dbg(common, CONFIG, "tsfadjust is: %llu for bslot: %d\n", 347 avp = (void *)sc->beacon.bslot[slot]->drv_priv;
292 (unsigned long long)tsfadjust, avp->av_bslot); 348
349 /* tsf_adjust is added to the TSF value. We send out the
350 * beacon late, so need to adjust the TSF starting point to be
351 * later in time (i.e. the theoretical first beacon has a TSF
352 * of 0 after correction).
353 */
354 tsfadjust = cur_conf->beacon_interval * avp->av_bslot;
355 tsfadjust = -TU_TO_USEC(tsfadjust) / ATH_BCBUF;
356 avp->tsf_adjust = cpu_to_le64(tsfadjust);
357
358 ath_dbg(common, CONFIG, "tsfadjust is: %lld for bslot: %d\n",
359 (signed long long)tsfadjust, avp->av_bslot);
360 }
293} 361}
294 362
295bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif) 363bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif)
@@ -443,20 +511,28 @@ void ath9k_beacon_tasklet(unsigned long data)
443 * Both nexttbtt and intval have to be in usecs. 511 * Both nexttbtt and intval have to be in usecs.
444 */ 512 */
445static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt, 513static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt,
446 u32 intval, bool reset_tsf) 514 u32 intval)
447{ 515{
448 struct ath_hw *ah = sc->sc_ah; 516 struct ath_hw *ah = sc->sc_ah;
449 517
450 ath9k_hw_disable_interrupts(ah); 518 ath9k_hw_disable_interrupts(ah);
451 if (reset_tsf)
452 ath9k_hw_reset_tsf(ah);
453 ath9k_beaconq_config(sc); 519 ath9k_beaconq_config(sc);
454 ath9k_hw_beaconinit(ah, nexttbtt, intval); 520 ath9k_hw_beaconinit(ah, nexttbtt, intval);
521 ah->imask |= ATH9K_INT_SWBA;
455 sc->beacon.bmisscnt = 0; 522 sc->beacon.bmisscnt = 0;
456 ath9k_hw_set_interrupts(ah); 523 ath9k_hw_set_interrupts(ah);
457 ath9k_hw_enable_interrupts(ah); 524 ath9k_hw_enable_interrupts(ah);
458} 525}
459 526
527static void ath9k_beacon_stop(struct ath_softc *sc)
528{
529 ath9k_hw_disable_interrupts(sc->sc_ah);
530 sc->sc_ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
531 sc->beacon.bmisscnt = 0;
532 ath9k_hw_set_interrupts(sc->sc_ah);
533 ath9k_hw_enable_interrupts(sc->sc_ah);
534}
535
460/* 536/*
461 * For multi-bss ap support beacons are either staggered evenly over N slots or 537 * For multi-bss ap support beacons are either staggered evenly over N slots or
462 * burst together. For the former arrange for the SWBA to be delivered for each 538 * burst together. For the former arrange for the SWBA to be delivered for each
@@ -468,7 +544,7 @@ static void ath9k_beacon_config_ap(struct ath_softc *sc,
468 struct ath_hw *ah = sc->sc_ah; 544 struct ath_hw *ah = sc->sc_ah;
469 545
470 ath9k_cmn_beacon_config_ap(ah, conf, ATH_BCBUF); 546 ath9k_cmn_beacon_config_ap(ah, conf, ATH_BCBUF);
471 ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, false); 547 ath9k_beacon_init(sc, conf->nexttbtt, conf->intval);
472} 548}
473 549
474static void ath9k_beacon_config_sta(struct ath_hw *ah, 550static void ath9k_beacon_config_sta(struct ath_hw *ah,
@@ -497,7 +573,7 @@ static void ath9k_beacon_config_adhoc(struct ath_softc *sc,
497 573
498 ath9k_cmn_beacon_config_adhoc(ah, conf); 574 ath9k_cmn_beacon_config_adhoc(ah, conf);
499 575
500 ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, conf->ibss_creator); 576 ath9k_beacon_init(sc, conf->nexttbtt, conf->intval);
501 577
502 /* 578 /*
503 * Set the global 'beacon has been configured' flag for the 579 * Set the global 'beacon has been configured' flag for the
@@ -507,44 +583,6 @@ static void ath9k_beacon_config_adhoc(struct ath_softc *sc,
507 set_bit(ATH_OP_BEACONS, &common->op_flags); 583 set_bit(ATH_OP_BEACONS, &common->op_flags);
508} 584}
509 585
510static bool ath9k_allow_beacon_config(struct ath_softc *sc,
511 struct ieee80211_vif *vif)
512{
513 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
514 struct ath_vif *avp = (void *)vif->drv_priv;
515
516 if (ath9k_is_chanctx_enabled()) {
517 /*
518 * If the VIF is not present in the current channel context,
519 * then we can't do the usual opmode checks. Allow the
520 * beacon config for the VIF to be updated in this case and
521 * return immediately.
522 */
523 if (sc->cur_chan != avp->chanctx)
524 return true;
525 }
526
527 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
528 if (vif->type != NL80211_IFTYPE_AP) {
529 ath_dbg(common, CONFIG,
530 "An AP interface is already present !\n");
531 return false;
532 }
533 }
534
535 if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
536 if ((vif->type == NL80211_IFTYPE_STATION) &&
537 test_bit(ATH_OP_BEACONS, &common->op_flags) &&
538 vif != sc->cur_chan->primary_sta) {
539 ath_dbg(common, CONFIG,
540 "Beacon already configured for a station interface\n");
541 return false;
542 }
543 }
544
545 return true;
546}
547
548static void ath9k_cache_beacon_config(struct ath_softc *sc, 586static void ath9k_cache_beacon_config(struct ath_softc *sc,
549 struct ath_chanctx *ctx, 587 struct ath_chanctx *ctx,
550 struct ieee80211_bss_conf *bss_conf) 588 struct ieee80211_bss_conf *bss_conf)
@@ -580,87 +618,79 @@ static void ath9k_cache_beacon_config(struct ath_softc *sc,
580 if (cur_conf->dtim_period == 0) 618 if (cur_conf->dtim_period == 0)
581 cur_conf->dtim_period = 1; 619 cur_conf->dtim_period = 1;
582 620
621 ath9k_set_tsfadjust(sc, cur_conf);
583} 622}
584 623
585void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, 624void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *main_vif,
586 u32 changed) 625 bool beacons)
587{ 626{
588 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 627 struct ath_hw *ah = sc->sc_ah;
589 struct ath_hw *ah = sc->sc_ah; 628 struct ath_common *common = ath9k_hw_common(ah);
590 struct ath_common *common = ath9k_hw_common(ah); 629 struct ath_vif *avp;
591 struct ath_vif *avp = (void *)vif->drv_priv; 630 struct ath_chanctx *ctx;
592 struct ath_chanctx *ctx = avp->chanctx;
593 struct ath_beacon_config *cur_conf; 631 struct ath_beacon_config *cur_conf;
594 unsigned long flags; 632 unsigned long flags;
633 bool enabled;
595 bool skip_beacon = false; 634 bool skip_beacon = false;
596 635
597 if (!ctx) 636 if (!beacons) {
637 clear_bit(ATH_OP_BEACONS, &common->op_flags);
638 ath9k_beacon_stop(sc);
598 return; 639 return;
640 }
599 641
600 cur_conf = &avp->chanctx->beacon; 642 if (WARN_ON(!main_vif))
601 if (vif->type == NL80211_IFTYPE_AP)
602 ath9k_set_tsfadjust(sc, vif);
603
604 if (!ath9k_allow_beacon_config(sc, vif))
605 return; 643 return;
606 644
607 if (vif->type == NL80211_IFTYPE_STATION) { 645 avp = (void *)main_vif->drv_priv;
608 ath9k_cache_beacon_config(sc, ctx, bss_conf); 646 ctx = avp->chanctx;
609 if (ctx != sc->cur_chan) 647 cur_conf = &ctx->beacon;
610 return; 648 enabled = cur_conf->enable_beacon;
649 cur_conf->enable_beacon = beacons;
650
651 if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
652 ath9k_cache_beacon_config(sc, ctx, &main_vif->bss_conf);
611 653
612 ath9k_set_beacon(sc); 654 ath9k_set_beacon(sc);
613 set_bit(ATH_OP_BEACONS, &common->op_flags); 655 set_bit(ATH_OP_BEACONS, &common->op_flags);
614 return; 656 return;
615 } 657 }
616 658
617 /* 659 /* Update the beacon configuration. */
618 * Take care of multiple interfaces when 660 ath9k_cache_beacon_config(sc, ctx, &main_vif->bss_conf);
619 * enabling/disabling SWBA.
620 */
621 if (changed & BSS_CHANGED_BEACON_ENABLED) {
622 bool enabled = cur_conf->enable_beacon;
623
624 if (!bss_conf->enable_beacon) {
625 cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
626 } else {
627 cur_conf->enable_beacon |= BIT(avp->av_bslot);
628 if (!enabled)
629 ath9k_cache_beacon_config(sc, ctx, bss_conf);
630 }
631 }
632
633 if (ctx != sc->cur_chan)
634 return;
635 661
636 /* 662 /*
637 * Configure the HW beacon registers only when we have a valid 663 * Configure the HW beacon registers only when we have a valid
638 * beacon interval. 664 * beacon interval.
639 */ 665 */
640 if (cur_conf->beacon_interval) { 666 if (cur_conf->beacon_interval) {
641 /* 667 /* Special case to sync the TSF when joining an existing IBSS.
642 * If we are joining an existing IBSS network, start beaconing 668 * This is only done if no AP interface is active.
643 * only after a TSF-sync has taken place. Ensure that this 669 * Note that mac80211 always resets the TSF when creating a new
644 * happens by setting the appropriate flags. 670 * IBSS interface.
645 */ 671 */
646 if ((changed & BSS_CHANGED_IBSS) && !bss_conf->ibss_creator && 672 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC &&
647 bss_conf->enable_beacon) { 673 !enabled && beacons && !main_vif->bss_conf.ibss_creator) {
648 spin_lock_irqsave(&sc->sc_pm_lock, flags); 674 spin_lock_irqsave(&sc->sc_pm_lock, flags);
649 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; 675 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
650 spin_unlock_irqrestore(&sc->sc_pm_lock, flags); 676 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
651 skip_beacon = true; 677 skip_beacon = true;
652 } else {
653 ath9k_set_beacon(sc);
654 } 678 }
655 679
656 /* 680 /*
657 * Do not set the ATH_OP_BEACONS flag for IBSS joiner mode 681 * Do not set the ATH_OP_BEACONS flag for IBSS joiner mode
658 * here, it is done in ath9k_beacon_config_adhoc(). 682 * here, it is done in ath9k_beacon_config_adhoc().
659 */ 683 */
660 if (cur_conf->enable_beacon && !skip_beacon) 684 if (beacons && !skip_beacon) {
661 set_bit(ATH_OP_BEACONS, &common->op_flags); 685 set_bit(ATH_OP_BEACONS, &common->op_flags);
662 else 686 ath9k_set_beacon(sc);
687 } else {
663 clear_bit(ATH_OP_BEACONS, &common->op_flags); 688 clear_bit(ATH_OP_BEACONS, &common->op_flags);
689 ath9k_beacon_stop(sc);
690 }
691 } else {
692 clear_bit(ATH_OP_BEACONS, &common->op_flags);
693 ath9k_beacon_stop(sc);
664 } 694 }
665} 695}
666 696
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index d23737342f4f..f0ab6f9955e4 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -50,6 +50,7 @@
50#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) 50#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
51 51
52struct ath_beacon_config { 52struct ath_beacon_config {
53 struct ieee80211_vif *main_vif;
53 int beacon_interval; 54 int beacon_interval;
54 u16 dtim_period; 55 u16 dtim_period;
55 u16 bmiss_timeout; 56 u16 bmiss_timeout;
diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c
index d2ff0fc0484c..7334c9b09e82 100644
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -280,7 +280,7 @@ EXPORT_SYMBOL(ath_dynack_sample_ack_ts);
280void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an) 280void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an)
281{ 281{
282 /* ackto = slottime + sifs + air delay */ 282 /* ackto = slottime + sifs + air delay */
283 u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64; 283 u32 ackto = 9 + 16 + 64;
284 struct ath_dynack *da = &ah->dynack; 284 struct ath_dynack *da = &ah->dynack;
285 285
286 an->ackto = ackto; 286 an->ackto = ackto;
@@ -315,7 +315,7 @@ EXPORT_SYMBOL(ath_dynack_node_deinit);
315void ath_dynack_reset(struct ath_hw *ah) 315void ath_dynack_reset(struct ath_hw *ah)
316{ 316{
317 /* ackto = slottime + sifs + air delay */ 317 /* ackto = slottime + sifs + air delay */
318 u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64; 318 u32 ackto = 9 + 16 + 64;
319 struct ath_dynack *da = &ah->dynack; 319 struct ath_dynack *da = &ah->dynack;
320 320
321 da->lto = jiffies; 321 da->lto = jiffies;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index e6bcb4c90fa0..2c0e4d26e8f9 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -45,7 +45,7 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
45 * Long slot time : 2x cwmin 45 * Long slot time : 2x cwmin
46 * Short slot time : 4x cwmin 46 * Short slot time : 4x cwmin
47 */ 47 */
48 if (ah->slottime == ATH9K_SLOT_TIME_20) 48 if (ah->slottime == 20)
49 qi.tqi_cwmin = 2*qi_be.tqi_cwmin; 49 qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
50 else 50 else
51 qi.tqi_cwmin = 4*qi_be.tqi_cwmin; 51 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index c148c6c504f7..b65c1b661ade 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -678,7 +678,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
678 678
679 for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) 679 for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++)
680 priv->beacon.bslot[i] = NULL; 680 priv->beacon.bslot[i] = NULL;
681 priv->beacon.slottime = ATH9K_SLOT_TIME_9; 681 priv->beacon.slottime = 9;
682 682
683 ath9k_cmn_init_channels_rates(common); 683 ath9k_cmn_init_channels_rates(common);
684 ath9k_cmn_init_crypto(ah); 684 ath9k_cmn_init_crypto(ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8b2895f9ac7a..d1d0c06d627c 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -454,7 +454,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
454 if (AR_SREV_9100(ah)) 454 if (AR_SREV_9100(ah))
455 ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; 455 ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
456 456
457 ah->slottime = ATH9K_SLOT_TIME_9; 457 ah->slottime = 9;
458 ah->globaltxtimeout = (u32) -1; 458 ah->globaltxtimeout = (u32) -1;
459 ah->power_mode = ATH9K_PM_UNDEFINED; 459 ah->power_mode = ATH9K_PM_UNDEFINED;
460 ah->htc_reset_init = true; 460 ah->htc_reset_init = true;
@@ -471,33 +471,34 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
471 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); 471 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
472} 472}
473 473
474static int ath9k_hw_init_macaddr(struct ath_hw *ah) 474static void ath9k_hw_init_macaddr(struct ath_hw *ah)
475{ 475{
476 struct ath_common *common = ath9k_hw_common(ah); 476 struct ath_common *common = ath9k_hw_common(ah);
477 u32 sum;
478 int i; 477 int i;
479 u16 eeval; 478 u16 eeval;
480 static const u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW }; 479 static const u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW };
481 480
482 sum = 0; 481 /* MAC address may already be loaded via ath9k_platform_data */
482 if (is_valid_ether_addr(common->macaddr))
483 return;
484
483 for (i = 0; i < 3; i++) { 485 for (i = 0; i < 3; i++) {
484 eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]); 486 eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]);
485 sum += eeval;
486 common->macaddr[2 * i] = eeval >> 8; 487 common->macaddr[2 * i] = eeval >> 8;
487 common->macaddr[2 * i + 1] = eeval & 0xff; 488 common->macaddr[2 * i + 1] = eeval & 0xff;
488 } 489 }
489 if (!is_valid_ether_addr(common->macaddr)) {
490 ath_err(common,
491 "eeprom contains invalid mac address: %pM\n",
492 common->macaddr);
493 490
494 random_ether_addr(common->macaddr); 491 if (is_valid_ether_addr(common->macaddr))
495 ath_err(common, 492 return;
496 "random mac address will be used: %pM\n",
497 common->macaddr);
498 }
499 493
500 return 0; 494 ath_err(common, "eeprom contains invalid mac address: %pM\n",
495 common->macaddr);
496
497 random_ether_addr(common->macaddr);
498 ath_err(common, "random mac address will be used: %pM\n",
499 common->macaddr);
500
501 return;
501} 502}
502 503
503static int ath9k_hw_post_init(struct ath_hw *ah) 504static int ath9k_hw_post_init(struct ath_hw *ah)
@@ -636,12 +637,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
636 if (r) 637 if (r)
637 return r; 638 return r;
638 639
639 r = ath9k_hw_init_macaddr(ah); 640 ath9k_hw_init_macaddr(ah);
640 if (r) {
641 ath_err(common, "Failed to initialize MAC address\n");
642 return r;
643 }
644
645 ath9k_hw_init_hang_checks(ah); 641 ath9k_hw_init_hang_checks(ah);
646 642
647 common->state = ATH_HW_INITIALIZED; 643 common->state = ATH_HW_INITIALIZED;
@@ -1832,8 +1828,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1832 u32 saveLedState; 1828 u32 saveLedState;
1833 u32 saveDefAntenna; 1829 u32 saveDefAntenna;
1834 u32 macStaId1; 1830 u32 macStaId1;
1831 struct timespec tsf_ts;
1832 u32 tsf_offset;
1835 u64 tsf = 0; 1833 u64 tsf = 0;
1836 s64 usec = 0;
1837 int r; 1834 int r;
1838 bool start_mci_reset = false; 1835 bool start_mci_reset = false;
1839 bool save_fullsleep = ah->chip_fullsleep; 1836 bool save_fullsleep = ah->chip_fullsleep;
@@ -1877,8 +1874,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1877 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; 1874 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
1878 1875
1879 /* Save TSF before chip reset, a cold reset clears it */ 1876 /* Save TSF before chip reset, a cold reset clears it */
1877 getrawmonotonic(&tsf_ts);
1880 tsf = ath9k_hw_gettsf64(ah); 1878 tsf = ath9k_hw_gettsf64(ah);
1881 usec = ktime_to_us(ktime_get_raw());
1882 1879
1883 saveLedState = REG_READ(ah, AR_CFG_LED) & 1880 saveLedState = REG_READ(ah, AR_CFG_LED) &
1884 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | 1881 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
@@ -1911,8 +1908,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1911 } 1908 }
1912 1909
1913 /* Restore TSF */ 1910 /* Restore TSF */
1914 usec = ktime_to_us(ktime_get_raw()) - usec; 1911 tsf_offset = ath9k_hw_get_tsf_offset(&tsf_ts, NULL);
1915 ath9k_hw_settsf64(ah, tsf + usec); 1912 ath9k_hw_settsf64(ah, tsf + tsf_offset);
1916 1913
1917 if (AR_SREV_9280_20_OR_LATER(ah)) 1914 if (AR_SREV_9280_20_OR_LATER(ah))
1918 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 1915 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
@@ -1932,12 +1929,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1932 /* 1929 /*
1933 * Some AR91xx SoC devices frequently fail to accept TSF writes 1930 * Some AR91xx SoC devices frequently fail to accept TSF writes
1934 * right after the chip reset. When that happens, write a new 1931 * right after the chip reset. When that happens, write a new
1935 * value after the initvals have been applied, with an offset 1932 * value after the initvals have been applied.
1936 * based on measured time difference
1937 */ 1933 */
1938 if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) { 1934 if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) {
1939 tsf += 1500; 1935 tsf_offset = ath9k_hw_get_tsf_offset(&tsf_ts, NULL);
1940 ath9k_hw_settsf64(ah, tsf); 1936 ath9k_hw_settsf64(ah, tsf + tsf_offset);
1941 } 1937 }
1942 1938
1943 ath9k_hw_init_mfp(ah); 1939 ath9k_hw_init_mfp(ah);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 2ee8624755f7..edc74fca60aa 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -372,7 +372,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
372 372
373 common->last_rssi = ATH_RSSI_DUMMY_MARKER; 373 common->last_rssi = ATH_RSSI_DUMMY_MARKER;
374 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); 374 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
375 sc->beacon.slottime = ATH9K_SLOT_TIME_9; 375 sc->beacon.slottime = 9;
376 376
377 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) 377 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
378 sc->beacon.bslot[i] = NULL; 378 sc->beacon.bslot[i] = NULL;
@@ -512,31 +512,52 @@ static void ath9k_eeprom_release(struct ath_softc *sc)
512 release_firmware(sc->sc_ah->eeprom_blob); 512 release_firmware(sc->sc_ah->eeprom_blob);
513} 513}
514 514
515static int ath9k_init_soc_platform(struct ath_softc *sc) 515static int ath9k_init_platform(struct ath_softc *sc)
516{ 516{
517 struct ath9k_platform_data *pdata = sc->dev->platform_data; 517 struct ath9k_platform_data *pdata = sc->dev->platform_data;
518 struct ath_hw *ah = sc->sc_ah; 518 struct ath_hw *ah = sc->sc_ah;
519 int ret = 0; 519 struct ath_common *common = ath9k_hw_common(ah);
520 int ret;
520 521
521 if (!pdata) 522 if (!pdata)
522 return 0; 523 return 0;
523 524
525 if (!pdata->use_eeprom) {
526 ah->ah_flags &= ~AH_USE_EEPROM;
527 ah->gpio_mask = pdata->gpio_mask;
528 ah->gpio_val = pdata->gpio_val;
529 ah->led_pin = pdata->led_pin;
530 ah->is_clk_25mhz = pdata->is_clk_25mhz;
531 ah->get_mac_revision = pdata->get_mac_revision;
532 ah->external_reset = pdata->external_reset;
533 ah->disable_2ghz = pdata->disable_2ghz;
534 ah->disable_5ghz = pdata->disable_5ghz;
535
536 if (!pdata->endian_check)
537 ah->ah_flags |= AH_NO_EEP_SWAP;
538 }
539
524 if (pdata->eeprom_name) { 540 if (pdata->eeprom_name) {
525 ret = ath9k_eeprom_request(sc, pdata->eeprom_name); 541 ret = ath9k_eeprom_request(sc, pdata->eeprom_name);
526 if (ret) 542 if (ret)
527 return ret; 543 return ret;
528 } 544 }
529 545
546 if (pdata->led_active_high)
547 ah->config.led_active_high = true;
548
530 if (pdata->tx_gain_buffalo) 549 if (pdata->tx_gain_buffalo)
531 ah->config.tx_gain_buffalo = true; 550 ah->config.tx_gain_buffalo = true;
532 551
533 return ret; 552 if (pdata->macaddr)
553 ether_addr_copy(common->macaddr, pdata->macaddr);
554
555 return 0;
534} 556}
535 557
536static int ath9k_init_softc(u16 devid, struct ath_softc *sc, 558static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
537 const struct ath_bus_ops *bus_ops) 559 const struct ath_bus_ops *bus_ops)
538{ 560{
539 struct ath9k_platform_data *pdata = sc->dev->platform_data;
540 struct ath_hw *ah = NULL; 561 struct ath_hw *ah = NULL;
541 struct ath9k_hw_capabilities *pCap; 562 struct ath9k_hw_capabilities *pCap;
542 struct ath_common *common; 563 struct ath_common *common;
@@ -550,6 +571,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
550 ah->dev = sc->dev; 571 ah->dev = sc->dev;
551 ah->hw = sc->hw; 572 ah->hw = sc->hw;
552 ah->hw_version.devid = devid; 573 ah->hw_version.devid = devid;
574 ah->ah_flags |= AH_USE_EEPROM;
575 ah->led_pin = -1;
553 ah->reg_ops.read = ath9k_ioread32; 576 ah->reg_ops.read = ath9k_ioread32;
554 ah->reg_ops.multi_read = ath9k_multi_ioread32; 577 ah->reg_ops.multi_read = ath9k_multi_ioread32;
555 ah->reg_ops.write = ath9k_iowrite32; 578 ah->reg_ops.write = ath9k_iowrite32;
@@ -569,22 +592,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
569 if (!ath9k_is_chanctx_enabled()) 592 if (!ath9k_is_chanctx_enabled())
570 sc->cur_chan->hw_queue_base = 0; 593 sc->cur_chan->hw_queue_base = 0;
571 594
572 if (!pdata || pdata->use_eeprom) {
573 ah->ah_flags |= AH_USE_EEPROM;
574 sc->sc_ah->led_pin = -1;
575 } else {
576 sc->sc_ah->gpio_mask = pdata->gpio_mask;
577 sc->sc_ah->gpio_val = pdata->gpio_val;
578 sc->sc_ah->led_pin = pdata->led_pin;
579 ah->is_clk_25mhz = pdata->is_clk_25mhz;
580 ah->get_mac_revision = pdata->get_mac_revision;
581 ah->external_reset = pdata->external_reset;
582 ah->disable_2ghz = pdata->disable_2ghz;
583 ah->disable_5ghz = pdata->disable_5ghz;
584 if (!pdata->endian_check)
585 ah->ah_flags |= AH_NO_EEP_SWAP;
586 }
587
588 common->ops = &ah->reg_ops; 595 common->ops = &ah->reg_ops;
589 common->bus_ops = bus_ops; 596 common->bus_ops = bus_ops;
590 common->ps_ops = &ath9k_ps_ops; 597 common->ps_ops = &ath9k_ps_ops;
@@ -600,7 +607,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
600 */ 607 */
601 ath9k_init_pcoem_platform(sc); 608 ath9k_init_pcoem_platform(sc);
602 609
603 ret = ath9k_init_soc_platform(sc); 610 ret = ath9k_init_platform(sc);
604 if (ret) 611 if (ret)
605 return ret; 612 return ret;
606 613
@@ -646,9 +653,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
646 if (ret) 653 if (ret)
647 goto err_hw; 654 goto err_hw;
648 655
649 if (pdata && pdata->macaddr)
650 memcpy(common->macaddr, pdata->macaddr, ETH_ALEN);
651
652 ret = ath9k_init_queues(sc); 656 ret = ath9k_init_queues(sc);
653 if (ret) 657 if (ret)
654 goto err_queues; 658 goto err_queues;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 7fbf7f965f61..3bab01435a86 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -65,10 +65,6 @@
65#define INIT_SSH_RETRY 32 65#define INIT_SSH_RETRY 32
66#define INIT_SLG_RETRY 32 66#define INIT_SLG_RETRY 32
67 67
68#define ATH9K_SLOT_TIME_6 6
69#define ATH9K_SLOT_TIME_9 9
70#define ATH9K_SLOT_TIME_20 20
71
72#define ATH9K_TXERR_XRETRY 0x01 68#define ATH9K_TXERR_XRETRY 0x01
73#define ATH9K_TXERR_FILT 0x02 69#define ATH9K_TXERR_FILT 0x02
74#define ATH9K_TXERR_FIFO 0x04 70#define ATH9K_TXERR_FIFO 0x04
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 8b6398850657..7594650f214f 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -910,6 +910,22 @@ static bool ath9k_uses_beacons(int type)
910 } 910 }
911} 911}
912 912
913static void ath9k_vif_iter_set_beacon(struct ath9k_vif_iter_data *iter_data,
914 struct ieee80211_vif *vif)
915{
916 /* Use the first (configured) interface, but prefering AP interfaces. */
917 if (!iter_data->primary_beacon_vif) {
918 iter_data->primary_beacon_vif = vif;
919 } else {
920 if (iter_data->primary_beacon_vif->type != NL80211_IFTYPE_AP &&
921 vif->type == NL80211_IFTYPE_AP)
922 iter_data->primary_beacon_vif = vif;
923 }
924
925 iter_data->beacons = true;
926 iter_data->nbcnvifs += 1;
927}
928
913static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, 929static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data,
914 u8 *mac, struct ieee80211_vif *vif) 930 u8 *mac, struct ieee80211_vif *vif)
915{ 931{
@@ -926,11 +942,13 @@ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data,
926 } 942 }
927 943
928 if (!vif->bss_conf.use_short_slot) 944 if (!vif->bss_conf.use_short_slot)
929 iter_data->slottime = ATH9K_SLOT_TIME_20; 945 iter_data->slottime = 20;
930 946
931 switch (vif->type) { 947 switch (vif->type) {
932 case NL80211_IFTYPE_AP: 948 case NL80211_IFTYPE_AP:
933 iter_data->naps++; 949 iter_data->naps++;
950 if (vif->bss_conf.enable_beacon)
951 ath9k_vif_iter_set_beacon(iter_data, vif);
934 break; 952 break;
935 case NL80211_IFTYPE_STATION: 953 case NL80211_IFTYPE_STATION:
936 iter_data->nstations++; 954 iter_data->nstations++;
@@ -943,12 +961,12 @@ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data,
943 case NL80211_IFTYPE_ADHOC: 961 case NL80211_IFTYPE_ADHOC:
944 iter_data->nadhocs++; 962 iter_data->nadhocs++;
945 if (vif->bss_conf.enable_beacon) 963 if (vif->bss_conf.enable_beacon)
946 iter_data->beacons = true; 964 ath9k_vif_iter_set_beacon(iter_data, vif);
947 break; 965 break;
948 case NL80211_IFTYPE_MESH_POINT: 966 case NL80211_IFTYPE_MESH_POINT:
949 iter_data->nmeshes++; 967 iter_data->nmeshes++;
950 if (vif->bss_conf.enable_beacon) 968 if (vif->bss_conf.enable_beacon)
951 iter_data->beacons = true; 969 ath9k_vif_iter_set_beacon(iter_data, vif);
952 break; 970 break;
953 case NL80211_IFTYPE_WDS: 971 case NL80211_IFTYPE_WDS:
954 iter_data->nwds++; 972 iter_data->nwds++;
@@ -999,7 +1017,7 @@ void ath9k_calculate_iter_data(struct ath_softc *sc,
999 */ 1017 */
1000 memset(iter_data, 0, sizeof(*iter_data)); 1018 memset(iter_data, 0, sizeof(*iter_data));
1001 eth_broadcast_addr(iter_data->mask); 1019 eth_broadcast_addr(iter_data->mask);
1002 iter_data->slottime = ATH9K_SLOT_TIME_9; 1020 iter_data->slottime = 9;
1003 1021
1004 list_for_each_entry(avp, &ctx->vifs, list) 1022 list_for_each_entry(avp, &ctx->vifs, list)
1005 ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); 1023 ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif);
@@ -1061,7 +1079,7 @@ static void ath9k_set_offchannel_state(struct ath_softc *sc)
1061 ah->opmode = vif->type; 1079 ah->opmode = vif->type;
1062 ah->imask &= ~ATH9K_INT_SWBA; 1080 ah->imask &= ~ATH9K_INT_SWBA;
1063 ah->imask &= ~ATH9K_INT_TSFOOR; 1081 ah->imask &= ~ATH9K_INT_TSFOOR;
1064 ah->slottime = ATH9K_SLOT_TIME_9; 1082 ah->slottime = 9;
1065 1083
1066 ath_hw_setbssidmask(common); 1084 ath_hw_setbssidmask(common);
1067 ath9k_hw_setopmode(ah); 1085 ath9k_hw_setopmode(ah);
@@ -1081,7 +1099,6 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
1081 struct ath_hw *ah = sc->sc_ah; 1099 struct ath_hw *ah = sc->sc_ah;
1082 struct ath_common *common = ath9k_hw_common(ah); 1100 struct ath_common *common = ath9k_hw_common(ah);
1083 struct ath9k_vif_iter_data iter_data; 1101 struct ath9k_vif_iter_data iter_data;
1084 struct ath_beacon_config *cur_conf;
1085 1102
1086 ath_chanctx_check_active(sc, ctx); 1103 ath_chanctx_check_active(sc, ctx);
1087 1104
@@ -1103,13 +1120,12 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
1103 ath_hw_setbssidmask(common); 1120 ath_hw_setbssidmask(common);
1104 1121
1105 if (iter_data.naps > 0) { 1122 if (iter_data.naps > 0) {
1106 cur_conf = &ctx->beacon;
1107 ath9k_hw_set_tsfadjust(ah, true); 1123 ath9k_hw_set_tsfadjust(ah, true);
1108 ah->opmode = NL80211_IFTYPE_AP; 1124 ah->opmode = NL80211_IFTYPE_AP;
1109 if (cur_conf->enable_beacon)
1110 iter_data.beacons = true;
1111 } else { 1125 } else {
1112 ath9k_hw_set_tsfadjust(ah, false); 1126 ath9k_hw_set_tsfadjust(ah, false);
1127 if (iter_data.beacons)
1128 ath9k_beacon_ensure_primary_slot(sc);
1113 1129
1114 if (iter_data.nmeshes) 1130 if (iter_data.nmeshes)
1115 ah->opmode = NL80211_IFTYPE_MESH_POINT; 1131 ah->opmode = NL80211_IFTYPE_MESH_POINT;
@@ -1134,7 +1150,6 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
1134 ctx->switch_after_beacon = true; 1150 ctx->switch_after_beacon = true;
1135 } 1151 }
1136 1152
1137 ah->imask &= ~ATH9K_INT_SWBA;
1138 if (ah->opmode == NL80211_IFTYPE_STATION) { 1153 if (ah->opmode == NL80211_IFTYPE_STATION) {
1139 bool changed = (iter_data.primary_sta != ctx->primary_sta); 1154 bool changed = (iter_data.primary_sta != ctx->primary_sta);
1140 1155
@@ -1151,16 +1166,12 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
1151 if (ath9k_hw_mci_is_enabled(sc->sc_ah)) 1166 if (ath9k_hw_mci_is_enabled(sc->sc_ah))
1152 ath9k_mci_update_wlan_channels(sc, true); 1167 ath9k_mci_update_wlan_channels(sc, true);
1153 } 1168 }
1154 } else if (iter_data.beacons) {
1155 ah->imask |= ATH9K_INT_SWBA;
1156 } 1169 }
1170 sc->nbcnvifs = iter_data.nbcnvifs;
1171 ath9k_beacon_config(sc, iter_data.primary_beacon_vif,
1172 iter_data.beacons);
1157 ath9k_hw_set_interrupts(ah); 1173 ath9k_hw_set_interrupts(ah);
1158 1174
1159 if (iter_data.beacons)
1160 set_bit(ATH_OP_BEACONS, &common->op_flags);
1161 else
1162 clear_bit(ATH_OP_BEACONS, &common->op_flags);
1163
1164 if (ah->slottime != iter_data.slottime) { 1175 if (ah->slottime != iter_data.slottime) {
1165 ah->slottime = iter_data.slottime; 1176 ah->slottime = iter_data.slottime;
1166 ath9k_hw_init_global_settings(ah); 1177 ath9k_hw_init_global_settings(ah);
@@ -1777,9 +1788,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1777 if ((changed & BSS_CHANGED_BEACON_ENABLED) || 1788 if ((changed & BSS_CHANGED_BEACON_ENABLED) ||
1778 (changed & BSS_CHANGED_BEACON_INT) || 1789 (changed & BSS_CHANGED_BEACON_INT) ||
1779 (changed & BSS_CHANGED_BEACON_INFO)) { 1790 (changed & BSS_CHANGED_BEACON_INFO)) {
1780 ath9k_beacon_config(sc, vif, changed); 1791 ath9k_calculate_summary_state(sc, avp->chanctx);
1781 if (changed & BSS_CHANGED_BEACON_ENABLED)
1782 ath9k_calculate_summary_state(sc, avp->chanctx);
1783 } 1792 }
1784 1793
1785 if ((avp->chanctx == sc->cur_chan) && 1794 if ((avp->chanctx == sc->cur_chan) &&
@@ -1788,6 +1797,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1788 slottime = 9; 1797 slottime = 9;
1789 else 1798 else
1790 slottime = 20; 1799 slottime = 20;
1800
1791 if (vif->type == NL80211_IFTYPE_AP) { 1801 if (vif->type == NL80211_IFTYPE_AP) {
1792 /* 1802 /*
1793 * Defer update, so that connected stations can adjust 1803 * Defer update, so that connected stations can adjust
@@ -1823,11 +1833,19 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1823static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 1833static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1824{ 1834{
1825 struct ath_softc *sc = hw->priv; 1835 struct ath_softc *sc = hw->priv;
1836 struct ath_vif *avp = (void *)vif->drv_priv;
1826 u64 tsf; 1837 u64 tsf;
1827 1838
1828 mutex_lock(&sc->mutex); 1839 mutex_lock(&sc->mutex);
1829 ath9k_ps_wakeup(sc); 1840 ath9k_ps_wakeup(sc);
1830 tsf = ath9k_hw_gettsf64(sc->sc_ah); 1841 /* Get current TSF either from HW or kernel time. */
1842 if (sc->cur_chan == avp->chanctx) {
1843 tsf = ath9k_hw_gettsf64(sc->sc_ah);
1844 } else {
1845 tsf = sc->cur_chan->tsf_val +
1846 ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL);
1847 }
1848 tsf += le64_to_cpu(avp->tsf_adjust);
1831 ath9k_ps_restore(sc); 1849 ath9k_ps_restore(sc);
1832 mutex_unlock(&sc->mutex); 1850 mutex_unlock(&sc->mutex);
1833 1851
@@ -1839,10 +1857,15 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw,
1839 u64 tsf) 1857 u64 tsf)
1840{ 1858{
1841 struct ath_softc *sc = hw->priv; 1859 struct ath_softc *sc = hw->priv;
1860 struct ath_vif *avp = (void *)vif->drv_priv;
1842 1861
1843 mutex_lock(&sc->mutex); 1862 mutex_lock(&sc->mutex);
1844 ath9k_ps_wakeup(sc); 1863 ath9k_ps_wakeup(sc);
1845 ath9k_hw_settsf64(sc->sc_ah, tsf); 1864 tsf -= le64_to_cpu(avp->tsf_adjust);
1865 getrawmonotonic(&avp->chanctx->tsf_ts);
1866 if (sc->cur_chan == avp->chanctx)
1867 ath9k_hw_settsf64(sc->sc_ah, tsf);
1868 avp->chanctx->tsf_val = tsf;
1846 ath9k_ps_restore(sc); 1869 ath9k_ps_restore(sc);
1847 mutex_unlock(&sc->mutex); 1870 mutex_unlock(&sc->mutex);
1848} 1871}
@@ -1850,11 +1873,15 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw,
1850static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 1873static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1851{ 1874{
1852 struct ath_softc *sc = hw->priv; 1875 struct ath_softc *sc = hw->priv;
1876 struct ath_vif *avp = (void *)vif->drv_priv;
1853 1877
1854 mutex_lock(&sc->mutex); 1878 mutex_lock(&sc->mutex);
1855 1879
1856 ath9k_ps_wakeup(sc); 1880 ath9k_ps_wakeup(sc);
1857 ath9k_hw_reset_tsf(sc->sc_ah); 1881 getrawmonotonic(&avp->chanctx->tsf_ts);
1882 if (sc->cur_chan == avp->chanctx)
1883 ath9k_hw_reset_tsf(sc->sc_ah);
1884 avp->chanctx->tsf_val = 0;
1858 ath9k_ps_restore(sc); 1885 ath9k_ps_restore(sc);
1859 1886
1860 mutex_unlock(&sc->mutex); 1887 mutex_unlock(&sc->mutex);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 7cdaf40c3057..aa04b13bc5f2 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -794,6 +794,8 @@ static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
794 ath_err(common, 794 ath_err(common,
795 "%s: eeprom read failed, offset %08x is out of range\n", 795 "%s: eeprom read failed, offset %08x is out of range\n",
796 __func__, off); 796 __func__, off);
797
798 return false;
797 } 799 }
798 800
799 *data = pdata->eeprom_data[off]; 801 *data = pdata->eeprom_data[off];
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c
index 8643801f31b6..231fd022f0f5 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -35,26 +35,27 @@ void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low)
35 return ch->head_blk_ctl->bd_cpu_addr; 35 return ch->head_blk_ctl->bd_cpu_addr;
36} 36}
37 37
38static void wcn36xx_ccu_write_register(struct wcn36xx *wcn, int addr, int data)
39{
40 wcn36xx_dbg(WCN36XX_DBG_DXE,
41 "wcn36xx_ccu_write_register: addr=%x, data=%x\n",
42 addr, data);
43
44 writel(data, wcn->ccu_base + addr);
45}
46
38static void wcn36xx_dxe_write_register(struct wcn36xx *wcn, int addr, int data) 47static void wcn36xx_dxe_write_register(struct wcn36xx *wcn, int addr, int data)
39{ 48{
40 wcn36xx_dbg(WCN36XX_DBG_DXE, 49 wcn36xx_dbg(WCN36XX_DBG_DXE,
41 "wcn36xx_dxe_write_register: addr=%x, data=%x\n", 50 "wcn36xx_dxe_write_register: addr=%x, data=%x\n",
42 addr, data); 51 addr, data);
43 52
44 writel(data, wcn->mmio + addr); 53 writel(data, wcn->dxe_base + addr);
45} 54}
46 55
47#define wcn36xx_dxe_write_register_x(wcn, reg, reg_data) \
48do { \
49 if (wcn->chip_version == WCN36XX_CHIP_3680) \
50 wcn36xx_dxe_write_register(wcn, reg ## _3680, reg_data); \
51 else \
52 wcn36xx_dxe_write_register(wcn, reg ## _3660, reg_data); \
53} while (0) \
54
55static void wcn36xx_dxe_read_register(struct wcn36xx *wcn, int addr, int *data) 56static void wcn36xx_dxe_read_register(struct wcn36xx *wcn, int addr, int *data)
56{ 57{
57 *data = readl(wcn->mmio + addr); 58 *data = readl(wcn->dxe_base + addr);
58 59
59 wcn36xx_dbg(WCN36XX_DBG_DXE, 60 wcn36xx_dbg(WCN36XX_DBG_DXE,
60 "wcn36xx_dxe_read_register: addr=%x, data=%x\n", 61 "wcn36xx_dxe_read_register: addr=%x, data=%x\n",
@@ -701,9 +702,13 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
701 reg_data = WCN36XX_DXE_REG_RESET; 702 reg_data = WCN36XX_DXE_REG_RESET;
702 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CSR_RESET, reg_data); 703 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CSR_RESET, reg_data);
703 704
704 /* Setting interrupt path */ 705 /* Select channels for rx avail and xfer done interrupts... */
705 reg_data = WCN36XX_DXE_CCU_INT; 706 reg_data = (WCN36XX_DXE_INT_CH3_MASK | WCN36XX_DXE_INT_CH1_MASK) << 16 |
706 wcn36xx_dxe_write_register_x(wcn, WCN36XX_DXE_REG_CCU_INT, reg_data); 707 WCN36XX_DXE_INT_CH0_MASK | WCN36XX_DXE_INT_CH4_MASK;
708 if (wcn->is_pronto)
709 wcn36xx_ccu_write_register(wcn, WCN36XX_CCU_DXE_INT_SELECT_PRONTO, reg_data);
710 else
711 wcn36xx_ccu_write_register(wcn, WCN36XX_CCU_DXE_INT_SELECT_RIVA, reg_data);
707 712
708 /***************************************/ 713 /***************************************/
709 /* Init descriptors for TX LOW channel */ 714 /* Init descriptors for TX LOW channel */
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h b/drivers/net/wireless/ath/wcn36xx/dxe.h
index 3eca4f9594f2..c012e807753b 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.h
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.h
@@ -28,11 +28,10 @@ H2H_TEST_RX_TX = DMA2
28*/ 28*/
29 29
30/* DXE registers */ 30/* DXE registers */
31#define WCN36XX_DXE_MEM_REG 0x202000 31#define WCN36XX_DXE_MEM_REG 0
32 32
33#define WCN36XX_DXE_CCU_INT 0xA0011 33#define WCN36XX_CCU_DXE_INT_SELECT_RIVA 0x310
34#define WCN36XX_DXE_REG_CCU_INT_3660 0x200b10 34#define WCN36XX_CCU_DXE_INT_SELECT_PRONTO 0x10dc
35#define WCN36XX_DXE_REG_CCU_INT_3680 0x2050dc
36 35
37/* TODO This must calculated properly but not hardcoded */ 36/* TODO This must calculated properly but not hardcoded */
38#define WCN36XX_DXE_CTRL_TX_L 0x328a44 37#define WCN36XX_DXE_CTRL_TX_L 0x328a44
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h
index 658bfb8baabe..4f87ef1e1eb8 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -4123,7 +4123,7 @@ struct wcn36xx_hal_update_scan_params_req {
4123 4123
4124/* Update scan params - sent from host to PNO to be used during PNO 4124/* Update scan params - sent from host to PNO to be used during PNO
4125 * scanningx */ 4125 * scanningx */
4126struct update_scan_params_req_ex { 4126struct wcn36xx_hal_update_scan_params_req_ex {
4127 4127
4128 struct wcn36xx_hal_msg_header header; 4128 struct wcn36xx_hal_msg_header header;
4129 4129
@@ -4151,7 +4151,7 @@ struct update_scan_params_req_ex {
4151 4151
4152 /* Cb State */ 4152 /* Cb State */
4153 enum phy_chan_bond_state state; 4153 enum phy_chan_bond_state state;
4154}; 4154} __packed;
4155 4155
4156/* Update scan params - sent from host to PNO to be used during PNO 4156/* Update scan params - sent from host to PNO to be used during PNO
4157 * scanningx */ 4157 * scanningx */
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index a920d7020148..e1d59da2ad20 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -19,6 +19,8 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/firmware.h> 20#include <linux/firmware.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/of_address.h>
23#include <linux/of_device.h>
22#include "wcn36xx.h" 24#include "wcn36xx.h"
23 25
24unsigned int wcn36xx_dbg_mask; 26unsigned int wcn36xx_dbg_mask;
@@ -259,17 +261,6 @@ static void wcn36xx_feat_caps_info(struct wcn36xx *wcn)
259 } 261 }
260} 262}
261 263
262static void wcn36xx_detect_chip_version(struct wcn36xx *wcn)
263{
264 if (get_feat_caps(wcn->fw_feat_caps, DOT11AC)) {
265 wcn36xx_info("Chip is 3680\n");
266 wcn->chip_version = WCN36XX_CHIP_3680;
267 } else {
268 wcn36xx_info("Chip is 3660\n");
269 wcn->chip_version = WCN36XX_CHIP_3660;
270 }
271}
272
273static int wcn36xx_start(struct ieee80211_hw *hw) 264static int wcn36xx_start(struct ieee80211_hw *hw)
274{ 265{
275 struct wcn36xx *wcn = hw->priv; 266 struct wcn36xx *wcn = hw->priv;
@@ -324,9 +315,6 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
324 wcn36xx_feat_caps_info(wcn); 315 wcn36xx_feat_caps_info(wcn);
325 } 316 }
326 317
327 wcn36xx_detect_chip_version(wcn);
328 wcn36xx_smd_update_cfg(wcn, WCN36XX_HAL_CFG_ENABLE_MC_ADDR_LIST, 1);
329
330 /* DMA channel initialization */ 318 /* DMA channel initialization */
331 ret = wcn36xx_dxe_init(wcn); 319 ret = wcn36xx_dxe_init(wcn);
332 if (ret) { 320 if (ret) {
@@ -1064,7 +1052,11 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
1064static int wcn36xx_platform_get_resources(struct wcn36xx *wcn, 1052static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
1065 struct platform_device *pdev) 1053 struct platform_device *pdev)
1066{ 1054{
1055 struct device_node *mmio_node;
1067 struct resource *res; 1056 struct resource *res;
1057 int index;
1058 int ret;
1059
1068 /* Set TX IRQ */ 1060 /* Set TX IRQ */
1069 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, 1061 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
1070 "wcnss_wlantx_irq"); 1062 "wcnss_wlantx_irq");
@@ -1083,19 +1075,40 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
1083 } 1075 }
1084 wcn->rx_irq = res->start; 1076 wcn->rx_irq = res->start;
1085 1077
1086 /* Map the memory */ 1078 mmio_node = of_parse_phandle(pdev->dev.parent->of_node, "qcom,mmio", 0);
1087 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 1079 if (!mmio_node) {
1088 "wcnss_mmio"); 1080 wcn36xx_err("failed to acquire qcom,mmio reference\n");
1089 if (!res) { 1081 return -EINVAL;
1090 wcn36xx_err("failed to get mmio\n");
1091 return -ENOENT;
1092 } 1082 }
1093 wcn->mmio = ioremap(res->start, resource_size(res)); 1083
1094 if (!wcn->mmio) { 1084 wcn->is_pronto = !!of_device_is_compatible(mmio_node, "qcom,pronto");
1095 wcn36xx_err("failed to map io memory\n"); 1085
1096 return -ENOMEM; 1086 /* Map the CCU memory */
1087 index = of_property_match_string(mmio_node, "reg-names", "ccu");
1088 wcn->ccu_base = of_iomap(mmio_node, index);
1089 if (!wcn->ccu_base) {
1090 wcn36xx_err("failed to map ccu memory\n");
1091 ret = -ENOMEM;
1092 goto put_mmio_node;
1097 } 1093 }
1094
1095 /* Map the DXE memory */
1096 index = of_property_match_string(mmio_node, "reg-names", "dxe");
1097 wcn->dxe_base = of_iomap(mmio_node, index);
1098 if (!wcn->dxe_base) {
1099 wcn36xx_err("failed to map dxe memory\n");
1100 ret = -ENOMEM;
1101 goto unmap_ccu;
1102 }
1103
1104 of_node_put(mmio_node);
1098 return 0; 1105 return 0;
1106
1107unmap_ccu:
1108 iounmap(wcn->ccu_base);
1109put_mmio_node:
1110 of_node_put(mmio_node);
1111 return ret;
1099} 1112}
1100 1113
1101static int wcn36xx_probe(struct platform_device *pdev) 1114static int wcn36xx_probe(struct platform_device *pdev)
@@ -1138,7 +1151,8 @@ static int wcn36xx_probe(struct platform_device *pdev)
1138 return 0; 1151 return 0;
1139 1152
1140out_unmap: 1153out_unmap:
1141 iounmap(wcn->mmio); 1154 iounmap(wcn->ccu_base);
1155 iounmap(wcn->dxe_base);
1142out_wq: 1156out_wq:
1143 ieee80211_free_hw(hw); 1157 ieee80211_free_hw(hw);
1144out_err: 1158out_err:
@@ -1154,7 +1168,8 @@ static int wcn36xx_remove(struct platform_device *pdev)
1154 mutex_destroy(&wcn->hal_mutex); 1168 mutex_destroy(&wcn->hal_mutex);
1155 1169
1156 ieee80211_unregister_hw(hw); 1170 ieee80211_unregister_hw(hw);
1157 iounmap(wcn->mmio); 1171 iounmap(wcn->dxe_base);
1172 iounmap(wcn->ccu_base);
1158 ieee80211_free_hw(hw); 1173 ieee80211_free_hw(hw);
1159 1174
1160 return 0; 1175 return 0;
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index e8b630c4f11e..a443992320f2 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -674,22 +674,25 @@ static int wcn36xx_smd_update_scan_params_rsp(void *buf, size_t len)
674 return 0; 674 return 0;
675} 675}
676 676
677int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn) 677int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn,
678 u8 *channels, size_t channel_count)
678{ 679{
679 struct wcn36xx_hal_update_scan_params_req msg_body; 680 struct wcn36xx_hal_update_scan_params_req_ex msg_body;
680 int ret = 0; 681 int ret = 0;
681 682
682 mutex_lock(&wcn->hal_mutex); 683 mutex_lock(&wcn->hal_mutex);
683 INIT_HAL_MSG(msg_body, WCN36XX_HAL_UPDATE_SCAN_PARAM_REQ); 684 INIT_HAL_MSG(msg_body, WCN36XX_HAL_UPDATE_SCAN_PARAM_REQ);
684 685
685 msg_body.dot11d_enabled = 0; 686 msg_body.dot11d_enabled = false;
686 msg_body.dot11d_resolved = 0; 687 msg_body.dot11d_resolved = true;
687 msg_body.channel_count = 26; 688
689 msg_body.channel_count = channel_count;
690 memcpy(msg_body.channels, channels, channel_count);
688 msg_body.active_min_ch_time = 60; 691 msg_body.active_min_ch_time = 60;
689 msg_body.active_max_ch_time = 120; 692 msg_body.active_max_ch_time = 120;
690 msg_body.passive_min_ch_time = 60; 693 msg_body.passive_min_ch_time = 60;
691 msg_body.passive_max_ch_time = 110; 694 msg_body.passive_max_ch_time = 110;
692 msg_body.state = 0; 695 msg_body.state = PHY_SINGLE_CHANNEL_CENTERED;
693 696
694 PREPARE_HAL_BUF(wcn->hal_buf, msg_body); 697 PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
695 698
@@ -2226,17 +2229,12 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
2226 2229
2227 case WCN36XX_HAL_COEX_IND: 2230 case WCN36XX_HAL_COEX_IND:
2228 case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: 2231 case WCN36XX_HAL_AVOID_FREQ_RANGE_IND:
2232 case WCN36XX_HAL_DEL_BA_IND:
2229 case WCN36XX_HAL_OTA_TX_COMPL_IND: 2233 case WCN36XX_HAL_OTA_TX_COMPL_IND:
2230 case WCN36XX_HAL_MISSED_BEACON_IND: 2234 case WCN36XX_HAL_MISSED_BEACON_IND:
2231 case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: 2235 case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
2232 msg_ind = kmalloc(sizeof(*msg_ind), GFP_KERNEL); 2236 msg_ind = kmalloc(sizeof(*msg_ind) + len, GFP_KERNEL);
2233 if (!msg_ind) 2237 if (!msg_ind) {
2234 goto nomem;
2235 msg_ind->msg_len = len;
2236 msg_ind->msg = kmemdup(buf, len, GFP_KERNEL);
2237 if (!msg_ind->msg) {
2238 kfree(msg_ind);
2239nomem:
2240 /* 2238 /*
2241 * FIXME: Do something smarter then just 2239 * FIXME: Do something smarter then just
2242 * printing an error. 2240 * printing an error.
@@ -2245,10 +2243,14 @@ nomem:
2245 msg_header->msg_type); 2243 msg_header->msg_type);
2246 break; 2244 break;
2247 } 2245 }
2248 mutex_lock(&wcn->hal_ind_mutex); 2246
2247 msg_ind->msg_len = len;
2248 memcpy(msg_ind->msg, buf, len);
2249
2250 spin_lock(&wcn->hal_ind_lock);
2249 list_add_tail(&msg_ind->list, &wcn->hal_ind_queue); 2251 list_add_tail(&msg_ind->list, &wcn->hal_ind_queue);
2250 queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work); 2252 queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work);
2251 mutex_unlock(&wcn->hal_ind_mutex); 2253 spin_unlock(&wcn->hal_ind_lock);
2252 wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n"); 2254 wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n");
2253 break; 2255 break;
2254 default: 2256 default:
@@ -2262,8 +2264,9 @@ static void wcn36xx_ind_smd_work(struct work_struct *work)
2262 container_of(work, struct wcn36xx, hal_ind_work); 2264 container_of(work, struct wcn36xx, hal_ind_work);
2263 struct wcn36xx_hal_msg_header *msg_header; 2265 struct wcn36xx_hal_msg_header *msg_header;
2264 struct wcn36xx_hal_ind_msg *hal_ind_msg; 2266 struct wcn36xx_hal_ind_msg *hal_ind_msg;
2267 unsigned long flags;
2265 2268
2266 mutex_lock(&wcn->hal_ind_mutex); 2269 spin_lock_irqsave(&wcn->hal_ind_lock, flags);
2267 2270
2268 hal_ind_msg = list_first_entry(&wcn->hal_ind_queue, 2271 hal_ind_msg = list_first_entry(&wcn->hal_ind_queue,
2269 struct wcn36xx_hal_ind_msg, 2272 struct wcn36xx_hal_ind_msg,
@@ -2273,6 +2276,7 @@ static void wcn36xx_ind_smd_work(struct work_struct *work)
2273 2276
2274 switch (msg_header->msg_type) { 2277 switch (msg_header->msg_type) {
2275 case WCN36XX_HAL_COEX_IND: 2278 case WCN36XX_HAL_COEX_IND:
2279 case WCN36XX_HAL_DEL_BA_IND:
2276 case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: 2280 case WCN36XX_HAL_AVOID_FREQ_RANGE_IND:
2277 break; 2281 break;
2278 case WCN36XX_HAL_OTA_TX_COMPL_IND: 2282 case WCN36XX_HAL_OTA_TX_COMPL_IND:
@@ -2295,9 +2299,8 @@ static void wcn36xx_ind_smd_work(struct work_struct *work)
2295 msg_header->msg_type); 2299 msg_header->msg_type);
2296 } 2300 }
2297 list_del(wcn->hal_ind_queue.next); 2301 list_del(wcn->hal_ind_queue.next);
2298 kfree(hal_ind_msg->msg); 2302 spin_unlock_irqrestore(&wcn->hal_ind_lock, flags);
2299 kfree(hal_ind_msg); 2303 kfree(hal_ind_msg);
2300 mutex_unlock(&wcn->hal_ind_mutex);
2301} 2304}
2302int wcn36xx_smd_open(struct wcn36xx *wcn) 2305int wcn36xx_smd_open(struct wcn36xx *wcn)
2303{ 2306{
@@ -2310,7 +2313,7 @@ int wcn36xx_smd_open(struct wcn36xx *wcn)
2310 } 2313 }
2311 INIT_WORK(&wcn->hal_ind_work, wcn36xx_ind_smd_work); 2314 INIT_WORK(&wcn->hal_ind_work, wcn36xx_ind_smd_work);
2312 INIT_LIST_HEAD(&wcn->hal_ind_queue); 2315 INIT_LIST_HEAD(&wcn->hal_ind_queue);
2313 mutex_init(&wcn->hal_ind_mutex); 2316 spin_lock_init(&wcn->hal_ind_lock);
2314 2317
2315 ret = wcn->ctrl_ops->open(wcn, wcn36xx_smd_rsp_process); 2318 ret = wcn->ctrl_ops->open(wcn, wcn36xx_smd_rsp_process);
2316 if (ret) { 2319 if (ret) {
@@ -2330,5 +2333,4 @@ void wcn36xx_smd_close(struct wcn36xx *wcn)
2330{ 2333{
2331 wcn->ctrl_ops->close(); 2334 wcn->ctrl_ops->close();
2332 destroy_workqueue(wcn->hal_ind_wq); 2335 destroy_workqueue(wcn->hal_ind_wq);
2333 mutex_destroy(&wcn->hal_ind_mutex);
2334} 2336}
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index d93e3fd73831..df80cbbd9d1b 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -46,8 +46,8 @@ struct wcn36xx_fw_msg_status_rsp {
46 46
47struct wcn36xx_hal_ind_msg { 47struct wcn36xx_hal_ind_msg {
48 struct list_head list; 48 struct list_head list;
49 u8 *msg;
50 size_t msg_len; 49 size_t msg_len;
50 u8 msg[];
51}; 51};
52 52
53struct wcn36xx; 53struct wcn36xx;
@@ -63,7 +63,7 @@ int wcn36xx_smd_start_scan(struct wcn36xx *wcn);
63int wcn36xx_smd_end_scan(struct wcn36xx *wcn); 63int wcn36xx_smd_end_scan(struct wcn36xx *wcn);
64int wcn36xx_smd_finish_scan(struct wcn36xx *wcn, 64int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
65 enum wcn36xx_hal_sys_mode mode); 65 enum wcn36xx_hal_sys_mode mode);
66int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn); 66int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t channel_count);
67int wcn36xx_smd_add_sta_self(struct wcn36xx *wcn, struct ieee80211_vif *vif); 67int wcn36xx_smd_add_sta_self(struct wcn36xx *wcn, struct ieee80211_vif *vif);
68int wcn36xx_smd_delete_sta_self(struct wcn36xx *wcn, u8 *addr); 68int wcn36xx_smd_delete_sta_self(struct wcn36xx *wcn, u8 *addr);
69int wcn36xx_smd_delete_sta(struct wcn36xx *wcn, u8 sta_index); 69int wcn36xx_smd_delete_sta(struct wcn36xx *wcn, u8 sta_index);
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 7433d67a5929..22242d18e1fe 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -193,7 +193,7 @@ struct wcn36xx {
193 u8 fw_minor; 193 u8 fw_minor;
194 u8 fw_major; 194 u8 fw_major;
195 u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE]; 195 u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE];
196 u32 chip_version; 196 bool is_pronto;
197 197
198 /* extra byte for the NULL termination */ 198 /* extra byte for the NULL termination */
199 u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; 199 u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1];
@@ -202,7 +202,8 @@ struct wcn36xx {
202 /* IRQs */ 202 /* IRQs */
203 int tx_irq; 203 int tx_irq;
204 int rx_irq; 204 int rx_irq;
205 void __iomem *mmio; 205 void __iomem *ccu_base;
206 void __iomem *dxe_base;
206 207
207 struct wcn36xx_platform_ctrl_ops *ctrl_ops; 208 struct wcn36xx_platform_ctrl_ops *ctrl_ops;
208 /* 209 /*
@@ -215,7 +216,7 @@ struct wcn36xx {
215 struct completion hal_rsp_compl; 216 struct completion hal_rsp_compl;
216 struct workqueue_struct *hal_ind_wq; 217 struct workqueue_struct *hal_ind_wq;
217 struct work_struct hal_ind_work; 218 struct work_struct hal_ind_work;
218 struct mutex hal_ind_mutex; 219 spinlock_t hal_ind_lock;
219 struct list_head hal_ind_queue; 220 struct list_head hal_ind_queue;
220 221
221 /* DXE channels */ 222 /* DXE channels */
@@ -241,9 +242,6 @@ struct wcn36xx {
241 242
242}; 243};
243 244
244#define WCN36XX_CHIP_3660 0
245#define WCN36XX_CHIP_3680 1
246
247static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, 245static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn,
248 u8 major, 246 u8 major,
249 u8 minor, 247 u8 minor,
diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h
index e66153d60bd5..76860a461ed2 100644
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -40,6 +40,7 @@ struct ath9k_platform_data {
40 bool tx_gain_buffalo; 40 bool tx_gain_buffalo;
41 bool disable_2ghz; 41 bool disable_2ghz;
42 bool disable_5ghz; 42 bool disable_5ghz;
43 bool led_active_high;
43 44
44 int (*get_mac_revision)(void); 45 int (*get_mac_revision)(void);
45 int (*external_reset)(void); 46 int (*external_reset)(void);