From: Ben Greear <gree...@candelatech.com>

The firmware does not offer tx/rx bytes counters, so just keep track of
it in the driver.

For the cycle counters:

Note these counters are since the chip reset, though the counters
wrap often.  When cycle-counters counter overflows on
certain hardware, it will right shift all 4 of the
related registers to the right by one bit (basically,
divide by two).  Since you have no idea what the others
were at when cycle-counter wrapped, you must simply
ignore any sample where cycle-counter wraps, and set
new baseline values to calculate diffs against next
time.

Hardware with this funny wrap logic will cause the
d_flags 'counter' to have bit 0x1 set, so that is how
user-space can know how to deal with this.

Signed-off-by: Ben Greear <gree...@candelatech.com>
---
 drivers/net/wireless/ath/ath10k/core.h   |  3 +++
 drivers/net/wireless/ath/ath10k/debug.c  | 22 +++++++++++++++++-----
 drivers/net/wireless/ath/ath10k/htt_rx.c |  3 +++
 drivers/net/wireless/ath/ath10k/htt_tx.c | 22 +++++++++++++++++-----
 4 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index c4f649f..1a75e2e 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -466,6 +466,9 @@ struct ath10k_debug {
        struct ath10k_dbglog_entry_storage dbglog_entry_data;
 
        struct ath10k_fw_crash_data *fw_crash_data;
+
+       u64 tx_bytes; /* counter, firmware does not offer this stat */
+       u64 rx_bytes; /* counter, firmware does not offer this stat */
 };
 
 enum ath10k_state {
diff --git a/drivers/net/wireless/ath/ath10k/debug.c 
b/drivers/net/wireless/ath/ath10k/debug.c
index 54a2194..684a39d 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -1442,11 +1442,15 @@ exit:
 /* This generally cooresponds to the debugfs fw_stats file */
 static const char ath10k_gstrings_stats[][ETH_GSTRING_LEN] = {
        "tx_pkts_nic",
-       "tx_bytes_nic",
+       "tx_bytes_nic", /* from driver, firmware does not keep this stat. */
        "rx_pkts_nic",
-       "rx_bytes_nic",
+       "rx_bytes_nic", /* from driver, firmware does not keep this stat. */
        "d_noise_floor",
-       "d_cycle_count",
+       "d_cycle_count", /* this is duty cycle counter, basically channel-time. 
88MHz clock */
+       "d_tx_cycle_count", /* tx cycle count */
+       "d_rx_cycle_count", /* rx cycle count */
+       "d_busy_count", /* Total channel busy time cycles (called 'clear' by 
firmware) */
+       "d_flags", /* 0x1:  hw has shifted cycle-count wrap, see 
ath10k_hw_fill_survey_time */
        "d_phy_error",
        "d_rts_bad",
        "d_rts_good",
@@ -1518,6 +1522,7 @@ void ath10k_debug_get_et_stats(struct ieee80211_hw *hw,
        static const struct ath10k_fw_stats_pdev zero_stats = {};
        const struct ath10k_fw_stats_pdev *pdev_stats;
        int i = 0, ret;
+       u64 d_flags = 0;
 
        mutex_lock(&ar->conf_mutex);
 
@@ -1541,12 +1546,19 @@ void ath10k_debug_get_et_stats(struct ieee80211_hw *hw,
 
        spin_lock_bh(&ar->data_lock);
 
+       if (ar->hw_params.has_shifted_cc_wraparound)
+               d_flags |= 0x1;
+
        data[i++] = pdev_stats->hw_reaped; /* ppdu reaped */
-       data[i++] = 0; /* tx bytes */
+       data[i++] = ar->debug.tx_bytes;
        data[i++] = pdev_stats->htt_mpdus;
-       data[i++] = 0; /* rx bytes */
+       data[i++] = ar->debug.rx_bytes;
        data[i++] = pdev_stats->ch_noise_floor;
        data[i++] = pdev_stats->cycle_count;
+       data[i++] = pdev_stats->tx_frame_count;
+       data[i++] = pdev_stats->rx_frame_count;
+       data[i++] = pdev_stats->rx_clear_count; /* yes, this appears to 
actually be 'busy' count */
+       data[i++] = d_flags; /* give user-space a chance to decode cycle 
counters */
        data[i++] = pdev_stats->phy_err_count;
        data[i++] = pdev_stats->rts_bad;
        data[i++] = pdev_stats->rts_good;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index cc979a4..47da904 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -1379,6 +1379,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
 }
 
        skb_queue_walk(amsdu, msdu) {
+#ifdef CONFIG_ATH10K_DEBUGFS
+               ar->debug.rx_bytes += msdu->len;
+#endif
                ath10k_htt_rx_h_csum_offload(msdu);
                ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype,
                                        is_decrypted);
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c 
b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 6269c61..06ec995 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -769,6 +769,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct 
sk_buff *msdu)
        int len = 0;
        int msdu_id = -1;
        int res;
+       int skb_len;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
 
        len += sizeof(cmd->hdr);
@@ -795,7 +796,8 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct 
sk_buff *msdu)
                goto err_free_msdu_id;
        }
 
-       skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
+       skb_len = msdu->len;
+       skb_cb->paddr = dma_map_single(dev, msdu->data, skb_len,
                                       DMA_TO_DEVICE);
        res = dma_mapping_error(dev, skb_cb->paddr);
        if (res) {
@@ -809,16 +811,20 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct 
sk_buff *msdu)
 
        cmd->hdr.msg_type         = HTT_H2T_MSG_TYPE_MGMT_TX;
        cmd->mgmt_tx.msdu_paddr = __cpu_to_le32(ATH10K_SKB_CB(msdu)->paddr);
-       cmd->mgmt_tx.len        = __cpu_to_le32(msdu->len);
+       cmd->mgmt_tx.len        = __cpu_to_le32(skb_len);
        cmd->mgmt_tx.desc_id    = __cpu_to_le32(msdu_id);
        cmd->mgmt_tx.vdev_id    = __cpu_to_le32(vdev_id);
        memcpy(cmd->mgmt_tx.hdr, msdu->data,
-              min_t(int, msdu->len, HTT_MGMT_FRM_HDR_DOWNLOAD_LEN));
+              min_t(int, skb_len, HTT_MGMT_FRM_HDR_DOWNLOAD_LEN));
 
        res = ath10k_htc_send(&htt->ar->htc, htt->eid, txdesc);
        if (res)
                goto err_unmap_msdu;
 
+#ifdef CONFIG_ATH10K_DEBUGFS
+       ar->debug.tx_bytes += skb_len;
+#endif
+
        return 0;
 
 err_unmap_msdu:
@@ -852,6 +858,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum 
ath10k_hw_txrx_mode txmode,
        u8 flags0 = 0;
        u16 msdu_id, flags1 = 0;
        u16 freq = 0;
+       int skb_len;
        u32 frags_paddr = 0;
        u32 txbuf_paddr;
        struct htt_msdu_ext_desc *ext_desc = NULL;
@@ -990,13 +997,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum 
ath10k_hw_txrx_mode txmode,
                                __cpu_to_le32(HTT_INVALID_PEERID);
        }
 
+       skb_len = msdu->len;
        trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid);
        ath10k_dbg(ar, ATH10K_DBG_HTT,
                   "htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr 
%08x, msdu_paddr %08x vdev %hhu tid %hhu freq %hu\n",
-                  flags0, flags1, msdu->len, msdu_id, frags_paddr,
+                  flags0, flags1, skb_len, msdu_id, frags_paddr,
                   (u32)skb_cb->paddr, vdev_id, tid, freq);
        ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ",
-                       msdu->data, msdu->len);
+                       msdu->data, skb_len);
        trace_ath10k_tx_hdr(ar, msdu->data, msdu->len);
        trace_ath10k_tx_payload(ar, msdu->data, msdu->len);
 
@@ -1021,6 +1029,10 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum 
ath10k_hw_txrx_mode txmode,
        if (res)
                goto err_unmap_msdu;
 
+#ifdef CONFIG_ATH10K_DEBUGFS
+       ar->debug.tx_bytes += skb_len;
+#endif
+
        return 0;
 
 err_unmap_msdu:
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to