Message ID | 20250425012802.698914-4-nithyanantham.paramasivam@oss.qualcomm.com |
---|---|
State | New |
Headers | show |
Series | wifi: ath12k: Add device dp stats support | expand |
On 4/25/2025 6:58 AM, Nithyanantham Paramasivam wrote: > From: Vinith Kumar R <quic_vinithku@quicinc.com> > > Print the data path related device specific stats in debugfs. > These device_dp_stats are exposed in the ath12k debugfs directory. > > Output of device_dp_stats: > root@CDCWLEX0799743-LIN:/home/qctest# > cat /sys/kernel/debug/ath12k/pci-0000\:58\:00.0/device_dp_stats > DEVICE RX STATS: > > err ring pkts: 0 > Invalid RBM: 0 > > RXDMA errors: > Overflow: 0 > MPDU len: 0 > FCS: 0 > Decrypt: 0 > TKIP MIC: 0 > Unencrypt: 0 > MSDU len: 0 > MSDU limit: 0 > WiFi parse: 0 > AMSDU parse: 0 > SA timeout: 0 > DA timeout: 0 > Flow timeout: 0 > Flush req: 0 > AMSDU frag: 0 > Multicast echo: 0 > AMSDU mismatch: 0 > Unauth WDS: 0 > AMSDU or WDS: 0 > > REO errors: > Desc addr zero: 0 > Desc inval: 0 > AMPDU in non BA: 0 > Non BA dup: 0 > BA dup: 0 > Frame 2k jump: 0 > BAR 2k jump: 0 > Frame OOR: 155 > BAR OOR: 0 > No BA session: 0 > Frame SN equal SSN: 0 > PN check fail: 0 > 2k err: 0 > PN err: 0 > Desc blocked: 0 > > HAL REO errors: > ring0: 0 > ring1: 0 > ring2: 0 > ring3: 0 > ring4: 0 > ring5: 0 > ring6: 0 > ring7: 0 > > DEVICE TX STATS: > > TCL Ring Full Failures: > ring0: 0 > ring1: 0 > ring2: 0 > ring3: 0 > > Misc Transmit Failures: 0 > > tx_wbm_rel_source: 0:986 1:0 2:0 3:57 4:0 > > tqm_rel_reason: 0:1043 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:0 > > fw_tx_status: 0:57 1:0 2:0 3:0 4:0 5:0 6:0 > > tx_enqueued: 0:329 1:145 2:464 3:105 > > tx_completed: 0:329 1:145 2:464 3:105 > > radio0 tx_pending: 0 > > REO Rx Received: > Ring1: 0:201 1:0 2:0 > Ring2: 0:0 1:0 2:0 > Ring3: 0:6152 1:0 2:0 > Ring4: 0:9 1:0 2:0 > Ring5: 0:0 1:0 2:0 > Ring6: 0:0 1:0 2:0 > Ring7: 0:0 1:0 2:0 > Ring8: 0:0 1:0 2:0 > > Rx WBM REL SRC Errors: > TQM: 0:0 1:0 2:0 > Rxdma: 0:0 1:0 2:0 > Reo: 0:155 1:0 2:0 > FW: 0:0 1:0 2:0 > SW: 0:0 1:0 2:0 > > Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.1.1-00210-QCAHKSWPL_SILICONZ-1 > Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 > > Signed-off-by: Vinith Kumar R <quic_vinithku@quicinc.com> > Signed-off-by: Nithyanantham Paramasivam <nithyanantham.paramasivam@oss.qualcomm.com> > --- > drivers/net/wireless/ath/ath12k/core.c | 2 + > drivers/net/wireless/ath/ath12k/debugfs.c | 199 +++++++++++++++++++++- > 2 files changed, 195 insertions(+), 6 deletions(-) > > diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c > index 2cfeb853289d..5203d94c8b10 100644 > --- a/drivers/net/wireless/ath/ath12k/core.c > +++ b/drivers/net/wireless/ath/ath12k/core.c > @@ -789,6 +789,8 @@ static int ath12k_core_soc_create(struct ath12k_base *ab) > goto err_qmi_deinit; > } > > + ath12k_debugfs_pdev_create(ab); > + > return 0; > > err_qmi_deinit: > diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c > index 1f0983c33885..dd624d73b8b2 100644 > --- a/drivers/net/wireless/ath/ath12k/debugfs.c > +++ b/drivers/net/wireless/ath/ath12k/debugfs.c > @@ -103,12 +103,6 @@ static const struct file_operations fops_simulate_fw_crash = { > .llseek = default_llseek, > }; > > -void ath12k_debugfs_pdev_create(struct ath12k_base *ab) > -{ > - debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, > - &fops_simulate_fw_crash); > -} > - > static ssize_t ath12k_write_tpc_stats_type(struct file *file, > const char __user *user_buf, > size_t count, loff_t *ppos) > @@ -1027,6 +1021,199 @@ void ath12k_debugfs_op_vif_add(struct ieee80211_hw *hw, > &ath12k_fops_link_stats); > } > > +static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file, > + char __user *user_buf, > + size_t count, loff_t *ppos) > +{ > + struct ath12k_base *ab = file->private_data; > + struct ath12k_device_dp_stats *device_stats = &ab->device_stats; > + int len = 0, i, j, ret; > + struct ath12k *ar; > + const int size = 4096; > + static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = { > + [HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR] = "Overflow", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR] = "MPDU len", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_FCS_ERR] = "FCS", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR] = "Decrypt", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR] = "TKIP MIC", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_UNECRYPTED_ERR] = "Unencrypt", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LEN_ERR] = "MSDU len", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LIMIT_ERR] = "MSDU limit", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_WIFI_PARSE_ERR] = "WiFi parse", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_PARSE_ERR] = "AMSDU parse", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_SA_TIMEOUT_ERR] = "SA timeout", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_DA_TIMEOUT_ERR] = "DA timeout", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR] = "Flow timeout", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR] = "Flush req", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR] = "AMSDU frag", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR] = "Multicast echo", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR] = "AMSDU mismatch", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR] = "Unauth WDS", > + [HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR] = "AMSDU or WDS"}; > + > + static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = { > + [HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO] = "Desc addr zero", > + [HAL_REO_DEST_RING_ERROR_CODE_DESC_INVALID] = "Desc inval", > + [HAL_REO_DEST_RING_ERROR_CODE_AMPDU_IN_NON_BA] = "AMPDU in non BA", > + [HAL_REO_DEST_RING_ERROR_CODE_NON_BA_DUPLICATE] = "Non BA dup", > + [HAL_REO_DEST_RING_ERROR_CODE_BA_DUPLICATE] = "BA dup", > + [HAL_REO_DEST_RING_ERROR_CODE_FRAME_2K_JUMP] = "Frame 2k jump", > + [HAL_REO_DEST_RING_ERROR_CODE_BAR_2K_JUMP] = "BAR 2k jump", > + [HAL_REO_DEST_RING_ERROR_CODE_FRAME_OOR] = "Frame OOR", > + [HAL_REO_DEST_RING_ERROR_CODE_BAR_OOR] = "BAR OOR", > + [HAL_REO_DEST_RING_ERROR_CODE_NO_BA_SESSION] = "No BA session", > + [HAL_REO_DEST_RING_ERROR_CODE_FRAME_SN_EQUALS_SSN] = "Frame SN equal SSN", > + [HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED] = "PN check fail", > + [HAL_REO_DEST_RING_ERROR_CODE_2K_ERR_FLAG_SET] = "2k err", > + [HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET] = "PN err", > + [HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED] = "Desc blocked"}; > + > + static const char *wbm_rel_src[HAL_WBM_REL_SRC_MODULE_MAX] = { > + [HAL_WBM_REL_SRC_MODULE_TQM] = "TQM", > + [HAL_WBM_REL_SRC_MODULE_RXDMA] = "Rxdma", > + [HAL_WBM_REL_SRC_MODULE_REO] = "Reo", > + [HAL_WBM_REL_SRC_MODULE_FW] = "FW", > + [HAL_WBM_REL_SRC_MODULE_SW] = "SW"}; > + > + char *buf __free(kfree) = kzalloc(size, GFP_KERNEL); > + > + if (!buf) > + return -ENOMEM; > + > + len += scnprintf(buf + len, size - len, "DEVICE RX STATS:\n\n"); > + len += scnprintf(buf + len, size - len, "err ring pkts: %u\n", > + device_stats->err_ring_pkts); > + len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n", > + device_stats->invalid_rbm); > + len += scnprintf(buf + len, size - len, "RXDMA errors:\n"); > + > + for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++) > + len += scnprintf(buf + len, size - len, "%s: %u\n", > + rxdma_err[i], device_stats->rxdma_error[i]); > + > + len += scnprintf(buf + len, size - len, "\nREO errors:\n"); > + > + for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++) > + len += scnprintf(buf + len, size - len, "%s: %u\n", > + reo_err[i], device_stats->reo_error[i]); > + > + len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n"); > + > + for (i = 0; i < DP_REO_DST_RING_MAX; i++) > + len += scnprintf(buf + len, size - len, > + "ring%d: %u\n", i, > + device_stats->hal_reo_error[i]); > + > + len += scnprintf(buf + len, size - len, "\nDEVICE TX STATS:\n"); > + len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n"); > + > + for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) > + len += scnprintf(buf + len, size - len, "ring%d: %u\n", > + i, device_stats->tx_err.desc_na[i]); > + > + len += scnprintf(buf + len, size - len, > + "\nMisc Transmit Failures: %d\n", > + atomic_read(&device_stats->tx_err.misc_fail)); > + > + len += scnprintf(buf + len, size - len, "\ntx_wbm_rel_source:"); > + > + for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++) > + len += scnprintf(buf + len, size - len, " %d:%u", > + i, device_stats->tx_wbm_rel_source[i]); > + > + len += scnprintf(buf + len, size - len, "\n"); > + > + len += scnprintf(buf + len, size - len, "\ntqm_rel_reason:"); > + > + for (i = 0; i < MAX_TQM_RELEASE_REASON; i++) > + len += scnprintf(buf + len, size - len, " %d:%u", > + i, device_stats->tqm_rel_reason[i]); > + > + len += scnprintf(buf + len, size - len, "\n"); > + > + len += scnprintf(buf + len, size - len, "\nfw_tx_status:"); > + > + for (i = 0; i < MAX_FW_TX_STATUS; i++) > + len += scnprintf(buf + len, size - len, " %d:%u", > + i, device_stats->fw_tx_status[i]); > + > + len += scnprintf(buf + len, size - len, "\n"); > + > + len += scnprintf(buf + len, size - len, "\ntx_enqueued:"); > + > + for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) > + len += scnprintf(buf + len, size - len, " %d:%u", i, > + device_stats->tx_enqueued[i]); > + > + len += scnprintf(buf + len, size - len, "\n"); > + > + len += scnprintf(buf + len, size - len, "\ntx_completed:"); > + > + for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) > + len += scnprintf(buf + len, size - len, " %d:%u", > + i, device_stats->tx_completed[i]); > + > + len += scnprintf(buf + len, size - len, "\n"); > + > + for (i = 0; i < ab->num_radios; i++) { > + ar = ath12k_mac_get_ar_by_pdev_id(ab, DP_SW2HW_MACID(i)); > + if (ar) { > + len += scnprintf(buf + len, size - len, > + "\nradio%d tx_pending: %u\n", i, > + atomic_read(&ar->dp.num_tx_pending)); > + } > + } > + > + len += scnprintf(buf + len, size - len, "\nREO Rx Received:\n"); > + > + for (i = 0; i < DP_REO_DST_RING_MAX; i++) { > + len += scnprintf(buf + len, size - len, "Ring%d:", i + 1); > + > + for (j = 0; j < ATH12K_MAX_DEVICES; j++) { > + len += scnprintf(buf + len, size - len, > + "\t%d:%u", j, > + device_stats->reo_rx[i][j]); > + } > + > + len += scnprintf(buf + len, size - len, "\n"); > + } > + > + len += scnprintf(buf + len, size - len, "\nRx WBM REL SRC Errors:\n"); > + > + for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++) { > + len += scnprintf(buf + len, size - len, "%s:", wbm_rel_src[i]); > + > + for (j = 0; j < ATH12K_MAX_DEVICES; j++) { > + len += scnprintf(buf + len, > + size - len, > + "\t%d:%u", j, > + device_stats->rx_wbm_rel_source[i][j]); > + } > + > + len += scnprintf(buf + len, size - len, "\n"); > + } > + > + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); > + > + return ret; > +} > + > +static const struct file_operations fops_device_dp_stats = { > + .read = ath12k_debugfs_dump_device_dp_stats, > + .open = simple_open, > + .owner = THIS_MODULE, > + .llseek = default_llseek, > +}; > + > +void ath12k_debugfs_pdev_create(struct ath12k_base *ab) > +{ > + debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, > + &fops_simulate_fw_crash); > + > + debugfs_create_file("device_dp_stats", 0400, ab->debugfs_soc, ab, > + &fops_device_dp_stats); > +} > + > void ath12k_debugfs_soc_create(struct ath12k_base *ab) > { > bool dput_needed; Reviewed-by: Mahendran P <quic_mahep@quicinc.com>
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 2cfeb853289d..5203d94c8b10 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -789,6 +789,8 @@ static int ath12k_core_soc_create(struct ath12k_base *ab) goto err_qmi_deinit; } + ath12k_debugfs_pdev_create(ab); + return 0; err_qmi_deinit: diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index 1f0983c33885..dd624d73b8b2 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -103,12 +103,6 @@ static const struct file_operations fops_simulate_fw_crash = { .llseek = default_llseek, }; -void ath12k_debugfs_pdev_create(struct ath12k_base *ab) -{ - debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, - &fops_simulate_fw_crash); -} - static ssize_t ath12k_write_tpc_stats_type(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -1027,6 +1021,199 @@ void ath12k_debugfs_op_vif_add(struct ieee80211_hw *hw, &ath12k_fops_link_stats); } +static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath12k_base *ab = file->private_data; + struct ath12k_device_dp_stats *device_stats = &ab->device_stats; + int len = 0, i, j, ret; + struct ath12k *ar; + const int size = 4096; + static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = { + [HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR] = "Overflow", + [HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR] = "MPDU len", + [HAL_REO_ENTR_RING_RXDMA_ECODE_FCS_ERR] = "FCS", + [HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR] = "Decrypt", + [HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR] = "TKIP MIC", + [HAL_REO_ENTR_RING_RXDMA_ECODE_UNECRYPTED_ERR] = "Unencrypt", + [HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LEN_ERR] = "MSDU len", + [HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LIMIT_ERR] = "MSDU limit", + [HAL_REO_ENTR_RING_RXDMA_ECODE_WIFI_PARSE_ERR] = "WiFi parse", + [HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_PARSE_ERR] = "AMSDU parse", + [HAL_REO_ENTR_RING_RXDMA_ECODE_SA_TIMEOUT_ERR] = "SA timeout", + [HAL_REO_ENTR_RING_RXDMA_ECODE_DA_TIMEOUT_ERR] = "DA timeout", + [HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR] = "Flow timeout", + [HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR] = "Flush req", + [HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR] = "AMSDU frag", + [HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR] = "Multicast echo", + [HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR] = "AMSDU mismatch", + [HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR] = "Unauth WDS", + [HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR] = "AMSDU or WDS"}; + + static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = { + [HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO] = "Desc addr zero", + [HAL_REO_DEST_RING_ERROR_CODE_DESC_INVALID] = "Desc inval", + [HAL_REO_DEST_RING_ERROR_CODE_AMPDU_IN_NON_BA] = "AMPDU in non BA", + [HAL_REO_DEST_RING_ERROR_CODE_NON_BA_DUPLICATE] = "Non BA dup", + [HAL_REO_DEST_RING_ERROR_CODE_BA_DUPLICATE] = "BA dup", + [HAL_REO_DEST_RING_ERROR_CODE_FRAME_2K_JUMP] = "Frame 2k jump", + [HAL_REO_DEST_RING_ERROR_CODE_BAR_2K_JUMP] = "BAR 2k jump", + [HAL_REO_DEST_RING_ERROR_CODE_FRAME_OOR] = "Frame OOR", + [HAL_REO_DEST_RING_ERROR_CODE_BAR_OOR] = "BAR OOR", + [HAL_REO_DEST_RING_ERROR_CODE_NO_BA_SESSION] = "No BA session", + [HAL_REO_DEST_RING_ERROR_CODE_FRAME_SN_EQUALS_SSN] = "Frame SN equal SSN", + [HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED] = "PN check fail", + [HAL_REO_DEST_RING_ERROR_CODE_2K_ERR_FLAG_SET] = "2k err", + [HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET] = "PN err", + [HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED] = "Desc blocked"}; + + static const char *wbm_rel_src[HAL_WBM_REL_SRC_MODULE_MAX] = { + [HAL_WBM_REL_SRC_MODULE_TQM] = "TQM", + [HAL_WBM_REL_SRC_MODULE_RXDMA] = "Rxdma", + [HAL_WBM_REL_SRC_MODULE_REO] = "Reo", + [HAL_WBM_REL_SRC_MODULE_FW] = "FW", + [HAL_WBM_REL_SRC_MODULE_SW] = "SW"}; + + char *buf __free(kfree) = kzalloc(size, GFP_KERNEL); + + if (!buf) + return -ENOMEM; + + len += scnprintf(buf + len, size - len, "DEVICE RX STATS:\n\n"); + len += scnprintf(buf + len, size - len, "err ring pkts: %u\n", + device_stats->err_ring_pkts); + len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n", + device_stats->invalid_rbm); + len += scnprintf(buf + len, size - len, "RXDMA errors:\n"); + + for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++) + len += scnprintf(buf + len, size - len, "%s: %u\n", + rxdma_err[i], device_stats->rxdma_error[i]); + + len += scnprintf(buf + len, size - len, "\nREO errors:\n"); + + for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++) + len += scnprintf(buf + len, size - len, "%s: %u\n", + reo_err[i], device_stats->reo_error[i]); + + len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n"); + + for (i = 0; i < DP_REO_DST_RING_MAX; i++) + len += scnprintf(buf + len, size - len, + "ring%d: %u\n", i, + device_stats->hal_reo_error[i]); + + len += scnprintf(buf + len, size - len, "\nDEVICE TX STATS:\n"); + len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n"); + + for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) + len += scnprintf(buf + len, size - len, "ring%d: %u\n", + i, device_stats->tx_err.desc_na[i]); + + len += scnprintf(buf + len, size - len, + "\nMisc Transmit Failures: %d\n", + atomic_read(&device_stats->tx_err.misc_fail)); + + len += scnprintf(buf + len, size - len, "\ntx_wbm_rel_source:"); + + for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++) + len += scnprintf(buf + len, size - len, " %d:%u", + i, device_stats->tx_wbm_rel_source[i]); + + len += scnprintf(buf + len, size - len, "\n"); + + len += scnprintf(buf + len, size - len, "\ntqm_rel_reason:"); + + for (i = 0; i < MAX_TQM_RELEASE_REASON; i++) + len += scnprintf(buf + len, size - len, " %d:%u", + i, device_stats->tqm_rel_reason[i]); + + len += scnprintf(buf + len, size - len, "\n"); + + len += scnprintf(buf + len, size - len, "\nfw_tx_status:"); + + for (i = 0; i < MAX_FW_TX_STATUS; i++) + len += scnprintf(buf + len, size - len, " %d:%u", + i, device_stats->fw_tx_status[i]); + + len += scnprintf(buf + len, size - len, "\n"); + + len += scnprintf(buf + len, size - len, "\ntx_enqueued:"); + + for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) + len += scnprintf(buf + len, size - len, " %d:%u", i, + device_stats->tx_enqueued[i]); + + len += scnprintf(buf + len, size - len, "\n"); + + len += scnprintf(buf + len, size - len, "\ntx_completed:"); + + for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) + len += scnprintf(buf + len, size - len, " %d:%u", + i, device_stats->tx_completed[i]); + + len += scnprintf(buf + len, size - len, "\n"); + + for (i = 0; i < ab->num_radios; i++) { + ar = ath12k_mac_get_ar_by_pdev_id(ab, DP_SW2HW_MACID(i)); + if (ar) { + len += scnprintf(buf + len, size - len, + "\nradio%d tx_pending: %u\n", i, + atomic_read(&ar->dp.num_tx_pending)); + } + } + + len += scnprintf(buf + len, size - len, "\nREO Rx Received:\n"); + + for (i = 0; i < DP_REO_DST_RING_MAX; i++) { + len += scnprintf(buf + len, size - len, "Ring%d:", i + 1); + + for (j = 0; j < ATH12K_MAX_DEVICES; j++) { + len += scnprintf(buf + len, size - len, + "\t%d:%u", j, + device_stats->reo_rx[i][j]); + } + + len += scnprintf(buf + len, size - len, "\n"); + } + + len += scnprintf(buf + len, size - len, "\nRx WBM REL SRC Errors:\n"); + + for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++) { + len += scnprintf(buf + len, size - len, "%s:", wbm_rel_src[i]); + + for (j = 0; j < ATH12K_MAX_DEVICES; j++) { + len += scnprintf(buf + len, + size - len, + "\t%d:%u", j, + device_stats->rx_wbm_rel_source[i][j]); + } + + len += scnprintf(buf + len, size - len, "\n"); + } + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); + + return ret; +} + +static const struct file_operations fops_device_dp_stats = { + .read = ath12k_debugfs_dump_device_dp_stats, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +void ath12k_debugfs_pdev_create(struct ath12k_base *ab) +{ + debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, + &fops_simulate_fw_crash); + + debugfs_create_file("device_dp_stats", 0400, ab->debugfs_soc, ab, + &fops_device_dp_stats); +} + void ath12k_debugfs_soc_create(struct ath12k_base *ab) { bool dput_needed;