diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/debug.c')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/debug.c | 267 |
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 | ||
294 | static 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 | |||
305 | static 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 | |||
316 | void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) | 294 | void 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 | |||
441 | static 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 | |||
663 | unlock: | ||
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 | |||
672 | static int ath10k_fw_stats_open(struct inode *inode, struct file *file) | 416 | static 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); |