--- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -673,12 +673,22 @@ struct ath11k_soc_dp_ring_stats { struct ath11k_dp_ring_bp_stats bp_stats; }; -struct ath11k_soc_dp_rx_stats { +struct ath11k_soc_dp_tx_err_stats { + /* TCL Ring Descriptor unavailable */ + u32 desc_na[DP_TCL_NUM_RING_MAX]; + /* Other failures during dp_tx due to mem allocation failure + * idr unavailable etc. + */ + atomic_t misc_fail; +}; + +struct ath11k_soc_dp_stats { u32 err_ring_pkts; u32 invalid_rbm; u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX]; u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX]; u32 hal_reo_error[DP_REO_DST_RING_MAX]; + struct ath11k_soc_dp_tx_err_stats tx_err; }; /* Master structure to hold the hw data which may be used in core module */ @@ -747,7 +757,7 @@ struct ath11k_base { struct dentry *debugfs_ath11k; struct ath11k_soc_dp_ring_stats ring_stats; #endif - struct ath11k_soc_dp_rx_stats soc_stats; + struct ath11k_soc_dp_stats soc_stats; unsigned long dev_flags; struct completion driver_recovery; --- a/drivers/net/wireless/ath/ath11k/debug.c +++ b/drivers/net/wireless/ath/ath11k/debug.c @@ -976,12 +976,12 @@ static const struct file_operations fops .open = simple_open, }; -static ssize_t ath11k_debug_dump_soc_rx_stats(struct file *file, +static ssize_t ath11k_debug_dump_soc_dp_stats(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath11k_base *ab = file->private_data; - struct ath11k_soc_dp_rx_stats *soc_stats = &ab->soc_stats; + struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats; int len = 0, i, retval; const int size = 4096; static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = { @@ -1025,6 +1025,16 @@ static ssize_t ath11k_debug_dump_soc_rx_ soc_stats->hal_reo_error[2], soc_stats->hal_reo_error[3]); + len += scnprintf(buf + len, size - len, "\nSOC 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, soc_stats->tx_err.desc_na[i]); + + len += scnprintf(buf + len, size - len, + "\nMisc Transmit Failures: %d\n", + atomic_read(&soc_stats->tx_err.misc_fail)); + if (len > size) len = size; retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); @@ -1121,8 +1131,8 @@ static ssize_t ath11k_debug_dump_soc_rin return retval; } -static const struct file_operations fops_soc_rx_stats = { - .read = ath11k_debug_dump_soc_rx_stats, +static const struct file_operations fops_soc_dp_stats = { + .read = ath11k_debug_dump_soc_dp_stats, .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, @@ -1144,8 +1154,8 @@ int ath11k_debug_pdev_create(struct ath1 debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, &fops_simulate_fw_crash); - debugfs_create_file("soc_rx_stats", 0600, ab->debugfs_soc, ab, - &fops_soc_rx_stats); + debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab, + &fops_soc_dp_stats); return 0; } --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c @@ -125,9 +125,10 @@ tcl_ring_sel: spin_unlock_bh(&tx_ring->tx_idr_lock); if (ret < 0) { - if (ring_map == (BIT(DP_TCL_NUM_RING_MAX) - 1)) + if (ring_map == (BIT(DP_TCL_NUM_RING_MAX) - 1)) { + atomic_inc(&ab->soc_stats.tx_err.misc_fail); return -ENOSPC; - + } /* Check if the next ring is available */ ring_selector++; goto tcl_ring_sel; @@ -181,6 +182,7 @@ tcl_ring_sel: break; case HAL_TCL_ENCAP_TYPE_RAW: if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { + atomic_inc(&ab->soc_stats.tx_err.misc_fail); ret = -EINVAL; goto fail_remove_idr; } @@ -190,13 +192,15 @@ tcl_ring_sel: break; case HAL_TCL_ENCAP_TYPE_802_3: /* TODO: Take care of other encap modes as well */ + atomic_inc(&ab->soc_stats.tx_err.misc_fail); ret = -EINVAL; goto fail_remove_idr; } ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); if (dma_mapping_error(ab->dev, ti.paddr)) { - ath11k_warn(ab, "failed to DMA map data Tx buffer\n"); + atomic_inc(&ab->soc_stats.tx_err.misc_fail); + ath11k_dbg(ab, ATH11K_DBG_DP_TX, "failed to DMA map data Tx buffer\n"); ret = -ENOMEM; goto fail_remove_idr; } @@ -219,6 +223,7 @@ tcl_ring_sel: * desc because the desc is directly enqueued onto hw queue. */ ath11k_hal_srng_access_end(ab, tcl_ring); + ab->soc_stats.tx_err.desc_na[ti.ring_id]++; spin_unlock_bh(&tcl_ring->lock); ret = -ENOMEM; --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -4625,7 +4625,7 @@ static void ath11k_mac_op_tx(struct ieee ret = ath11k_dp_tx(ar, arvif, skb); if (ret) { - ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret); + ath11k_dbg(ar->ab, ATH11K_DBG_DP_TX, "failed to transmit frame %d\n", ret); ieee80211_free_txskb(ar->hw, skb); } }