aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/debug.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c267
1 files changed, 8 insertions, 259 deletions
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index eab71e2eb4d7..6cc1aa3449c8 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -291,28 +291,6 @@ static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
291 spin_unlock_bh(&ar->data_lock); 291 spin_unlock_bh(&ar->data_lock);
292} 292}
293 293
294static size_t ath10k_debug_fw_stats_num_peers(struct list_head *head)
295{
296 struct ath10k_fw_stats_peer *i;
297 size_t num = 0;
298
299 list_for_each_entry(i, head, list)
300 ++num;
301
302 return num;
303}
304
305static size_t ath10k_debug_fw_stats_num_vdevs(struct list_head *head)
306{
307 struct ath10k_fw_stats_vdev *i;
308 size_t num = 0;
309
310 list_for_each_entry(i, head, list)
311 ++num;
312
313 return num;
314}
315
316void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) 294void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
317{ 295{
318 struct ath10k_fw_stats stats = {}; 296 struct ath10k_fw_stats stats = {};
@@ -349,8 +327,8 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
349 goto free; 327 goto free;
350 } 328 }
351 329
352 num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers); 330 num_peers = ath10k_wmi_fw_stats_num_peers(&ar->debug.fw_stats.peers);
353 num_vdevs = ath10k_debug_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs); 331 num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
354 is_start = (list_empty(&ar->debug.fw_stats.pdevs) && 332 is_start = (list_empty(&ar->debug.fw_stats.pdevs) &&
355 !list_empty(&stats.pdevs)); 333 !list_empty(&stats.pdevs));
356 is_end = (!list_empty(&ar->debug.fw_stats.pdevs) && 334 is_end = (!list_empty(&ar->debug.fw_stats.pdevs) &&
@@ -435,240 +413,6 @@ static int ath10k_debug_fw_stats_request(struct ath10k *ar)
435 return 0; 413 return 0;
436} 414}
437 415
438/* FIXME: How to calculate the buffer size sanely? */
439#define ATH10K_FW_STATS_BUF_SIZE (1024*1024)
440
441static void ath10k_fw_stats_fill(struct ath10k *ar,
442 struct ath10k_fw_stats *fw_stats,
443 char *buf)
444{
445 unsigned int len = 0;
446 unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE;
447 const struct ath10k_fw_stats_pdev *pdev;
448 const struct ath10k_fw_stats_vdev *vdev;
449 const struct ath10k_fw_stats_peer *peer;
450 size_t num_peers;
451 size_t num_vdevs;
452 int i;
453
454 spin_lock_bh(&ar->data_lock);
455
456 pdev = list_first_entry_or_null(&fw_stats->pdevs,
457 struct ath10k_fw_stats_pdev, list);
458 if (!pdev) {
459 ath10k_warn(ar, "failed to get pdev stats\n");
460 goto unlock;
461 }
462
463 num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers);
464 num_vdevs = ath10k_debug_fw_stats_num_vdevs(&fw_stats->vdevs);
465
466 len += scnprintf(buf + len, buf_len - len, "\n");
467 len += scnprintf(buf + len, buf_len - len, "%30s\n",
468 "ath10k PDEV stats");
469 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
470 "=================");
471
472 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
473 "Channel noise floor", pdev->ch_noise_floor);
474 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
475 "Channel TX power", pdev->chan_tx_power);
476 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
477 "TX frame count", pdev->tx_frame_count);
478 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
479 "RX frame count", pdev->rx_frame_count);
480 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
481 "RX clear count", pdev->rx_clear_count);
482 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
483 "Cycle count", pdev->cycle_count);
484 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
485 "PHY error count", pdev->phy_err_count);
486 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
487 "RTS bad count", pdev->rts_bad);
488 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
489 "RTS good count", pdev->rts_good);
490 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
491 "FCS bad count", pdev->fcs_bad);
492 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
493 "No beacon count", pdev->no_beacons);
494 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
495 "MIB int count", pdev->mib_int_count);
496
497 len += scnprintf(buf + len, buf_len - len, "\n");
498 len += scnprintf(buf + len, buf_len - len, "%30s\n",
499 "ath10k PDEV TX stats");
500 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
501 "=================");
502
503 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
504 "HTT cookies queued", pdev->comp_queued);
505 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
506 "HTT cookies disp.", pdev->comp_delivered);
507 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
508 "MSDU queued", pdev->msdu_enqued);
509 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
510 "MPDU queued", pdev->mpdu_enqued);
511 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
512 "MSDUs dropped", pdev->wmm_drop);
513 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
514 "Local enqued", pdev->local_enqued);
515 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
516 "Local freed", pdev->local_freed);
517 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
518 "HW queued", pdev->hw_queued);
519 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
520 "PPDUs reaped", pdev->hw_reaped);
521 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
522 "Num underruns", pdev->underrun);
523 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
524 "PPDUs cleaned", pdev->tx_abort);
525 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
526 "MPDUs requed", pdev->mpdus_requed);
527 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
528 "Excessive retries", pdev->tx_ko);
529 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
530 "HW rate", pdev->data_rc);
531 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
532 "Sched self tiggers", pdev->self_triggers);
533 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
534 "Dropped due to SW retries",
535 pdev->sw_retry_failure);
536 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
537 "Illegal rate phy errors",
538 pdev->illgl_rate_phy_err);
539 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
540 "Pdev continous xretry", pdev->pdev_cont_xretry);
541 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
542 "TX timeout", pdev->pdev_tx_timeout);
543 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
544 "PDEV resets", pdev->pdev_resets);
545 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
546 "PHY underrun", pdev->phy_underrun);
547 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
548 "MPDU is more than txop limit", pdev->txop_ovf);
549
550 len += scnprintf(buf + len, buf_len - len, "\n");
551 len += scnprintf(buf + len, buf_len - len, "%30s\n",
552 "ath10k PDEV RX stats");
553 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
554 "=================");
555
556 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
557 "Mid PPDU route change",
558 pdev->mid_ppdu_route_change);
559 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
560 "Tot. number of statuses", pdev->status_rcvd);
561 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
562 "Extra frags on rings 0", pdev->r0_frags);
563 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
564 "Extra frags on rings 1", pdev->r1_frags);
565 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
566 "Extra frags on rings 2", pdev->r2_frags);
567 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
568 "Extra frags on rings 3", pdev->r3_frags);
569 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
570 "MSDUs delivered to HTT", pdev->htt_msdus);
571 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
572 "MPDUs delivered to HTT", pdev->htt_mpdus);
573 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
574 "MSDUs delivered to stack", pdev->loc_msdus);
575 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
576 "MPDUs delivered to stack", pdev->loc_mpdus);
577 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
578 "Oversized AMSUs", pdev->oversize_amsdu);
579 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
580 "PHY errors", pdev->phy_errs);
581 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
582 "PHY errors drops", pdev->phy_err_drop);
583 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
584 "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs);
585
586 len += scnprintf(buf + len, buf_len - len, "\n");
587 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
588 "ath10k VDEV stats", num_vdevs);
589 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
590 "=================");
591
592 list_for_each_entry(vdev, &fw_stats->vdevs, list) {
593 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
594 "vdev id", vdev->vdev_id);
595 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
596 "beacon snr", vdev->beacon_snr);
597 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
598 "data snr", vdev->data_snr);
599 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
600 "num rx frames", vdev->num_rx_frames);
601 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
602 "num rts fail", vdev->num_rts_fail);
603 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
604 "num rts success", vdev->num_rts_success);
605 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
606 "num rx err", vdev->num_rx_err);
607 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
608 "num rx discard", vdev->num_rx_discard);
609 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
610 "num tx not acked", vdev->num_tx_not_acked);
611
612 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++)
613 len += scnprintf(buf + len, buf_len - len,
614 "%25s [%02d] %u\n",
615 "num tx frames", i,
616 vdev->num_tx_frames[i]);
617
618 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++)
619 len += scnprintf(buf + len, buf_len - len,
620 "%25s [%02d] %u\n",
621 "num tx frames retries", i,
622 vdev->num_tx_frames_retries[i]);
623
624 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++)
625 len += scnprintf(buf + len, buf_len - len,
626 "%25s [%02d] %u\n",
627 "num tx frames failures", i,
628 vdev->num_tx_frames_failures[i]);
629
630 for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++)
631 len += scnprintf(buf + len, buf_len - len,
632 "%25s [%02d] 0x%08x\n",
633 "tx rate history", i,
634 vdev->tx_rate_history[i]);
635
636 for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++)
637 len += scnprintf(buf + len, buf_len - len,
638 "%25s [%02d] %u\n",
639 "beacon rssi history", i,
640 vdev->beacon_rssi_history[i]);
641
642 len += scnprintf(buf + len, buf_len - len, "\n");
643 }
644
645 len += scnprintf(buf + len, buf_len - len, "\n");
646 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
647 "ath10k PEER stats", num_peers);
648 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
649 "=================");
650
651 list_for_each_entry(peer, &fw_stats->peers, list) {
652 len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
653 "Peer MAC address", peer->peer_macaddr);
654 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
655 "Peer RSSI", peer->peer_rssi);
656 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
657 "Peer TX rate", peer->peer_tx_rate);
658 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
659 "Peer RX rate", peer->peer_rx_rate);
660 len += scnprintf(buf + len, buf_len - len, "\n");
661 }
662
663unlock:
664 spin_unlock_bh(&ar->data_lock);
665
666 if (len >= buf_len)
667 buf[len - 1] = 0;
668 else
669 buf[len] = 0;
670}
671
672static int ath10k_fw_stats_open(struct inode *inode, struct file *file) 416static int ath10k_fw_stats_open(struct inode *inode, struct file *file)
673{ 417{
674 struct ath10k *ar = inode->i_private; 418 struct ath10k *ar = inode->i_private;
@@ -694,7 +438,12 @@ static int ath10k_fw_stats_open(struct inode *inode, struct file *file)
694 goto err_free; 438 goto err_free;
695 } 439 }
696 440
697 ath10k_fw_stats_fill(ar, &ar->debug.fw_stats, buf); 441 ret = ath10k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, buf);
442 if (ret) {
443 ath10k_warn(ar, "failed to fill fw stats: %d\n", ret);
444 goto err_free;
445 }
446
698 file->private_data = buf; 447 file->private_data = buf;
699 448
700 mutex_unlock(&ar->conf_mutex); 449 mutex_unlock(&ar->conf_mutex);