aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 12:00:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 12:00:47 -0400
commit6c373ca89399c5a3f7ef210ad8f63dc3437da345 (patch)
tree74d1ec65087df1da1021b43ac51acc1ee8601809 /drivers/net/wireless/ath/ath10k
parentbb0fd7ab0986105765d11baa82e619c618a235aa (diff)
parent9f9151412dd7aae0e3f51a89ae4a1f8755fdb4d0 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) Add BQL support to via-rhine, from Tino Reichardt. 2) Integrate SWITCHDEV layer support into the DSA layer, so DSA drivers can support hw switch offloading. From Floria Fainelli. 3) Allow 'ip address' commands to initiate multicast group join/leave, from Madhu Challa. 4) Many ipv4 FIB lookup optimizations from Alexander Duyck. 5) Support EBPF in cls_bpf classifier and act_bpf action, from Daniel Borkmann. 6) Remove the ugly compat support in ARP for ugly layers like ax25, rose, etc. And use this to clean up the neigh layer, then use it to implement MPLS support. All from Eric Biederman. 7) Support L3 forwarding offloading in switches, from Scott Feldman. 8) Collapse the LOCAL and MAIN ipv4 FIB tables when possible, to speed up route lookups even further. From Alexander Duyck. 9) Many improvements and bug fixes to the rhashtable implementation, from Herbert Xu and Thomas Graf. In particular, in the case where an rhashtable user bulk adds a large number of items into an empty table, we expand the table much more sanely. 10) Don't make the tcp_metrics hash table per-namespace, from Eric Biederman. 11) Extend EBPF to access SKB fields, from Alexei Starovoitov. 12) Split out new connection request sockets so that they can be established in the main hash table. Much less false sharing since hash lookups go direct to the request sockets instead of having to go first to the listener then to the request socks hashed underneath. From Eric Dumazet. 13) Add async I/O support for crytpo AF_ALG sockets, from Tadeusz Struk. 14) Support stable privacy address generation for RFC7217 in IPV6. From Hannes Frederic Sowa. 15) Hash network namespace into IP frag IDs, also from Hannes Frederic Sowa. 16) Convert PTP get/set methods to use 64-bit time, from Richard Cochran. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1816 commits) fm10k: Bump driver version to 0.15.2 fm10k: corrected VF multicast update fm10k: mbx_update_max_size does not drop all oversized messages fm10k: reset head instead of calling update_max_size fm10k: renamed mbx_tx_dropped to mbx_tx_oversized fm10k: update xcast mode before synchronizing multicast addresses fm10k: start service timer on probe fm10k: fix function header comment fm10k: comment next_vf_mbx flow fm10k: don't handle mailbox events in iov_event path and always process mailbox fm10k: use separate workqueue for fm10k driver fm10k: Set PF queues to unlimited bandwidth during virtualization fm10k: expose tx_timeout_count as an ethtool stat fm10k: only increment tx_timeout_count in Tx hang path fm10k: remove extraneous "Reset interface" message fm10k: separate PF only stats so that VF does not display them fm10k: use hw->mac.max_queues for stats fm10k: only show actual queues, not the maximum in hardware fm10k: allow creation of VLAN on default vid fm10k: fix unused warnings ...
Diffstat (limited to 'drivers/net/wireless/ath/ath10k')
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c8
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h27
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c101
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c169
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h7
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c132
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h15
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c27
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h18
12 files changed, 465 insertions, 47 deletions
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h
index c18647b87f71..0eddb204d85b 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -39,7 +39,7 @@ struct ath10k_ce_pipe;
39#define CE_DESC_FLAGS_GATHER (1 << 0) 39#define CE_DESC_FLAGS_GATHER (1 << 0)
40#define CE_DESC_FLAGS_BYTE_SWAP (1 << 1) 40#define CE_DESC_FLAGS_BYTE_SWAP (1 << 1)
41#define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC 41#define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC
42#define CE_DESC_FLAGS_META_DATA_LSB 3 42#define CE_DESC_FLAGS_META_DATA_LSB 2
43 43
44struct ce_desc { 44struct ce_desc {
45 __le32 addr; 45 __le32 addr;
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 310e12bc078a..c0e454bb6a8d 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -436,16 +436,16 @@ static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode)
436 436
437static void ath10k_core_free_firmware_files(struct ath10k *ar) 437static void ath10k_core_free_firmware_files(struct ath10k *ar)
438{ 438{
439 if (ar->board && !IS_ERR(ar->board)) 439 if (!IS_ERR(ar->board))
440 release_firmware(ar->board); 440 release_firmware(ar->board);
441 441
442 if (ar->otp && !IS_ERR(ar->otp)) 442 if (!IS_ERR(ar->otp))
443 release_firmware(ar->otp); 443 release_firmware(ar->otp);
444 444
445 if (ar->firmware && !IS_ERR(ar->firmware)) 445 if (!IS_ERR(ar->firmware))
446 release_firmware(ar->firmware); 446 release_firmware(ar->firmware);
447 447
448 if (ar->cal_file && !IS_ERR(ar->cal_file)) 448 if (!IS_ERR(ar->cal_file))
449 release_firmware(ar->cal_file); 449 release_firmware(ar->cal_file);
450 450
451 ar->board = NULL; 451 ar->board = NULL;
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index d60e46fe6d19..f65310c3ba5f 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -159,6 +159,25 @@ struct ath10k_fw_stats_peer {
159 u32 peer_rx_rate; /* 10x only */ 159 u32 peer_rx_rate; /* 10x only */
160}; 160};
161 161
162struct ath10k_fw_stats_vdev {
163 struct list_head list;
164
165 u32 vdev_id;
166 u32 beacon_snr;
167 u32 data_snr;
168 u32 num_tx_frames[4];
169 u32 num_rx_frames;
170 u32 num_tx_frames_retries[4];
171 u32 num_tx_frames_failures[4];
172 u32 num_rts_fail;
173 u32 num_rts_success;
174 u32 num_rx_err;
175 u32 num_rx_discard;
176 u32 num_tx_not_acked;
177 u32 tx_rate_history[10];
178 u32 beacon_rssi_history[10];
179};
180
162struct ath10k_fw_stats_pdev { 181struct ath10k_fw_stats_pdev {
163 struct list_head list; 182 struct list_head list;
164 183
@@ -220,6 +239,7 @@ struct ath10k_fw_stats_pdev {
220 239
221struct ath10k_fw_stats { 240struct ath10k_fw_stats {
222 struct list_head pdevs; 241 struct list_head pdevs;
242 struct list_head vdevs;
223 struct list_head peers; 243 struct list_head peers;
224}; 244};
225 245
@@ -288,6 +308,7 @@ struct ath10k_vif {
288 bool is_started; 308 bool is_started;
289 bool is_up; 309 bool is_up;
290 bool spectral_enabled; 310 bool spectral_enabled;
311 bool ps;
291 u32 aid; 312 u32 aid;
292 u8 bssid[ETH_ALEN]; 313 u8 bssid[ETH_ALEN];
293 314
@@ -413,6 +434,12 @@ enum ath10k_fw_features {
413 */ 434 */
414 ATH10K_FW_FEATURE_WMI_10_2 = 4, 435 ATH10K_FW_FEATURE_WMI_10_2 = 4,
415 436
437 /* Some firmware revisions lack proper multi-interface client powersave
438 * implementation. Enabling PS could result in connection drops,
439 * traffic stalls, etc.
440 */
441 ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT = 5,
442
416 /* keep last */ 443 /* keep last */
417 ATH10K_FW_FEATURE_COUNT, 444 ATH10K_FW_FEATURE_COUNT,
418}; 445};
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index d2281e5c2ffe..301081db1ef6 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -243,6 +243,16 @@ static void ath10k_debug_fw_stats_pdevs_free(struct list_head *head)
243 } 243 }
244} 244}
245 245
246static void ath10k_debug_fw_stats_vdevs_free(struct list_head *head)
247{
248 struct ath10k_fw_stats_vdev *i, *tmp;
249
250 list_for_each_entry_safe(i, tmp, head, list) {
251 list_del(&i->list);
252 kfree(i);
253 }
254}
255
246static void ath10k_debug_fw_stats_peers_free(struct list_head *head) 256static void ath10k_debug_fw_stats_peers_free(struct list_head *head)
247{ 257{
248 struct ath10k_fw_stats_peer *i, *tmp; 258 struct ath10k_fw_stats_peer *i, *tmp;
@@ -258,6 +268,7 @@ static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
258 spin_lock_bh(&ar->data_lock); 268 spin_lock_bh(&ar->data_lock);
259 ar->debug.fw_stats_done = false; 269 ar->debug.fw_stats_done = false;
260 ath10k_debug_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); 270 ath10k_debug_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
271 ath10k_debug_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
261 ath10k_debug_fw_stats_peers_free(&ar->debug.fw_stats.peers); 272 ath10k_debug_fw_stats_peers_free(&ar->debug.fw_stats.peers);
262 spin_unlock_bh(&ar->data_lock); 273 spin_unlock_bh(&ar->data_lock);
263} 274}
@@ -273,14 +284,27 @@ static size_t ath10k_debug_fw_stats_num_peers(struct list_head *head)
273 return num; 284 return num;
274} 285}
275 286
287static size_t ath10k_debug_fw_stats_num_vdevs(struct list_head *head)
288{
289 struct ath10k_fw_stats_vdev *i;
290 size_t num = 0;
291
292 list_for_each_entry(i, head, list)
293 ++num;
294
295 return num;
296}
297
276void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) 298void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
277{ 299{
278 struct ath10k_fw_stats stats = {}; 300 struct ath10k_fw_stats stats = {};
279 bool is_start, is_started, is_end; 301 bool is_start, is_started, is_end;
280 size_t num_peers; 302 size_t num_peers;
303 size_t num_vdevs;
281 int ret; 304 int ret;
282 305
283 INIT_LIST_HEAD(&stats.pdevs); 306 INIT_LIST_HEAD(&stats.pdevs);
307 INIT_LIST_HEAD(&stats.vdevs);
284 INIT_LIST_HEAD(&stats.peers); 308 INIT_LIST_HEAD(&stats.peers);
285 309
286 spin_lock_bh(&ar->data_lock); 310 spin_lock_bh(&ar->data_lock);
@@ -308,6 +332,7 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
308 } 332 }
309 333
310 num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers); 334 num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers);
335 num_vdevs = ath10k_debug_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
311 is_start = (list_empty(&ar->debug.fw_stats.pdevs) && 336 is_start = (list_empty(&ar->debug.fw_stats.pdevs) &&
312 !list_empty(&stats.pdevs)); 337 !list_empty(&stats.pdevs));
313 is_end = (!list_empty(&ar->debug.fw_stats.pdevs) && 338 is_end = (!list_empty(&ar->debug.fw_stats.pdevs) &&
@@ -330,7 +355,13 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
330 goto free; 355 goto free;
331 } 356 }
332 357
358 if (num_vdevs >= BITS_PER_LONG) {
359 ath10k_warn(ar, "dropping fw vdev stats\n");
360 goto free;
361 }
362
333 list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers); 363 list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers);
364 list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs);
334 } 365 }
335 366
336 complete(&ar->debug.fw_stats_complete); 367 complete(&ar->debug.fw_stats_complete);
@@ -340,6 +371,7 @@ free:
340 * resources if that is not the case. 371 * resources if that is not the case.
341 */ 372 */
342 ath10k_debug_fw_stats_pdevs_free(&stats.pdevs); 373 ath10k_debug_fw_stats_pdevs_free(&stats.pdevs);
374 ath10k_debug_fw_stats_vdevs_free(&stats.vdevs);
343 ath10k_debug_fw_stats_peers_free(&stats.peers); 375 ath10k_debug_fw_stats_peers_free(&stats.peers);
344 376
345unlock: 377unlock:
@@ -363,7 +395,10 @@ static int ath10k_debug_fw_stats_request(struct ath10k *ar)
363 395
364 reinit_completion(&ar->debug.fw_stats_complete); 396 reinit_completion(&ar->debug.fw_stats_complete);
365 397
366 ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); 398 ret = ath10k_wmi_request_stats(ar,
399 WMI_STAT_PDEV |
400 WMI_STAT_VDEV |
401 WMI_STAT_PEER);
367 if (ret) { 402 if (ret) {
368 ath10k_warn(ar, "could not request stats (%d)\n", ret); 403 ath10k_warn(ar, "could not request stats (%d)\n", ret);
369 return ret; 404 return ret;
@@ -395,8 +430,11 @@ static void ath10k_fw_stats_fill(struct ath10k *ar,
395 unsigned int len = 0; 430 unsigned int len = 0;
396 unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE; 431 unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE;
397 const struct ath10k_fw_stats_pdev *pdev; 432 const struct ath10k_fw_stats_pdev *pdev;
433 const struct ath10k_fw_stats_vdev *vdev;
398 const struct ath10k_fw_stats_peer *peer; 434 const struct ath10k_fw_stats_peer *peer;
399 size_t num_peers; 435 size_t num_peers;
436 size_t num_vdevs;
437 int i;
400 438
401 spin_lock_bh(&ar->data_lock); 439 spin_lock_bh(&ar->data_lock);
402 440
@@ -408,6 +446,7 @@ static void ath10k_fw_stats_fill(struct ath10k *ar,
408 } 446 }
409 447
410 num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers); 448 num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers);
449 num_vdevs = ath10k_debug_fw_stats_num_vdevs(&fw_stats->vdevs);
411 450
412 len += scnprintf(buf + len, buf_len - len, "\n"); 451 len += scnprintf(buf + len, buf_len - len, "\n");
413 len += scnprintf(buf + len, buf_len - len, "%30s\n", 452 len += scnprintf(buf + len, buf_len - len, "%30s\n",
@@ -531,6 +570,65 @@ static void ath10k_fw_stats_fill(struct ath10k *ar,
531 570
532 len += scnprintf(buf + len, buf_len - len, "\n"); 571 len += scnprintf(buf + len, buf_len - len, "\n");
533 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n", 572 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
573 "ath10k VDEV stats", num_vdevs);
574 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
575 "=================");
576
577 list_for_each_entry(vdev, &fw_stats->vdevs, list) {
578 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
579 "vdev id", vdev->vdev_id);
580 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
581 "beacon snr", vdev->beacon_snr);
582 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
583 "data snr", vdev->data_snr);
584 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
585 "num rx frames", vdev->num_rx_frames);
586 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
587 "num rts fail", vdev->num_rts_fail);
588 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
589 "num rts success", vdev->num_rts_success);
590 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
591 "num rx err", vdev->num_rx_err);
592 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
593 "num rx discard", vdev->num_rx_discard);
594 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
595 "num tx not acked", vdev->num_tx_not_acked);
596
597 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++)
598 len += scnprintf(buf + len, buf_len - len,
599 "%25s [%02d] %u\n",
600 "num tx frames", i,
601 vdev->num_tx_frames[i]);
602
603 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++)
604 len += scnprintf(buf + len, buf_len - len,
605 "%25s [%02d] %u\n",
606 "num tx frames retries", i,
607 vdev->num_tx_frames_retries[i]);
608
609 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++)
610 len += scnprintf(buf + len, buf_len - len,
611 "%25s [%02d] %u\n",
612 "num tx frames failures", i,
613 vdev->num_tx_frames_failures[i]);
614
615 for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++)
616 len += scnprintf(buf + len, buf_len - len,
617 "%25s [%02d] 0x%08x\n",
618 "tx rate history", i,
619 vdev->tx_rate_history[i]);
620
621 for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++)
622 len += scnprintf(buf + len, buf_len - len,
623 "%25s [%02d] %u\n",
624 "beacon rssi history", i,
625 vdev->beacon_rssi_history[i]);
626
627 len += scnprintf(buf + len, buf_len - len, "\n");
628 }
629
630 len += scnprintf(buf + len, buf_len - len, "\n");
631 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
534 "ath10k PEER stats", num_peers); 632 "ath10k PEER stats", num_peers);
535 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 633 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
536 "================="); 634 "=================");
@@ -1900,6 +1998,7 @@ int ath10k_debug_create(struct ath10k *ar)
1900 return -ENOMEM; 1998 return -ENOMEM;
1901 1999
1902 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); 2000 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
2001 INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
1903 INIT_LIST_HEAD(&ar->debug.fw_stats.peers); 2002 INIT_LIST_HEAD(&ar->debug.fw_stats.peers);
1904 2003
1905 return 0; 2004 return 0;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index c1da44f65a4d..01a2b384f358 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -176,7 +176,7 @@ static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt)
176 * automatically balances load wrt to CPU power. 176 * automatically balances load wrt to CPU power.
177 * 177 *
178 * This probably comes at a cost of lower maximum throughput but 178 * This probably comes at a cost of lower maximum throughput but
179 * improves the avarage and stability. */ 179 * improves the average and stability. */
180 spin_lock_bh(&htt->rx_ring.lock); 180 spin_lock_bh(&htt->rx_ring.lock);
181 num_deficit = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt; 181 num_deficit = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt;
182 num_to_fill = min(ATH10K_HTT_MAX_NUM_REFILL, num_deficit); 182 num_to_fill = min(ATH10K_HTT_MAX_NUM_REFILL, num_deficit);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 4ce433f1c1fb..973485bd4121 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -611,7 +611,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
611 611
612 ret = ath10k_vdev_setup_sync(ar); 612 ret = ath10k_vdev_setup_sync(ar);
613 if (ret) { 613 if (ret) {
614 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i: %d\n", 614 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
615 vdev_id, ret); 615 vdev_id, ret);
616 return ret; 616 return ret;
617 } 617 }
@@ -658,7 +658,7 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar)
658 658
659 ret = ath10k_vdev_setup_sync(ar); 659 ret = ath10k_vdev_setup_sync(ar);
660 if (ret) 660 if (ret)
661 ath10k_warn(ar, "failed to synchronise monitor vdev %i: %d\n", 661 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
662 ar->monitor_vdev_id, ret); 662 ar->monitor_vdev_id, ret);
663 663
664 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n", 664 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
@@ -927,8 +927,9 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, bool restart)
927 927
928 ret = ath10k_vdev_setup_sync(ar); 928 ret = ath10k_vdev_setup_sync(ar);
929 if (ret) { 929 if (ret) {
930 ath10k_warn(ar, "failed to synchronise setup for vdev %i: %d\n", 930 ath10k_warn(ar,
931 arg.vdev_id, ret); 931 "failed to synchronize setup for vdev %i restart %d: %d\n",
932 arg.vdev_id, restart, ret);
932 return ret; 933 return ret;
933 } 934 }
934 935
@@ -966,7 +967,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
966 967
967 ret = ath10k_vdev_setup_sync(ar); 968 ret = ath10k_vdev_setup_sync(ar);
968 if (ret) { 969 if (ret) {
969 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n", 970 ath10k_warn(ar, "failed to synchronize setup for vdev %i stop: %d\n",
970 arvif->vdev_id, ret); 971 arvif->vdev_id, ret);
971 return ret; 972 return ret;
972 } 973 }
@@ -1182,7 +1183,7 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
1182 if (is_zero_ether_addr(arvif->bssid)) 1183 if (is_zero_ether_addr(arvif->bssid))
1183 return; 1184 return;
1184 1185
1185 memset(arvif->bssid, 0, ETH_ALEN); 1186 eth_zero_addr(arvif->bssid);
1186 1187
1187 return; 1188 return;
1188 } 1189 }
@@ -1253,6 +1254,20 @@ static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1253 return 0; 1254 return 0;
1254} 1255}
1255 1256
1257static int ath10k_mac_ps_vif_count(struct ath10k *ar)
1258{
1259 struct ath10k_vif *arvif;
1260 int num = 0;
1261
1262 lockdep_assert_held(&ar->conf_mutex);
1263
1264 list_for_each_entry(arvif, &ar->arvifs, list)
1265 if (arvif->ps)
1266 num++;
1267
1268 return num;
1269}
1270
1256static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) 1271static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
1257{ 1272{
1258 struct ath10k *ar = arvif->ar; 1273 struct ath10k *ar = arvif->ar;
@@ -1262,13 +1277,24 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
1262 enum wmi_sta_ps_mode psmode; 1277 enum wmi_sta_ps_mode psmode;
1263 int ret; 1278 int ret;
1264 int ps_timeout; 1279 int ps_timeout;
1280 bool enable_ps;
1265 1281
1266 lockdep_assert_held(&arvif->ar->conf_mutex); 1282 lockdep_assert_held(&arvif->ar->conf_mutex);
1267 1283
1268 if (arvif->vif->type != NL80211_IFTYPE_STATION) 1284 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1269 return 0; 1285 return 0;
1270 1286
1271 if (vif->bss_conf.ps) { 1287 enable_ps = arvif->ps;
1288
1289 if (enable_ps && ath10k_mac_ps_vif_count(ar) > 1 &&
1290 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
1291 ar->fw_features)) {
1292 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1293 arvif->vdev_id);
1294 enable_ps = false;
1295 }
1296
1297 if (enable_ps) {
1272 psmode = WMI_STA_PS_MODE_ENABLED; 1298 psmode = WMI_STA_PS_MODE_ENABLED;
1273 param = WMI_STA_PS_PARAM_INACTIVITY_TIME; 1299 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1274 1300
@@ -1386,7 +1412,8 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
1386 lockdep_assert_held(&ar->conf_mutex); 1412 lockdep_assert_held(&ar->conf_mutex);
1387 1413
1388 bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan, 1414 bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan,
1389 info->bssid, NULL, 0, 0, 0); 1415 info->bssid, NULL, 0, IEEE80211_BSS_TYPE_ANY,
1416 IEEE80211_PRIVACY_ANY);
1390 if (bss) { 1417 if (bss) {
1391 const struct cfg80211_bss_ies *ies; 1418 const struct cfg80211_bss_ies *ies;
1392 1419
@@ -1781,6 +1808,68 @@ static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
1781 ath10k_smps_map[smps]); 1808 ath10k_smps_map[smps]);
1782} 1809}
1783 1810
1811static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
1812 struct ieee80211_vif *vif,
1813 struct ieee80211_sta_vht_cap vht_cap)
1814{
1815 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1816 int ret;
1817 u32 param;
1818 u32 value;
1819
1820 if (!(ar->vht_cap_info &
1821 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
1822 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
1823 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
1824 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
1825 return 0;
1826
1827 param = ar->wmi.vdev_param->txbf;
1828 value = 0;
1829
1830 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
1831 return 0;
1832
1833 /* The following logic is correct. If a remote STA advertises support
1834 * for being a beamformer then we should enable us being a beamformee.
1835 */
1836
1837 if (ar->vht_cap_info &
1838 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
1839 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
1840 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
1841 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
1842
1843 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
1844 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
1845 }
1846
1847 if (ar->vht_cap_info &
1848 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
1849 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
1850 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
1851 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
1852
1853 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
1854 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
1855 }
1856
1857 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
1858 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
1859
1860 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
1861 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
1862
1863 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
1864 if (ret) {
1865 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
1866 value, ret);
1867 return ret;
1868 }
1869
1870 return 0;
1871}
1872
1784/* can be called only in mac80211 callbacks due to `key_count` usage */ 1873/* can be called only in mac80211 callbacks due to `key_count` usage */
1785static void ath10k_bss_assoc(struct ieee80211_hw *hw, 1874static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1786 struct ieee80211_vif *vif, 1875 struct ieee80211_vif *vif,
@@ -1789,6 +1878,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1789 struct ath10k *ar = hw->priv; 1878 struct ath10k *ar = hw->priv;
1790 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 1879 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1791 struct ieee80211_sta_ht_cap ht_cap; 1880 struct ieee80211_sta_ht_cap ht_cap;
1881 struct ieee80211_sta_vht_cap vht_cap;
1792 struct wmi_peer_assoc_complete_arg peer_arg; 1882 struct wmi_peer_assoc_complete_arg peer_arg;
1793 struct ieee80211_sta *ap_sta; 1883 struct ieee80211_sta *ap_sta;
1794 int ret; 1884 int ret;
@@ -1811,6 +1901,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1811 /* ap_sta must be accessed only within rcu section which must be left 1901 /* ap_sta must be accessed only within rcu section which must be left
1812 * before calling ath10k_setup_peer_smps() which might sleep. */ 1902 * before calling ath10k_setup_peer_smps() which might sleep. */
1813 ht_cap = ap_sta->ht_cap; 1903 ht_cap = ap_sta->ht_cap;
1904 vht_cap = ap_sta->vht_cap;
1814 1905
1815 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg); 1906 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
1816 if (ret) { 1907 if (ret) {
@@ -1836,6 +1927,13 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1836 return; 1927 return;
1837 } 1928 }
1838 1929
1930 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
1931 if (ret) {
1932 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
1933 arvif->vdev_id, bss_conf->bssid, ret);
1934 return;
1935 }
1936
1839 ath10k_dbg(ar, ATH10K_DBG_MAC, 1937 ath10k_dbg(ar, ATH10K_DBG_MAC,
1840 "mac vdev %d up (associated) bssid %pM aid %d\n", 1938 "mac vdev %d up (associated) bssid %pM aid %d\n",
1841 arvif->vdev_id, bss_conf->bssid, bss_conf->aid); 1939 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
@@ -1853,6 +1951,18 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1853 } 1951 }
1854 1952
1855 arvif->is_up = true; 1953 arvif->is_up = true;
1954
1955 /* Workaround: Some firmware revisions (tested with qca6174
1956 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
1957 * poked with peer param command.
1958 */
1959 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
1960 WMI_PEER_DUMMY_VAR, 1);
1961 if (ret) {
1962 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
1963 arvif->bssid, arvif->vdev_id, ret);
1964 return;
1965 }
1856} 1966}
1857 1967
1858static void ath10k_bss_disassoc(struct ieee80211_hw *hw, 1968static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
@@ -1860,6 +1970,7 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
1860{ 1970{
1861 struct ath10k *ar = hw->priv; 1971 struct ath10k *ar = hw->priv;
1862 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 1972 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1973 struct ieee80211_sta_vht_cap vht_cap = {};
1863 int ret; 1974 int ret;
1864 1975
1865 lockdep_assert_held(&ar->conf_mutex); 1976 lockdep_assert_held(&ar->conf_mutex);
@@ -1874,6 +1985,13 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
1874 1985
1875 arvif->def_wep_key_idx = -1; 1986 arvif->def_wep_key_idx = -1;
1876 1987
1988 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
1989 if (ret) {
1990 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
1991 arvif->vdev_id, ret);
1992 return;
1993 }
1994
1877 arvif->is_up = false; 1995 arvif->is_up = false;
1878} 1996}
1879 1997
@@ -2554,6 +2672,17 @@ static int ath10k_start_scan(struct ath10k *ar,
2554 return -ETIMEDOUT; 2672 return -ETIMEDOUT;
2555 } 2673 }
2556 2674
2675 /* If we failed to start the scan, return error code at
2676 * this point. This is probably due to some issue in the
2677 * firmware, but no need to wedge the driver due to that...
2678 */
2679 spin_lock_bh(&ar->data_lock);
2680 if (ar->scan.state == ATH10K_SCAN_IDLE) {
2681 spin_unlock_bh(&ar->data_lock);
2682 return -EINVAL;
2683 }
2684 spin_unlock_bh(&ar->data_lock);
2685
2557 /* Add a 200ms margin to account for event/command processing */ 2686 /* Add a 200ms margin to account for event/command processing */
2558 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout, 2687 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
2559 msecs_to_jiffies(arg->max_scan_time+200)); 2688 msecs_to_jiffies(arg->max_scan_time+200));
@@ -3323,9 +3452,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
3323 list_del(&arvif->list); 3452 list_del(&arvif->list);
3324 3453
3325 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { 3454 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
3326 ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, vif->addr); 3455 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
3456 vif->addr);
3327 if (ret) 3457 if (ret)
3328 ath10k_warn(ar, "failed to remove peer for AP vdev %i: %d\n", 3458 ath10k_warn(ar, "failed to submit AP self-peer removal on vdev %i: %d\n",
3329 arvif->vdev_id, ret); 3459 arvif->vdev_id, ret);
3330 3460
3331 kfree(arvif->u.ap.noa_data); 3461 kfree(arvif->u.ap.noa_data);
@@ -3339,6 +3469,21 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
3339 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n", 3469 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
3340 arvif->vdev_id, ret); 3470 arvif->vdev_id, ret);
3341 3471
3472 /* Some firmware revisions don't notify host about self-peer removal
3473 * until after associated vdev is deleted.
3474 */
3475 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
3476 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
3477 vif->addr);
3478 if (ret)
3479 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
3480 arvif->vdev_id, ret);
3481
3482 spin_lock_bh(&ar->data_lock);
3483 ar->num_peers--;
3484 spin_unlock_bh(&ar->data_lock);
3485 }
3486
3342 ath10k_peer_cleanup(ar, arvif->vdev_id); 3487 ath10k_peer_cleanup(ar, arvif->vdev_id);
3343 3488
3344 mutex_unlock(&ar->conf_mutex); 3489 mutex_unlock(&ar->conf_mutex);
@@ -3534,7 +3679,9 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
3534 } 3679 }
3535 3680
3536 if (changed & BSS_CHANGED_PS) { 3681 if (changed & BSS_CHANGED_PS) {
3537 ret = ath10k_mac_vif_setup_ps(arvif); 3682 arvif->ps = vif->bss_conf.ps;
3683
3684 ret = ath10k_config_ps(ar);
3538 if (ret) 3685 if (ret)
3539 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n", 3686 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
3540 arvif->vdev_id, ret); 3687 arvif->vdev_id, ret);
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index e6972b09333e..7681237fe298 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -104,7 +104,7 @@ static const struct ce_attr host_ce_config_wlan[] = {
104 { 104 {
105 .flags = CE_ATTR_FLAGS, 105 .flags = CE_ATTR_FLAGS,
106 .src_nentries = 0, 106 .src_nentries = 0,
107 .src_sz_max = 512, 107 .src_sz_max = 2048,
108 .dest_nentries = 512, 108 .dest_nentries = 512,
109 }, 109 },
110 110
@@ -174,7 +174,7 @@ static const struct ce_pipe_config target_ce_config_wlan[] = {
174 .pipenum = __cpu_to_le32(1), 174 .pipenum = __cpu_to_le32(1),
175 .pipedir = __cpu_to_le32(PIPEDIR_IN), 175 .pipedir = __cpu_to_le32(PIPEDIR_IN),
176 .nentries = __cpu_to_le32(32), 176 .nentries = __cpu_to_le32(32),
177 .nbytes_max = __cpu_to_le32(512), 177 .nbytes_max = __cpu_to_le32(2048),
178 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 178 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
179 .reserved = __cpu_to_le32(0), 179 .reserved = __cpu_to_le32(0),
180 }, 180 },
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 04dc4b9db04e..c8b64e7a6089 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -110,8 +110,7 @@ struct wmi_ops {
110 bool deliver_cab); 110 bool deliver_cab);
111 struct sk_buff *(*gen_pdev_set_wmm)(struct ath10k *ar, 111 struct sk_buff *(*gen_pdev_set_wmm)(struct ath10k *ar,
112 const struct wmi_wmm_params_all_arg *arg); 112 const struct wmi_wmm_params_all_arg *arg);
113 struct sk_buff *(*gen_request_stats)(struct ath10k *ar, 113 struct sk_buff *(*gen_request_stats)(struct ath10k *ar, u32 stats_mask);
114 enum wmi_stats_id stats_id);
115 struct sk_buff *(*gen_force_fw_hang)(struct ath10k *ar, 114 struct sk_buff *(*gen_force_fw_hang)(struct ath10k *ar,
116 enum wmi_force_fw_hang_type type, 115 enum wmi_force_fw_hang_type type,
117 u32 delay_ms); 116 u32 delay_ms);
@@ -816,14 +815,14 @@ ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
816} 815}
817 816
818static inline int 817static inline int
819ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) 818ath10k_wmi_request_stats(struct ath10k *ar, u32 stats_mask)
820{ 819{
821 struct sk_buff *skb; 820 struct sk_buff *skb;
822 821
823 if (!ar->wmi.ops->gen_request_stats) 822 if (!ar->wmi.ops->gen_request_stats)
824 return -EOPNOTSUPP; 823 return -EOPNOTSUPP;
825 824
826 skb = ar->wmi.ops->gen_request_stats(ar, stats_id); 825 skb = ar->wmi.ops->gen_request_stats(ar, stats_mask);
827 if (IS_ERR(skb)) 826 if (IS_ERR(skb))
828 return PTR_ERR(skb); 827 return PTR_ERR(skb);
829 828
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 71614ba1b145..ee0c5f602e29 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -869,16 +869,57 @@ static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar,
869 return 0; 869 return 0;
870} 870}
871 871
872static void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src,
873 struct ath10k_fw_stats_vdev *dst)
874{
875 int i;
876
877 dst->vdev_id = __le32_to_cpu(src->vdev_id);
878 dst->beacon_snr = __le32_to_cpu(src->beacon_snr);
879 dst->data_snr = __le32_to_cpu(src->data_snr);
880 dst->num_rx_frames = __le32_to_cpu(src->num_rx_frames);
881 dst->num_rts_fail = __le32_to_cpu(src->num_rts_fail);
882 dst->num_rts_success = __le32_to_cpu(src->num_rts_success);
883 dst->num_rx_err = __le32_to_cpu(src->num_rx_err);
884 dst->num_rx_discard = __le32_to_cpu(src->num_rx_discard);
885 dst->num_tx_not_acked = __le32_to_cpu(src->num_tx_not_acked);
886
887 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++)
888 dst->num_tx_frames[i] =
889 __le32_to_cpu(src->num_tx_frames[i]);
890
891 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++)
892 dst->num_tx_frames_retries[i] =
893 __le32_to_cpu(src->num_tx_frames_retries[i]);
894
895 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++)
896 dst->num_tx_frames_failures[i] =
897 __le32_to_cpu(src->num_tx_frames_failures[i]);
898
899 for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++)
900 dst->tx_rate_history[i] =
901 __le32_to_cpu(src->tx_rate_history[i]);
902
903 for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++)
904 dst->beacon_rssi_history[i] =
905 __le32_to_cpu(src->beacon_rssi_history[i]);
906}
907
872static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, 908static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
873 struct sk_buff *skb, 909 struct sk_buff *skb,
874 struct ath10k_fw_stats *stats) 910 struct ath10k_fw_stats *stats)
875{ 911{
876 const void **tb; 912 const void **tb;
877 const struct wmi_stats_event *ev; 913 const struct wmi_tlv_stats_ev *ev;
878 const void *data; 914 const void *data;
879 u32 num_pdev_stats, num_vdev_stats, num_peer_stats; 915 u32 num_pdev_stats;
916 u32 num_vdev_stats;
917 u32 num_peer_stats;
918 u32 num_bcnflt_stats;
919 u32 num_chan_stats;
880 size_t data_len; 920 size_t data_len;
881 int ret; 921 int ret;
922 int i;
882 923
883 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 924 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
884 if (IS_ERR(tb)) { 925 if (IS_ERR(tb)) {
@@ -899,8 +940,73 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
899 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); 940 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
900 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); 941 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
901 num_peer_stats = __le32_to_cpu(ev->num_peer_stats); 942 num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
943 num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats);
944 num_chan_stats = __le32_to_cpu(ev->num_chan_stats);
945
946 ath10k_dbg(ar, ATH10K_DBG_WMI,
947 "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i\n",
948 num_pdev_stats, num_vdev_stats, num_peer_stats,
949 num_bcnflt_stats, num_chan_stats);
950
951 for (i = 0; i < num_pdev_stats; i++) {
952 const struct wmi_pdev_stats *src;
953 struct ath10k_fw_stats_pdev *dst;
954
955 src = data;
956 if (data_len < sizeof(*src))
957 return -EPROTO;
958
959 data += sizeof(*src);
960 data_len -= sizeof(*src);
961
962 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
963 if (!dst)
964 continue;
965
966 ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
967 ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
968 ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
969 list_add_tail(&dst->list, &stats->pdevs);
970 }
971
972 for (i = 0; i < num_vdev_stats; i++) {
973 const struct wmi_tlv_vdev_stats *src;
974 struct ath10k_fw_stats_vdev *dst;
975
976 src = data;
977 if (data_len < sizeof(*src))
978 return -EPROTO;
979
980 data += sizeof(*src);
981 data_len -= sizeof(*src);
982
983 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
984 if (!dst)
985 continue;
902 986
903 WARN_ON(1); /* FIXME: not implemented yet */ 987 ath10k_wmi_tlv_pull_vdev_stats(src, dst);
988 list_add_tail(&dst->list, &stats->vdevs);
989 }
990
991 for (i = 0; i < num_peer_stats; i++) {
992 const struct wmi_10x_peer_stats *src;
993 struct ath10k_fw_stats_peer *dst;
994
995 src = data;
996 if (data_len < sizeof(*src))
997 return -EPROTO;
998
999 data += sizeof(*src);
1000 data_len -= sizeof(*src);
1001
1002 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
1003 if (!dst)
1004 continue;
1005
1006 ath10k_wmi_pull_peer_stats(&src->old, dst);
1007 dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
1008 list_add_tail(&dst->list, &stats->peers);
1009 }
904 1010
905 kfree(tb); 1011 kfree(tb);
906 return 0; 1012 return 0;
@@ -1604,14 +1710,12 @@ ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
1604 const struct wmi_wmm_params_all_arg *arg) 1710 const struct wmi_wmm_params_all_arg *arg)
1605{ 1711{
1606 struct wmi_tlv_vdev_set_wmm_cmd *cmd; 1712 struct wmi_tlv_vdev_set_wmm_cmd *cmd;
1607 struct wmi_wmm_params *wmm;
1608 struct wmi_tlv *tlv; 1713 struct wmi_tlv *tlv;
1609 struct sk_buff *skb; 1714 struct sk_buff *skb;
1610 size_t len; 1715 size_t len;
1611 void *ptr; 1716 void *ptr;
1612 1717
1613 len = (sizeof(*tlv) + sizeof(*cmd)) + 1718 len = sizeof(*tlv) + sizeof(*cmd);
1614 (4 * (sizeof(*tlv) + sizeof(*wmm)));
1615 skb = ath10k_wmi_alloc_skb(ar, len); 1719 skb = ath10k_wmi_alloc_skb(ar, len);
1616 if (!skb) 1720 if (!skb)
1617 return ERR_PTR(-ENOMEM); 1721 return ERR_PTR(-ENOMEM);
@@ -1623,13 +1727,10 @@ ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
1623 cmd = (void *)tlv->value; 1727 cmd = (void *)tlv->value;
1624 cmd->vdev_id = __cpu_to_le32(vdev_id); 1728 cmd->vdev_id = __cpu_to_le32(vdev_id);
1625 1729
1626 ptr += sizeof(*tlv); 1730 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[0].params, &arg->ac_be);
1627 ptr += sizeof(*cmd); 1731 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[1].params, &arg->ac_bk);
1628 1732 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[2].params, &arg->ac_vi);
1629 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be); 1733 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[3].params, &arg->ac_vo);
1630 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk);
1631 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi);
1632 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo);
1633 1734
1634 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n"); 1735 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n");
1635 return skb; 1736 return skb;
@@ -2080,8 +2181,7 @@ ath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar,
2080} 2181}
2081 2182
2082static struct sk_buff * 2183static struct sk_buff *
2083ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, 2184ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
2084 enum wmi_stats_id stats_id)
2085{ 2185{
2086 struct wmi_request_stats_cmd *cmd; 2186 struct wmi_request_stats_cmd *cmd;
2087 struct wmi_tlv *tlv; 2187 struct wmi_tlv *tlv;
@@ -2095,7 +2195,7 @@ ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar,
2095 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD); 2195 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD);
2096 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2196 tlv->len = __cpu_to_le16(sizeof(*cmd));
2097 cmd = (void *)tlv->value; 2197 cmd = (void *)tlv->value;
2098 cmd->stats_id = __cpu_to_le32(stats_id); 2198 cmd->stats_id = __cpu_to_le32(stats_mask);
2099 2199
2100 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n"); 2200 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n");
2101 return skb; 2201 return skb;
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index de68fe76eae6..a6c8280cc4b1 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -1302,8 +1302,14 @@ struct wmi_tlv_pdev_set_wmm_cmd {
1302 __le32 dg_type; /* no idea.. */ 1302 __le32 dg_type; /* no idea.. */
1303} __packed; 1303} __packed;
1304 1304
1305struct wmi_tlv_vdev_wmm_params {
1306 __le32 dummy;
1307 struct wmi_wmm_params params;
1308} __packed;
1309
1305struct wmi_tlv_vdev_set_wmm_cmd { 1310struct wmi_tlv_vdev_set_wmm_cmd {
1306 __le32 vdev_id; 1311 __le32 vdev_id;
1312 struct wmi_tlv_vdev_wmm_params vdev_wmm_params[4];
1307} __packed; 1313} __packed;
1308 1314
1309struct wmi_tlv_phyerr_ev { 1315struct wmi_tlv_phyerr_ev {
@@ -1439,6 +1445,15 @@ struct wmi_tlv_sta_keepalive_cmd {
1439 __le32 interval; /* in seconds */ 1445 __le32 interval; /* in seconds */
1440} __packed; 1446} __packed;
1441 1447
1448struct wmi_tlv_stats_ev {
1449 __le32 stats_id; /* WMI_STAT_ */
1450 __le32 num_pdev_stats;
1451 __le32 num_vdev_stats;
1452 __le32 num_peer_stats;
1453 __le32 num_bcnflt_stats;
1454 __le32 num_chan_stats;
1455} __packed;
1456
1442void ath10k_wmi_tlv_attach(struct ath10k *ar); 1457void ath10k_wmi_tlv_attach(struct ath10k *ar);
1443 1458
1444#endif 1459#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index aeea1c793943..c7ea77edce24 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1125,6 +1125,25 @@ static void ath10k_wmi_event_scan_started(struct ath10k *ar)
1125 } 1125 }
1126} 1126}
1127 1127
1128static void ath10k_wmi_event_scan_start_failed(struct ath10k *ar)
1129{
1130 lockdep_assert_held(&ar->data_lock);
1131
1132 switch (ar->scan.state) {
1133 case ATH10K_SCAN_IDLE:
1134 case ATH10K_SCAN_RUNNING:
1135 case ATH10K_SCAN_ABORTING:
1136 ath10k_warn(ar, "received scan start failed event in an invalid scan state: %s (%d)\n",
1137 ath10k_scan_state_str(ar->scan.state),
1138 ar->scan.state);
1139 break;
1140 case ATH10K_SCAN_STARTING:
1141 complete(&ar->scan.started);
1142 __ath10k_scan_finish(ar);
1143 break;
1144 }
1145}
1146
1128static void ath10k_wmi_event_scan_completed(struct ath10k *ar) 1147static void ath10k_wmi_event_scan_completed(struct ath10k *ar)
1129{ 1148{
1130 lockdep_assert_held(&ar->data_lock); 1149 lockdep_assert_held(&ar->data_lock);
@@ -1292,6 +1311,7 @@ int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb)
1292 break; 1311 break;
1293 case WMI_SCAN_EVENT_START_FAILED: 1312 case WMI_SCAN_EVENT_START_FAILED:
1294 ath10k_warn(ar, "received scan start failure event\n"); 1313 ath10k_warn(ar, "received scan start failure event\n");
1314 ath10k_wmi_event_scan_start_failed(ar);
1295 break; 1315 break;
1296 case WMI_SCAN_EVENT_DEQUEUED: 1316 case WMI_SCAN_EVENT_DEQUEUED:
1297 case WMI_SCAN_EVENT_PREEMPTED: 1317 case WMI_SCAN_EVENT_PREEMPTED:
@@ -4954,7 +4974,7 @@ ath10k_wmi_op_gen_pdev_set_wmm(struct ath10k *ar,
4954} 4974}
4955 4975
4956static struct sk_buff * 4976static struct sk_buff *
4957ath10k_wmi_op_gen_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) 4977ath10k_wmi_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
4958{ 4978{
4959 struct wmi_request_stats_cmd *cmd; 4979 struct wmi_request_stats_cmd *cmd;
4960 struct sk_buff *skb; 4980 struct sk_buff *skb;
@@ -4964,9 +4984,10 @@ ath10k_wmi_op_gen_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id)
4964 return ERR_PTR(-ENOMEM); 4984 return ERR_PTR(-ENOMEM);
4965 4985
4966 cmd = (struct wmi_request_stats_cmd *)skb->data; 4986 cmd = (struct wmi_request_stats_cmd *)skb->data;
4967 cmd->stats_id = __cpu_to_le32(stats_id); 4987 cmd->stats_id = __cpu_to_le32(stats_mask);
4968 4988
4969 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); 4989 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats 0x%08x\n",
4990 stats_mask);
4970 return skb; 4991 return skb;
4971} 4992}
4972 4993
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 20ce3603e64b..adf935bf0580 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -3057,8 +3057,12 @@ struct wmi_pdev_stats_peer {
3057} __packed; 3057} __packed;
3058 3058
3059enum wmi_stats_id { 3059enum wmi_stats_id {
3060 WMI_REQUEST_PEER_STAT = 0x01, 3060 WMI_STAT_PEER = BIT(0),
3061 WMI_REQUEST_AP_STAT = 0x02 3061 WMI_STAT_AP = BIT(1),
3062 WMI_STAT_PDEV = BIT(2),
3063 WMI_STAT_VDEV = BIT(3),
3064 WMI_STAT_BCNFLT = BIT(4),
3065 WMI_STAT_VDEV_RATE = BIT(5),
3062}; 3066};
3063 3067
3064struct wlan_inst_rssi_args { 3068struct wlan_inst_rssi_args {
@@ -3093,7 +3097,7 @@ struct wmi_pdev_suspend_cmd {
3093} __packed; 3097} __packed;
3094 3098
3095struct wmi_stats_event { 3099struct wmi_stats_event {
3096 __le32 stats_id; /* %WMI_REQUEST_ */ 3100 __le32 stats_id; /* WMI_STAT_ */
3097 /* 3101 /*
3098 * number of pdev stats event structures 3102 * number of pdev stats event structures
3099 * (wmi_pdev_stats) 0 or 1 3103 * (wmi_pdev_stats) 0 or 1
@@ -3745,6 +3749,11 @@ enum wmi_10x_vdev_param {
3745 WMI_10X_VDEV_PARAM_VHT80_RATEMASK, 3749 WMI_10X_VDEV_PARAM_VHT80_RATEMASK,
3746}; 3750};
3747 3751
3752#define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0)
3753#define WMI_VDEV_PARAM_TXBF_MU_TX_BFEE BIT(1)
3754#define WMI_VDEV_PARAM_TXBF_SU_TX_BFER BIT(2)
3755#define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3)
3756
3748/* slot time long */ 3757/* slot time long */
3749#define WMI_VDEV_SLOT_TIME_LONG 0x1 3758#define WMI_VDEV_SLOT_TIME_LONG 0x1
3750/* slot time short */ 3759/* slot time short */
@@ -4436,7 +4445,8 @@ enum wmi_peer_param {
4436 WMI_PEER_AUTHORIZE = 0x3, 4445 WMI_PEER_AUTHORIZE = 0x3,
4437 WMI_PEER_CHAN_WIDTH = 0x4, 4446 WMI_PEER_CHAN_WIDTH = 0x4,
4438 WMI_PEER_NSS = 0x5, 4447 WMI_PEER_NSS = 0x5,
4439 WMI_PEER_USE_4ADDR = 0x6 4448 WMI_PEER_USE_4ADDR = 0x6,
4449 WMI_PEER_DUMMY_VAR = 0xff, /* dummy parameter for STA PS workaround */
4440}; 4450};
4441 4451
4442struct wmi_peer_set_param_cmd { 4452struct wmi_peer_set_param_cmd {