2018-08-06 15:21:34

by Anilkumar Kolli

[permalink] [raw]
Subject: [PATCH 0/4] Add support to dump tx stats histogram

This patch series adds support to dump per station tx stats histogram.

These stats can be enabled through ath10k/enable_extd_tx_stats debugfs entry,
enabling this may impact in cpu usage and throughput.

ath10k/enable_extd_tx_stats is disabled by default.

Tx histogram has Per station tx stats which includes,
- pkts/bytes transmitted at all possible rates(mcs/nss/bw/gi).
- ACK fails count
- ampdu bytes/pkts transmitted at all possible rates(mcs/nss/bw/gi).
- BA fails count
- tx duration

Tested on QCA9984/QCA4019/QCA988x
Firmware: 10.4-3.5.3-00057
10.2.4-1.0-00037

Example output format:
# cat /sys/kernel/debug/ieee80211/phy0/netdev\:wlan0/stations/8c\:
fd\:f0\:0a\:8c\:14/tx_stats

succ_pkts
VHT MCS packets
0 0 0 0 0 138 26 18 23 38747
HT MCS packets
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW packets (20,40,80,160 MHz)
41 337 38574 0
NSS packets (1x1,2x2,3x3,4x4)
38952 0 0 0
GI packets (LGI,SGI)
38 38914
legacy rate packets (1,2 ... Mbps)
0 0 0 0 68 0 0 0 0 0 0 0
succ_bytes
VHT MCS bytes
0 0 0 0 0 16407 3288 2360 2703 4651892
HT MCS bytes
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW bytes (20,40,80,160 MHz)
5163 40962 4630525 0
NSS bytes (1x1,2x2,3x3,4x4)
4676650 0 0 0
GI bytes (LGI,SGI)
4471 4672179
legacy rate bytes (1,2 ... Mbps)
0 0 0 0 3270 0 0 0 0 0 0 0
ampdu_pkts
VHT MCS packets
0 0 0 8 20 7872 34 21 33 39730
HT MCS packets
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW packets (20,40,80,160 MHz)
72 567 47079 0
NSS packets (1x1,2x2,3x3,4x4)
40035 7683 0 0
GI packets (LGI,SGI)
7698 40020
legacy rate packets (1,2 ... Mbps)
0 0 0 0 0 0 0 0 0 0 0 0

ampdu_bytes
VHT MCS bytes
0 0 0 896 2579 941417 4222 2666 3857 4774284
HT MCS bytes
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW bytes (20,40,80,160 MHz)
9262 70052 5650607 0
NSS bytes (1x1,2x2,3x3,4x4)
4811265 918656 0 0
GI bytes (LGI,SGI)
920650 4809271
legacy rate bytes (1,2 ... Mbps)
0 0 0 0 0 0 0 0 0 0 0 0
fail_pkts
VHT MCS packets
0 0 0 0 0 0 0 0 0 0
HT MCS packets
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW packets (20,40,80,160 MHz)
0 0 0 0
NSS packets (1x1,2x2,3x3,4x4)
0 0 0 0
GI packets (LGI,SGI)
0 0
legacy rate packets (1,2 ... Mbps)
0 0 0 0 0 0 0 0 0 0 0 0
fail_bytes
VHT MCS bytes
0 0 0 0 0 0 0 0 0 0
HT MCS bytes
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW bytes (20,40,80,160 MHz)
0 0 0 0
NSS bytes (1x1,2x2,3x3,4x4)
0 0 0 0
GI bytes (LGI,SGI)
0 0
legacy rate bytes (1,2 ... Mbps)
0 0 0 0 0 0 0 0 0 0 0 0
retry_pkts
VHT MCS packets
0 0 0 8 20 7734 8 3 10 983
HT MCS packets
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW packets (20,40,80,160 MHz)
31 230 8505 0
NSS packets (1x1,2x2,3x3,4x4)
1083 7683 0 0
GI packets (LGI,SGI)
7660 1106
legacy rate packets (1,2 ... Mbps)
0 0 0 0 0 0 0 0 0 0 0 0
retry_bytes
VHT MCS bytes
0 0 0 896 2579 925010 934 306 1154 122392
HT MCS bytes
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW bytes (20,40,80,160 MHz)
4099 29090 1020082 0
NSS bytes (1x1,2x2,3x3,4x4)
134615 918656 0 0
GI bytes (LGI,SGI)
916179 137092
legacy rate bytes (1,2 ... Mbps)
0 0 0 0 0 0 0 0 0 0 0 0
TX duration
6639098 usecs
BA fails
8610
ack fails
0

Anilkumar Kolli (4):
ath10k: get the legacy rate index to update the txrate
ath10k: add debugfs entry to enable extended tx stats
ath10k: add extended per sta tx statistics
ath10k: add debugfs support to dump per sta tx stats

drivers/net/wireless/ath/ath10k/core.h | 32 ++++++
drivers/net/wireless/ath/ath10k/debug.c | 62 +++++++++++-
drivers/net/wireless/ath/ath10k/debugfs_sta.c | 100 +++++++++++++++++++
drivers/net/wireless/ath/ath10k/htt_rx.c | 133 ++++++++++++++++++++++---
drivers/net/wireless/ath/ath10k/mac.c | 7 ++
drivers/net/wireless/ath/ath10k/wmi.h | 13 ++-
6 files changed, 328 insertions(+), 19 deletions(-)

--
1.7.9.5


2018-08-06 15:21:43

by Anilkumar Kolli

[permalink] [raw]
Subject: [PATCH 1/4] ath10k: get the legacy rate index to update the txrate table

Get the legacy rate index to update the pkts/bytes counter
against each possible tx rate.

Signed-off-by: Anilkumar Kolli <[email protected]>
---
drivers/net/wireless/ath/ath10k/htt_rx.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 4d1cd90d6d27..01eb4a7f4a69 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2488,7 +2488,7 @@ void ath10k_htt_htc_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
dev_kfree_skb_any(skb);
}

-static inline bool is_valid_legacy_rate(u8 rate)
+static inline int ath10k_get_legacy_rate_idx(struct ath10k *ar, u8 rate)
{
static const u8 legacy_rates[] = {1, 2, 5, 11, 6, 9, 12,
18, 24, 36, 48, 54};
@@ -2496,10 +2496,11 @@ static inline bool is_valid_legacy_rate(u8 rate)

for (i = 0; i < ARRAY_SIZE(legacy_rates); i++) {
if (rate == legacy_rates[i])
- return true;
+ return i;
}

- return false;
+ ath10k_warn(ar, "Invalid legacy rate %hhd peer stats", rate);
+ return -EINVAL;
}

static void
@@ -2508,7 +2509,7 @@ static inline bool is_valid_legacy_rate(u8 rate)
struct ath10k_per_peer_tx_stats *peer_stats)
{
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
- u8 rate = 0, sgi;
+ u8 rate = 0, rate_idx = 0, sgi;
struct rate_info txrate;

lockdep_assert_held(&ar->data_lock);
@@ -2536,17 +2537,12 @@ static inline bool is_valid_legacy_rate(u8 rate)
if (txrate.flags == WMI_RATE_PREAMBLE_CCK ||
txrate.flags == WMI_RATE_PREAMBLE_OFDM) {
rate = ATH10K_HW_LEGACY_RATE(peer_stats->ratecode);
-
- if (!is_valid_legacy_rate(rate)) {
- ath10k_warn(ar, "Invalid legacy rate %hhd peer stats",
- rate);
- return;
- }
-
/* This is hacky, FW sends CCK rate 5.5Mbps as 6 */
- rate *= 10;
- if (rate == 60 && txrate.flags == WMI_RATE_PREAMBLE_CCK)
- rate = rate - 5;
+ if (rate == 6 && txrate.flags == WMI_RATE_PREAMBLE_CCK)
+ rate = 5;
+ rate_idx = ath10k_get_legacy_rate_idx(ar, rate);
+ if (rate_idx < 0)
+ return;
arsta->txrate.legacy = rate;
} else if (txrate.flags == WMI_RATE_PREAMBLE_HT) {
arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
--
1.7.9.5

2018-08-31 16:07:01

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath10k: add extended per sta tx statistics support

Anilkumar Kolli <[email protected]> writes:

> This patch adds per station tx statistics support.
>
> Per station tx stats include
> - pkts/bytes transmitted at all possible rates(mcs/nss/bw/gi).
> - ACK fails count
> - ampdu bytes/pkts transmitted at all possible rates(mcs/nss/bw/gi).
> - BA fails count
>
> Tested on QCA9984/QCA4019/QCA988x
> Firmware: 10.4-3.5.3-00057
> 10.2.4-1.0-00037
>
> Signed-off-by: Anilkumar Kolli <[email protected]>

[...]

> --- a/drivers/net/wireless/ath/ath10k/wmi.h
> +++ b/drivers/net/wireless/ath/ath10k/wmi.h
> @@ -4958,10 +4958,15 @@ enum wmi_rate_preamble {
> #define ATH10K_HW_GI(flags) (((flags) >> 5) & 0x1)
> #define ATH10K_HW_RATECODE(rate, nss, preamble) \
> (((preamble) << 6) | ((nss) << 4) | (rate))
> -
> -#define VHT_MCS_NUM 10
> -#define VHT_BW_NUM 4
> -#define VHT_NSS_NUM 4
> +#define ATH10K_HW_AMPDU(flags) (flags & 0x1)
> +#define ATH10K_HW_BA_FAIL(flags) (((flags) >> 1) & 0x3)
> +
> +#define NUM_VHT_MCS 10
> +#define NUM_BW 4
> +#define NUM_NSS 4
> +#define NUM_LEGACY 12
> +#define NUM_GI 2
> +#define NUM_HT_MCS 32

Why are you renaming these to use NUM_ prefix? That looks odd to me,
usually the "NUM" is the last.

If changing something, you should add ATH10K_ prefix to missing defines.

--
Kalle Valo

2018-08-06 15:21:52

by Anilkumar Kolli

[permalink] [raw]
Subject: [PATCH 2/4] ath10k: add debugfs entry to enable extended tx stats

This patch adds debugfs entry to enable/disable extended
tx statistics. Extended tx statistics are from peer stats
feature.

Signed-off-by: Anilkumar Kolli <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 +
drivers/net/wireless/ath/ath10k/debug.c | 62 ++++++++++++++++++++++++++++++-
2 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 9feea02e7d37..b5f6940bb102 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -607,6 +607,7 @@ struct ath10k_debug {
u32 reg_addr;
u32 nf_cal_period;
void *cal_data;
+ u32 enable_extd_tx_stats;
};

enum ath10k_state {
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 0baaad90b8d1..ada29a4cc9c8 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -2042,6 +2042,61 @@ static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf,
.open = simple_open
};

+static ssize_t ath10k_write_enable_extd_tx_stats(struct file *file,
+ const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath10k *ar = file->private_data;
+ u32 filter;
+ int ret;
+
+ if (kstrtouint_from_user(ubuf, count, 0, &filter))
+ return -EINVAL;
+
+ mutex_lock(&ar->conf_mutex);
+
+ if (ar->state != ATH10K_STATE_ON) {
+ ar->debug.enable_extd_tx_stats = filter;
+ ret = count;
+ goto out;
+ }
+
+ if (filter == ar->debug.enable_extd_tx_stats) {
+ ret = count;
+ goto out;
+ }
+
+ ar->debug.enable_extd_tx_stats = filter;
+ ret = count;
+
+out:
+ mutex_unlock(&ar->conf_mutex);
+ return ret;
+}
+
+static ssize_t ath10k_read_enable_extd_tx_stats(struct file *file,
+ char __user *ubuf,
+ size_t count, loff_t *ppos)
+
+{
+ char buf[32];
+ struct ath10k *ar = file->private_data;
+ int len = 0;
+
+ mutex_lock(&ar->conf_mutex);
+ len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
+ ar->debug.enable_extd_tx_stats);
+ mutex_unlock(&ar->conf_mutex);
+
+ return simple_read_from_buffer(ubuf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_enable_extd_tx_stats = {
+ .read = ath10k_read_enable_extd_tx_stats,
+ .write = ath10k_write_enable_extd_tx_stats,
+ .open = simple_open
+};
+
static ssize_t ath10k_write_peer_stats(struct file *file,
const char __user *ubuf,
size_t count, loff_t *ppos)
@@ -2454,10 +2509,15 @@ int ath10k_debug_register(struct ath10k *ar)
debugfs_create_file("btcoex", 0644, ar->debug.debugfs_phy, ar,
&fops_btcoex);

- if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map))
+ if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map)) {
debugfs_create_file("peer_stats", 0644, ar->debug.debugfs_phy, ar,
&fops_peer_stats);

+ debugfs_create_file("enable_extd_tx_stats", 0644,
+ ar->debug.debugfs_phy, ar,
+ &fops_enable_extd_tx_stats);
+ }
+
debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar,
&fops_fw_checksums);

--
1.7.9.5

2018-08-06 15:22:02

by Anilkumar Kolli

[permalink] [raw]
Subject: [PATCH 3/4] ath10k: add extended per sta tx statistics support

This patch adds per station tx statistics support.

Per station tx stats include
- pkts/bytes transmitted at all possible rates(mcs/nss/bw/gi).
- ACK fails count
- ampdu bytes/pkts transmitted at all possible rates(mcs/nss/bw/gi).
- BA fails count

Tested on QCA9984/QCA4019/QCA988x
Firmware: 10.4-3.5.3-00057
10.2.4-1.0-00037

Signed-off-by: Anilkumar Kolli <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 31 +++++++++
drivers/net/wireless/ath/ath10k/htt_rx.c | 109 ++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath10k/mac.c | 7 ++
drivers/net/wireless/ath/ath10k/wmi.h | 13 ++--
4 files changed, 156 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index b5f6940bb102..ee852e690382 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -461,6 +461,36 @@ struct ath10k_sta_tid_stats {
unsigned long int rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_MAX];
};

+enum ath10k_counter_type {
+ ATH10K_COUNTER_TYPE_BYTES,
+ ATH10K_COUNTER_TYPE_PKTS,
+ ATH10K_COUNTER_TYPE_MAX,
+};
+
+enum ath10k_stats_type {
+ ATH10K_STATS_TYPE_SUCC,
+ ATH10K_STATS_TYPE_FAIL,
+ ATH10K_STATS_TYPE_RETRY,
+ ATH10K_STATS_TYPE_AMPDU,
+ ATH10K_STATS_TYPE_MAX,
+};
+
+struct ath10k_htt_data_stats {
+ u64 legacy[ATH10K_COUNTER_TYPE_MAX][NUM_LEGACY];
+ u64 ht[ATH10K_COUNTER_TYPE_MAX][NUM_HT_MCS];
+ u64 vht[ATH10K_COUNTER_TYPE_MAX][NUM_VHT_MCS];
+ u64 bw[ATH10K_COUNTER_TYPE_MAX][NUM_BW];
+ u64 nss[ATH10K_COUNTER_TYPE_MAX][NUM_NSS];
+ u64 gi[ATH10K_COUNTER_TYPE_MAX][NUM_GI];
+};
+
+struct ath10k_htt_tx_stats {
+ struct ath10k_htt_data_stats stats[ATH10K_STATS_TYPE_MAX];
+ u64 tx_duration;
+ u64 ba_fails;
+ u64 ack_fails;
+};
+
struct ath10k_sta {
struct ath10k_vif *arvif;

@@ -474,6 +504,7 @@ struct ath10k_sta {

struct work_struct update_wk;
u64 rx_duration;
+ struct ath10k_htt_tx_stats *tx_stats;

#ifdef CONFIG_MAC80211_DEBUGFS
/* protected by conf_mutex */
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 01eb4a7f4a69..d634d08a0ea0 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2504,6 +2504,111 @@ static inline int ath10k_get_legacy_rate_idx(struct ath10k *ar, u8 rate)
}

static void
+ath10k_accumulate_per_peer_tx_stats(struct ath10k *ar,
+ struct ath10k_sta *arsta,
+ struct ath10k_per_peer_tx_stats *pstats,
+ u8 legacy_rate_idx)
+{
+ struct rate_info *txrate = &arsta->txrate;
+ struct ath10k_htt_tx_stats *tx_stats;
+ int ht_idx, gi, mcs, bw, nss;
+
+ if (!arsta->tx_stats)
+ return;
+
+ tx_stats = arsta->tx_stats;
+ gi = (arsta->txrate.flags & RATE_INFO_FLAGS_SHORT_GI);
+ ht_idx = txrate->mcs + txrate->nss * 8;
+ mcs = txrate->mcs;
+ bw = txrate->bw;
+ nss = txrate->nss;
+
+#define STATS_OP_FMT(name) tx_stats->stats[ATH10K_STATS_TYPE_##name]
+
+ if (txrate->flags == RATE_INFO_FLAGS_VHT_MCS) {
+ STATS_OP_FMT(SUCC).vht[0][mcs] += pstats->succ_bytes;
+ STATS_OP_FMT(SUCC).vht[1][mcs] += pstats->succ_pkts;
+ STATS_OP_FMT(FAIL).vht[0][mcs] += pstats->failed_bytes;
+ STATS_OP_FMT(FAIL).vht[1][mcs] += pstats->failed_pkts;
+ STATS_OP_FMT(RETRY).vht[0][mcs] += pstats->retry_bytes;
+ STATS_OP_FMT(RETRY).vht[1][mcs] += pstats->retry_pkts;
+ } else if (txrate->flags == RATE_INFO_FLAGS_MCS) {
+ STATS_OP_FMT(SUCC).ht[0][ht_idx] += pstats->succ_bytes;
+ STATS_OP_FMT(SUCC).ht[1][ht_idx] += pstats->succ_pkts;
+ STATS_OP_FMT(FAIL).ht[0][ht_idx] += pstats->failed_bytes;
+ STATS_OP_FMT(FAIL).ht[1][ht_idx] += pstats->failed_pkts;
+ STATS_OP_FMT(RETRY).ht[0][ht_idx] += pstats->retry_bytes;
+ STATS_OP_FMT(RETRY).ht[1][ht_idx] += pstats->retry_pkts;
+ } else {
+ mcs = legacy_rate_idx;
+ if (mcs < 0)
+ return;
+
+ STATS_OP_FMT(SUCC).legacy[0][mcs] += pstats->succ_bytes;
+ STATS_OP_FMT(SUCC).legacy[1][mcs] += pstats->succ_pkts;
+ STATS_OP_FMT(FAIL).legacy[0][mcs] += pstats->failed_bytes;
+ STATS_OP_FMT(FAIL).legacy[1][mcs] += pstats->failed_pkts;
+ STATS_OP_FMT(RETRY).legacy[0][mcs] += pstats->retry_bytes;
+ STATS_OP_FMT(RETRY).legacy[1][mcs] += pstats->retry_pkts;
+ }
+
+ if (ATH10K_HW_AMPDU(pstats->flags)) {
+ tx_stats->ba_fails += ATH10K_HW_BA_FAIL(pstats->flags);
+
+ if (txrate->flags == RATE_INFO_FLAGS_MCS) {
+ STATS_OP_FMT(AMPDU).ht[0][ht_idx] +=
+ pstats->succ_bytes + pstats->retry_bytes;
+ STATS_OP_FMT(AMPDU).ht[1][ht_idx] +=
+ pstats->succ_pkts + pstats->retry_pkts;
+ } else {
+ STATS_OP_FMT(AMPDU).vht[0][mcs] +=
+ pstats->succ_bytes + pstats->retry_bytes;
+ STATS_OP_FMT(AMPDU).vht[1][mcs] +=
+ pstats->succ_pkts + pstats->retry_pkts;
+ }
+ STATS_OP_FMT(AMPDU).bw[0][bw] +=
+ pstats->succ_bytes + pstats->retry_bytes;
+ STATS_OP_FMT(AMPDU).nss[0][nss] +=
+ pstats->succ_bytes + pstats->retry_bytes;
+ STATS_OP_FMT(AMPDU).gi[0][gi] +=
+ pstats->succ_bytes + pstats->retry_bytes;
+ STATS_OP_FMT(AMPDU).bw[1][bw] +=
+ pstats->succ_pkts + pstats->retry_pkts;
+ STATS_OP_FMT(AMPDU).nss[1][nss] +=
+ pstats->succ_pkts + pstats->retry_pkts;
+ STATS_OP_FMT(AMPDU).gi[1][gi] +=
+ pstats->succ_pkts + pstats->retry_pkts;
+ } else {
+ tx_stats->ack_fails +=
+ ATH10K_HW_BA_FAIL(pstats->flags);
+ }
+
+ STATS_OP_FMT(SUCC).bw[0][bw] += pstats->succ_bytes;
+ STATS_OP_FMT(SUCC).nss[0][nss] += pstats->succ_bytes;
+ STATS_OP_FMT(SUCC).gi[0][gi] += pstats->succ_bytes;
+
+ STATS_OP_FMT(SUCC).bw[1][bw] += pstats->succ_pkts;
+ STATS_OP_FMT(SUCC).nss[1][nss] += pstats->succ_pkts;
+ STATS_OP_FMT(SUCC).gi[1][gi] += pstats->succ_pkts;
+
+ STATS_OP_FMT(FAIL).bw[0][bw] += pstats->failed_bytes;
+ STATS_OP_FMT(FAIL).nss[0][nss] += pstats->failed_bytes;
+ STATS_OP_FMT(FAIL).gi[0][gi] += pstats->failed_bytes;
+
+ STATS_OP_FMT(FAIL).bw[1][bw] += pstats->failed_pkts;
+ STATS_OP_FMT(FAIL).nss[1][nss] += pstats->failed_pkts;
+ STATS_OP_FMT(FAIL).gi[1][gi] += pstats->failed_pkts;
+
+ STATS_OP_FMT(RETRY).bw[0][bw] += pstats->retry_bytes;
+ STATS_OP_FMT(RETRY).nss[0][nss] += pstats->retry_bytes;
+ STATS_OP_FMT(RETRY).gi[0][gi] += pstats->retry_bytes;
+
+ STATS_OP_FMT(RETRY).bw[1][bw] += pstats->retry_pkts;
+ STATS_OP_FMT(RETRY).nss[1][nss] += pstats->retry_pkts;
+ STATS_OP_FMT(RETRY).gi[1][gi] += pstats->retry_pkts;
+}
+
+static void
ath10k_update_per_peer_tx_stats(struct ath10k *ar,
struct ieee80211_sta *sta,
struct ath10k_per_peer_tx_stats *peer_stats)
@@ -2557,6 +2662,10 @@ static inline int ath10k_get_legacy_rate_idx(struct ath10k *ar, u8 rate)

arsta->txrate.nss = txrate.nss;
arsta->txrate.bw = ath10k_bw_to_mac80211_bw(txrate.bw);
+
+ if (ar->debug.enable_extd_tx_stats)
+ ath10k_accumulate_per_peer_tx_stats(ar, arsta, peer_stats,
+ rate_idx);
}

static void ath10k_htt_fetch_peer_stats(struct ath10k *ar,
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 90f9372dec25..fd42b32ead0b 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -6243,6 +6243,10 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
ar->num_stations + 1, ar->max_num_stations,
ar->num_peers + 1, ar->max_num_peers);

+ arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats), GFP_KERNEL);
+ if (!arsta->tx_stats)
+ goto exit;
+
num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);

@@ -6328,6 +6332,9 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
"mac vdev %d peer delete %pM sta %pK (sta gone)\n",
arvif->vdev_id, sta->addr, sta);

+ if (ar->debug.enable_extd_tx_stats)
+ kfree(arsta->tx_stats);
+
if (sta->tdls) {
ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id,
sta,
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 36220258e3c7..d057837ffadf 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4958,10 +4958,15 @@ enum wmi_rate_preamble {
#define ATH10K_HW_GI(flags) (((flags) >> 5) & 0x1)
#define ATH10K_HW_RATECODE(rate, nss, preamble) \
(((preamble) << 6) | ((nss) << 4) | (rate))
-
-#define VHT_MCS_NUM 10
-#define VHT_BW_NUM 4
-#define VHT_NSS_NUM 4
+#define ATH10K_HW_AMPDU(flags) (flags & 0x1)
+#define ATH10K_HW_BA_FAIL(flags) (((flags) >> 1) & 0x3)
+
+#define NUM_VHT_MCS 10
+#define NUM_BW 4
+#define NUM_NSS 4
+#define NUM_LEGACY 12
+#define NUM_GI 2
+#define NUM_HT_MCS 32

/* Value to disable fixed rate setting */
#define WMI_FIXED_RATE_NONE (0xff)
--
1.7.9.5

2018-08-28 17:28:22

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath10k: add debugfs support to dump per sta tx stats

Anilkumar Kolli <[email protected]> wrote:

> This patch adds 'tx_stats' in per station debugfs entry.
>
> Use this command to dump tx_stats:
> cat /sys/kernel/debug/ieee80211/phy0/netdev\:wlan0/
> stations/<MACADDR>/tx_stats
>
> Signed-off-by: Anilkumar Kolli <[email protected]>
> Signed-off-by: Kalle Valo <[email protected]>

kbuild bot found new warnings:

drivers/net/wireless/ath/ath10k/debugfs_sta.c: In function 'ath10k_dbg_sta_dump_tx_stats':
>> drivers/net/wireless/ath/ath10k/debugfs_sta.c:714:1: warning: the frame size of 1088 bytes is larger than 1024 bytes [-Wframe-larger-than=]
}
^

drivers/net/wireless/ath/ath10k/debugfs_sta.c: In function 'ath10k_sta_add_debugfs':
>> drivers/net/wireless/ath/ath10k/debugfs_sta.c:737:41: error: 'struct ath10k' has no member named 'debug'
if (ath10k_peer_stats_enabled(ar) && ar->debug.enable_extd_tx_stats)
^~

--
https://patchwork.kernel.org/patch/10557079/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2018-08-28 17:26:58

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath10k: add extended per sta tx statistics support

Anilkumar Kolli <[email protected]> wrote:

> This patch adds per station tx statistics support.
>
> Per station tx stats include
> - pkts/bytes transmitted at all possible rates(mcs/nss/bw/gi).
> - ACK fails count
> - ampdu bytes/pkts transmitted at all possible rates(mcs/nss/bw/gi).
> - BA fails count
>
> Tested on QCA9984/QCA4019/QCA988x
> Firmware: 10.4-3.5.3-00057
> 10.2.4-1.0-00037
>
> Signed-off-by: Anilkumar Kolli <[email protected]>
> Signed-off-by: Kalle Valo <[email protected]>

kbuild bot found a new warning:

drivers/net/wireless/ath/ath10k/mac.c: In function 'ath10k_sta_state':
>> drivers/net/wireless/ath/ath10k/mac.c:6335:9: error: 'struct ath10k' has no member named 'debug'
if (ar->debug.enable_extd_tx_stats)
^~

--
https://patchwork.kernel.org/patch/10557073/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2018-08-06 15:22:10

by Anilkumar Kolli

[permalink] [raw]
Subject: [PATCH 4/4] ath10k: add debugfs support to dump per sta tx stats

This patch adds 'tx_stats' in per station debugfs entry.

Use this command to dump tx_stats:
cat /sys/kernel/debug/ieee80211/phy0/netdev\:wlan0/
stations/<MACADDR>/tx_stats

Signed-off-by: Anilkumar Kolli <[email protected]>
---
drivers/net/wireless/ath/ath10k/debugfs_sta.c | 100 +++++++++++++++++++++++++
1 file changed, 100 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
index a63c97e2c50c..800eddd26af8 100644
--- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
@@ -626,9 +626,105 @@ static ssize_t ath10k_dbg_sta_read_tid_stats(struct file *file,
.llseek = default_llseek,
};

+static inline int ath10k_dump_htt_tx_stats(char *buf, int len, int size,
+ struct ath10k_htt_data_stats stats,
+ int type, const char *name)
+{
+ static const char *str[ATH10K_COUNTER_TYPE_MAX] = {
+ "bytes", "packets"};
+ int i;
+
+ len += scnprintf(buf + len, size - len, "%s_%s\n", name,
+ str[type]);
+ len += scnprintf(buf + len, size - len, " VHT MCS %s\n",
+ str[type]);
+ for (i = 0; i < NUM_VHT_MCS; i++)
+ len += scnprintf(buf + len, size - len, " %llu ",
+ stats.vht[type][i]);
+ len += scnprintf(buf + len, size - len, "\n");
+ len += scnprintf(buf + len, size - len, " HT MCS %s\n",
+ str[type]);
+ for (i = 0; i < NUM_HT_MCS; i++)
+ len += scnprintf(buf + len, size - len, " %llu ",
+ stats.ht[type][i]);
+ len += scnprintf(buf + len, size - len, "\n");
+ len += scnprintf(buf + len, size - len,
+ " BW %s (20,40,80,160 MHz)\n", str[type]);
+ len += scnprintf(buf + len, size - len, " %llu %llu %llu %llu\n",
+ stats.bw[type][0], stats.bw[type][1],
+ stats.bw[type][2], stats.bw[type][3]);
+ len += scnprintf(buf + len, size - len,
+ " NSS %s (1x1,2x2,3x3,4x4)\n", str[type]);
+ len += scnprintf(buf + len, size - len, " %llu %llu %llu %llu\n",
+ stats.nss[type][0], stats.nss[type][1],
+ stats.nss[type][2], stats.nss[type][3]);
+ len += scnprintf(buf + len, size - len, " GI %s (LGI,SGI)\n",
+ str[type]);
+ len += scnprintf(buf + len, size - len, " %llu %llu\n",
+ stats.gi[type][0], stats.gi[type][1]);
+ len += scnprintf(buf + len, size - len,
+ " legacy rate %s (1,2 ... Mbps)\n ", str[type]);
+ for (i = 0; i < NUM_LEGACY; i++)
+ len += scnprintf(buf + len, size - len, "%llu ",
+ stats.legacy[type][i]);
+ len += scnprintf(buf + len, size - len, "\n");
+
+ return len;
+}
+
+static ssize_t ath10k_dbg_sta_dump_tx_stats(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_sta *sta = file->private_data;
+ struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
+ struct ath10k *ar = arsta->arvif->ar;
+ char *buf;
+ static const char *str_name[ATH10K_STATS_TYPE_MAX] = {
+ "succ", "fail", "retry", "ampdu"};
+ int len = 0, i, j, retval = 0, size = 2 * 1024;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ mutex_lock(&ar->conf_mutex);
+
+ for (i = 0; i < ATH10K_STATS_TYPE_MAX; i++)
+ for (j = 0; j < ATH10K_COUNTER_TYPE_MAX; j++)
+ len = ath10k_dump_htt_tx_stats(buf, len, size,
+ arsta->tx_stats->stats[i],
+ j, str_name[i]);
+
+ len += scnprintf(buf + len, size - len,
+ "\nTX duration\n %llu usecs\n",
+ arsta->tx_stats->tx_duration);
+ len += scnprintf(buf + len, size - len,
+ "BA fails\n %llu\n", arsta->tx_stats->ba_fails);
+ len += scnprintf(buf + len, size - len,
+ "ack fails\n %llu\n", arsta->tx_stats->ack_fails);
+
+ if (len > size)
+ len = size;
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ mutex_unlock(&ar->conf_mutex);
+ return retval;
+}
+
+static const struct file_operations fops_tx_stats = {
+ .read = ath10k_dbg_sta_dump_tx_stats,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct dentry *dir)
{
+ struct ath10k *ar = hw->priv;
+
debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode);
debugfs_create_file("addba", 0200, dir, sta, &fops_addba);
debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp);
@@ -637,4 +733,8 @@ void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
&fops_peer_debug_trigger);
debugfs_create_file("dump_tid_stats", 0400, dir, sta,
&fops_tid_stats_dump);
+
+ if (ath10k_peer_stats_enabled(ar) && ar->debug.enable_extd_tx_stats)
+ debugfs_create_file("tx_stats", 0400, dir, sta,
+ &fops_tx_stats);
}
--
1.7.9.5

2018-09-04 13:18:16

by Anilkumar Kolli

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath10k: add debugfs support to dump per sta tx stats

On 2018-08-28 19:06, Kalle Valo wrote:
> Anilkumar Kolli <[email protected]> wrote:
>
>> This patch adds 'tx_stats' in per station debugfs entry.
>>
>> Use this command to dump tx_stats:
>> cat /sys/kernel/debug/ieee80211/phy0/netdev\:wlan0/
>> stations/<MACADDR>/tx_stats
>>
>> Signed-off-by: Anilkumar Kolli <[email protected]>
>> Signed-off-by: Kalle Valo <[email protected]>
>
> kbuild bot found new warnings:
>
> drivers/net/wireless/ath/ath10k/debugfs_sta.c: In function
> 'ath10k_dbg_sta_dump_tx_stats':
>>> drivers/net/wireless/ath/ath10k/debugfs_sta.c:714:1: warning: the
>>> frame size of 1088 bytes is larger than 1024 bytes
>>> [-Wframe-larger-than=]
> }
> ^
>
> drivers/net/wireless/ath/ath10k/debugfs_sta.c: In function
> 'ath10k_sta_add_debugfs':
>>> drivers/net/wireless/ath/ath10k/debugfs_sta.c:737:41: error: 'struct
>>> ath10k' has no member named 'debug'
> if (ath10k_peer_stats_enabled(ar) &&
> ar->debug.enable_extd_tx_stats)
> ^~

Please drop this patch series, I sent V2 addressing these issues.

Thanks
Anil.