All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH-v2 1/6] mac80211:  Fix station rx-packets counters.
@ 2021-03-24 18:14 greearb
  2021-03-24 18:14 ` [PATCH-v2 2/6] mac80211: Provide per-station stats in debugfs greearb
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: greearb @ 2021-03-24 18:14 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

I noticed 'iw dev wlan6 station dump' showed almost no rx-packets
one one of my radios.  The rx-amsdu path did not appear to gather
any stats, and after code inspection, neither did the rx-data
handler.

Add common method to deal with these stats.  Verified in AX
and /a mode, stats look at least generally correct now.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 net/mac80211/rx.c | 54 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 17 deletions(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index eb8225209005..4a64c2183a27 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1713,6 +1713,27 @@ ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
 	return RX_CONTINUE;
 }
 
+static void ieee80211_update_data_rx_stats(struct ieee80211_rx_data *rx,
+					   struct ieee80211_sta_rx_stats *stats,
+					   struct ieee80211_rx_status *status,
+					   int skb_len)
+{
+	stats->fragments++;
+	stats->packets++;
+	stats->last_rx = jiffies;
+	stats->last_rate = sta_stats_encode_rate(status);
+
+	/* The seqno index has the same property as needed
+	 * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
+	 * for non-QoS-data frames. Here we know it's a data
+	 * frame, so count MSDUs.
+	 */
+	u64_stats_update_begin(&stats->syncp);
+	stats->msdu[rx->seqno_idx]++;
+	stats->bytes += skb_len;
+	u64_stats_update_end(&stats->syncp);
+}
+
 static ieee80211_rx_result debug_noinline
 ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 {
@@ -2706,6 +2727,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	__le16 fc = hdr->frame_control;
+	ieee80211_rx_result rv;
+	int orig_len = skb->len;
 
 	if (!(status->rx_flags & IEEE80211_RX_AMSDU))
 		return RX_CONTINUE;
@@ -2734,7 +2757,12 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
 	if (is_multicast_ether_addr(hdr->addr1))
 		return RX_DROP_UNUSABLE;
 
-	return __ieee80211_rx_h_amsdu(rx, 0);
+	rv = __ieee80211_rx_h_amsdu(rx, 0);
+	if ((rv == RX_QUEUED) && (rx->sta)) {
+		struct ieee80211_sta_rx_stats *stats = &rx->sta->rx_stats;
+		ieee80211_update_data_rx_stats(rx, stats, status, orig_len);
+	}
+	return rv;
 }
 
 #ifdef CONFIG_MAC80211_MESH
@@ -2958,6 +2986,13 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
 		mod_timer(&local->dynamic_ps_timer, jiffies +
 			  msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
 
+	
+	if (rx->sta) {
+		struct ieee80211_sta_rx_stats *stats = &rx->sta->rx_stats;
+		struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+		ieee80211_update_data_rx_stats(rx, stats, status, rx->skb->len);
+	}
+
 	ieee80211_deliver_skb(rx);
 
 	return RX_QUEUED;
@@ -4400,12 +4435,6 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
 		return true;
 	}
 
-	stats->last_rx = jiffies;
-	stats->last_rate = sta_stats_encode_rate(status);
-
-	stats->fragments++;
-	stats->packets++;
-
 	/* do the header conversion - first grab the addresses */
 	ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs);
 	ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs);
@@ -4416,18 +4445,9 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
 
 	skb->dev = fast_rx->dev;
 
+	ieee80211_update_data_rx_stats(rx, stats, status, orig_len);
 	dev_sw_netstats_rx_add(fast_rx->dev, skb->len);
 
-	/* The seqno index has the same property as needed
-	 * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
-	 * for non-QoS-data frames. Here we know it's a data
-	 * frame, so count MSDUs.
-	 */
-	u64_stats_update_begin(&stats->syncp);
-	stats->msdu[rx->seqno_idx]++;
-	stats->bytes += orig_len;
-	u64_stats_update_end(&stats->syncp);
-
 	if (fast_rx->internal_forward) {
 		struct sk_buff *xmit_skb = NULL;
 		if (is_multicast_ether_addr(addrs.da)) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH-v2 2/6] mac80211:  Provide per-station stats in debugfs
  2021-03-24 18:14 [PATCH-v2 1/6] mac80211: Fix station rx-packets counters greearb
@ 2021-03-24 18:14 ` greearb
  2021-03-24 18:14 ` [PATCH-v2 3/6] mac80211: Provide detailed station rx stats greearb
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: greearb @ 2021-03-24 18:14 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

Including per tid and per acs stats.

Nice for those who like to peer deep into the guts of a system.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 net/mac80211/debugfs_sta.c | 88 ++++++++++++++++++++++++++++++++++++++
 net/mac80211/sta_info.c    | 33 ++++++++++++++
 net/mac80211/sta_info.h    |  4 ++
 3 files changed, 125 insertions(+)

diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 1deacce85177..374db61527a9 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -102,6 +102,93 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
 }
 STA_OPS(flags);
 
+static ssize_t sta_stats_read(struct file *file, char __user *userbuf,
+			      size_t count, loff_t *ppos)
+{
+	struct sta_info *sta = file->private_data;
+	unsigned int len = 0;
+	const int buf_len = 8000;
+	char *buf = kzalloc(buf_len, GFP_KERNEL);
+	unsigned long sum;
+	char tmp[60];
+	int i;
+	struct ieee80211_sta_rx_stats rx_stats = {0};
+
+	if (!buf)
+		return -ENOMEM;
+
+	sta_accum_rx_stats(sta, &rx_stats);
+
+#define PRINT_MY_STATS(a, b) do {					\
+		len += scnprintf(buf + len, buf_len - len, "%30s %18lu\n", a, (unsigned long)(b)); \
+		if (len >= buf_len) {					\
+			goto done;					\
+		}							\
+	} while (0)
+
+#define PRINT_MY_STATS_S(a, b) do {					\
+		len += scnprintf(buf + len, buf_len - len, "%30s %18ld\n", a, (long)(b)); \
+		if (len >= buf_len) {					\
+			goto done;					\
+		}							\
+	} while (0)
+
+	PRINT_MY_STATS("rx-packets", rx_stats.packets);
+	PRINT_MY_STATS("rx-bytes", rx_stats.bytes);
+	PRINT_MY_STATS("rx-dup", rx_stats.num_duplicates);
+	PRINT_MY_STATS("rx-fragments", rx_stats.fragments);
+	PRINT_MY_STATS("rx-dropped", rx_stats.dropped);
+	PRINT_MY_STATS_S("rx-last-signal", rx_stats.last_signal);
+
+	for (i = 0; i<IEEE80211_MAX_CHAINS; i++) {
+		if (rx_stats.chains & (1<<i)) {
+			sprintf(tmp, "rx-last-signal-chain[%i]", i);
+			PRINT_MY_STATS_S(tmp, rx_stats.chain_signal_last[i]);
+		}
+	}
+	PRINT_MY_STATS("rx-last-rate-encoded", rx_stats.last_rate);
+
+	len += scnprintf(buf + len, buf_len - len, "\n");
+
+	sum = sta->tx_stats.packets[0] + sta->tx_stats.packets[1]
+		+ sta->tx_stats.packets[2] + sta->tx_stats.packets[3];
+	PRINT_MY_STATS("tx-packets", sum);
+
+		sum = sta->tx_stats.bytes[0] + sta->tx_stats.bytes[1]
+		+ sta->tx_stats.bytes[2] + sta->tx_stats.bytes[3];
+	PRINT_MY_STATS("tx-bytes", sum);
+
+	/* per txq stats */
+	PRINT_MY_STATS("tx-packets-acs[VO]", sta->tx_stats.packets[IEEE80211_AC_VO]);
+	PRINT_MY_STATS("tx-packets-acs[VI]", sta->tx_stats.packets[IEEE80211_AC_VI]);
+	PRINT_MY_STATS("tx-packets-acs[BE]", sta->tx_stats.packets[IEEE80211_AC_BE]);
+	PRINT_MY_STATS("tx-packets-acs[BK]", sta->tx_stats.packets[IEEE80211_AC_BK]);
+
+	PRINT_MY_STATS("tx-bytes-acs[VO]", sta->tx_stats.bytes[IEEE80211_AC_VO]);
+	PRINT_MY_STATS("tx-bytes-acs[VI]", sta->tx_stats.bytes[IEEE80211_AC_VI]);
+	PRINT_MY_STATS("tx-bytes-acs[BE]", sta->tx_stats.bytes[IEEE80211_AC_BE]);
+	PRINT_MY_STATS("tx-bytes-acs[BK]", sta->tx_stats.bytes[IEEE80211_AC_BK]);
+
+	len += scnprintf(buf + len, buf_len - len, "\n");
+	for (i = 0; i<=IEEE80211_NUM_TIDS; i++) {
+		sprintf(tmp, "tx-msdu-tid[%2i]", i);
+		PRINT_MY_STATS(tmp, sta->tx_stats.msdu[i]);
+	}
+
+	len += scnprintf(buf + len, buf_len - len, "\n");
+	for (i = 0; i<=IEEE80211_NUM_TIDS; i++) {
+		sprintf(tmp, "rx-msdu-tid[%2i]", i);
+		PRINT_MY_STATS(tmp, rx_stats.msdu[i]);
+	}
+
+#undef PRINT_MY_STATS
+done:
+	i = simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
+	kfree(buf);
+	return i;
+}
+STA_OPS(stats);
+
 static ssize_t sta_num_ps_buf_frames_read(struct file *file,
 					  char __user *userbuf,
 					  size_t count, loff_t *ppos)
@@ -1073,6 +1160,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
 	sta->debugfs_dir = debugfs_create_dir(mac, stations_dir);
 
 	DEBUGFS_ADD(flags);
+	DEBUGFS_ADD(stats);
 	DEBUGFS_ADD(aid);
 	DEBUGFS_ADD(num_ps_buf_frames);
 	DEBUGFS_ADD(last_seq_ctrl);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index b096370b45b1..aa95db547465 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2650,6 +2650,39 @@ static void sta_update_codel_params(struct sta_info *sta, u32 thr)
 	}
 }
 
+void sta_accum_rx_stats(struct sta_info *sta,
+			struct ieee80211_sta_rx_stats *rx_stats)
+{
+	int cpu;
+	int i;
+
+	memcpy(rx_stats, &sta->rx_stats, sizeof(*rx_stats));
+
+	if (!sta->pcpu_rx_stats)
+		return;
+
+	for_each_possible_cpu(cpu) {
+		struct ieee80211_sta_rx_stats *cpurxs;
+
+		cpurxs = per_cpu_ptr(sta->pcpu_rx_stats, cpu);
+		rx_stats->packets += cpurxs->packets;
+		if (time_after(cpurxs->last_rx, rx_stats->last_rx)) {
+			rx_stats->last_rx = cpurxs->last_rx;
+			rx_stats->last_signal = cpurxs->last_signal;
+			for (i = 0; i<IEEE80211_MAX_CHAINS; i++)
+				rx_stats->chain_signal_last[i] = cpurxs->chain_signal_last[i];
+			rx_stats->last_rate = cpurxs->last_rate;
+		}
+		rx_stats->num_duplicates += cpurxs->num_duplicates;
+		rx_stats->fragments += cpurxs->fragments;
+		rx_stats->dropped += cpurxs->dropped;
+		rx_stats->bytes += sta_get_stats_bytes(cpurxs);
+		for (i = 0; i<=IEEE80211_NUM_TIDS; i++) {
+			rx_stats->msdu[i] += sta_get_tidstats_msdu(cpurxs, i);
+		}
+	}
+}
+
 void ieee80211_sta_set_expected_throughput(struct ieee80211_sta *pubsta,
 					   u32 thr)
 {
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 897b4d12103e..a6b13d749ffa 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -422,6 +422,7 @@ struct mesh_sta {
 
 DECLARE_EWMA(signal, 10, 8)
 
+/* Update sta_accum_rx_stats if you change this structure. */
 struct ieee80211_sta_rx_stats {
 	unsigned long packets;
 	unsigned long last_rx;
@@ -907,4 +908,7 @@ static inline u32 sta_stats_encode_rate(struct ieee80211_rx_status *s)
 	return r;
 }
 
+void sta_accum_rx_stats(struct sta_info *sta,
+			struct ieee80211_sta_rx_stats *rx_stats);
+
 #endif /* STA_INFO_H */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH-v2 3/6] mac80211:  Provide detailed station rx stats.
  2021-03-24 18:14 [PATCH-v2 1/6] mac80211: Fix station rx-packets counters greearb
  2021-03-24 18:14 ` [PATCH-v2 2/6] mac80211: Provide per-station stats in debugfs greearb
@ 2021-03-24 18:14 ` greearb
  2021-03-24 18:14 ` [PATCH-v2 4/6] mac80211: Add counters for specific HE encoding types greearb
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: greearb @ 2021-03-24 18:14 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

This provides histograms of different encoding types,
nss, rate-idx, and some ofdma related stats.  The goal
is general visibility into what is going on with rate
control, ofdma, etc.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 include/uapi/linux/nl80211.h |  1 +
 net/mac80211/Kconfig         | 11 ++++++++
 net/mac80211/debugfs_sta.c   | 30 ++++++++++++++++++++
 net/mac80211/rx.c            | 55 ++++++++++++++++++++++++++++++++++++
 net/mac80211/sta_info.c      | 16 +++++++++++
 net/mac80211/sta_info.h      | 17 +++++++++++
 6 files changed, 130 insertions(+)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 55e7be30a930..8f548a599134 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3269,6 +3269,7 @@ enum nl80211_he_ru_alloc {
 	NL80211_RATE_INFO_HE_RU_ALLOC_484,
 	NL80211_RATE_INFO_HE_RU_ALLOC_996,
 	NL80211_RATE_INFO_HE_RU_ALLOC_2x996,
+	NL80211_RATE_INFO_HE_RU_ALLOC_LAST /* new entries before this */
 };
 
 /**
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 51ec8256b7fa..b0ebb64b3950 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -295,6 +295,17 @@ config MAC80211_DEBUG_COUNTERS
 
 	  If unsure, say N.
 
+config MAC80211_DEBUG_STA_COUNTERS
+	bool "Extra Station TX/RX statistics"
+	depends on MAC80211_DEBUG_MENU
+	depends on MAC80211_DEBUGFS
+	help
+	  Selecting this option causes mac80211 to keep additional
+	  and very verbose station-specific TX and RX statistics
+	  These will be exposed in debugfs.
+
+	  If unsure, say N.
+
 config MAC80211_STA_HASH_MAX_SIZE
 	int "Station hash table maximum size" if MAC80211_DEBUG_MENU
 	default 0
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 374db61527a9..f29e937aec5c 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -181,6 +181,36 @@ static ssize_t sta_stats_read(struct file *file, char __user *userbuf,
 		PRINT_MY_STATS(tmp, rx_stats.msdu[i]);
 	}
 
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+	PRINT_MY_STATS("rx-bw-20", rx_stats.msdu_20);
+	PRINT_MY_STATS("rx-bw-40", rx_stats.msdu_40);
+	PRINT_MY_STATS("rx-bw-80", rx_stats.msdu_80);
+	PRINT_MY_STATS("rx-bw-160", rx_stats.msdu_160);
+
+	PRINT_MY_STATS("rx-he-total", rx_stats.msdu_he_tot);
+	PRINT_MY_STATS("rx-vht", rx_stats.msdu_vht);
+	PRINT_MY_STATS("rx-ht", rx_stats.msdu_ht);
+	PRINT_MY_STATS("rx-legacy", rx_stats.msdu_legacy);
+
+	PRINT_MY_STATS("rx-he-ru-alloc[   26]", rx_stats.msdu_he_ru_alloc[NL80211_RATE_INFO_HE_RU_ALLOC_26]);
+	PRINT_MY_STATS("rx-he-ru-alloc[   52]", rx_stats.msdu_he_ru_alloc[NL80211_RATE_INFO_HE_RU_ALLOC_52]);
+	PRINT_MY_STATS("rx-he-ru-alloc[  106]", rx_stats.msdu_he_ru_alloc[NL80211_RATE_INFO_HE_RU_ALLOC_106]);
+	PRINT_MY_STATS("rx-he-ru-alloc[  242]", rx_stats.msdu_he_ru_alloc[NL80211_RATE_INFO_HE_RU_ALLOC_242]);
+	PRINT_MY_STATS("rx-he-ru-alloc[  484]", rx_stats.msdu_he_ru_alloc[NL80211_RATE_INFO_HE_RU_ALLOC_484]);
+	PRINT_MY_STATS("rx-he-ru-alloc[  996]", rx_stats.msdu_he_ru_alloc[NL80211_RATE_INFO_HE_RU_ALLOC_996]);
+	PRINT_MY_STATS("rx-he-ru-alloc[2x996]", rx_stats.msdu_he_ru_alloc[NL80211_RATE_INFO_HE_RU_ALLOC_2x996]);
+
+	for (i = 0; i < ARRAY_SIZE(rx_stats.msdu_nss); i++) {
+		sprintf(tmp, "rx-msdu-nss[%i]", i);
+		PRINT_MY_STATS(tmp, rx_stats.msdu_nss[i]);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(rx_stats.msdu_rate_idx); i++) {
+		sprintf(tmp, "rx-rate-idx[%3i]", i);
+		PRINT_MY_STATS(tmp, rx_stats.msdu_rate_idx[i]);
+	}
+#endif
+
 #undef PRINT_MY_STATS
 done:
 	i = simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 4a64c2183a27..01117e2d1f27 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1718,6 +1718,11 @@ static void ieee80211_update_data_rx_stats(struct ieee80211_rx_data *rx,
 					   struct ieee80211_rx_status *status,
 					   int skb_len)
 {
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+	u8 nss;
+	u8 rix;
+#endif
+
 	stats->fragments++;
 	stats->packets++;
 	stats->last_rx = jiffies;
@@ -1732,6 +1737,56 @@ static void ieee80211_update_data_rx_stats(struct ieee80211_rx_data *rx,
 	stats->msdu[rx->seqno_idx]++;
 	stats->bytes += skb_len;
 	u64_stats_update_end(&stats->syncp);
+
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+	/* This code has a lot in common with ieee80211_add_rx_radiotap_header */
+	switch (status->bw) {
+	case RATE_INFO_BW_20:
+		stats->msdu_20++;
+		break;
+	case RATE_INFO_BW_40:
+		stats->msdu_40++;
+		break;
+	case RATE_INFO_BW_80:
+		stats->msdu_80++;
+		break;
+	case RATE_INFO_BW_160:
+		stats->msdu_160++;
+		break;
+	case RATE_INFO_BW_HE_RU:
+		stats->msdu_he_ru_alloc[status->he_ru]++;
+		break;
+	};
+
+	nss = status->nss - 1;
+	rix = status->rate_idx;
+
+	if (status->encoding == RX_ENC_HE) {
+		stats->msdu_he_tot++;
+	}
+	else if (status->encoding == RX_ENC_VHT) {
+		stats->msdu_vht++;
+	}
+	else if (status->encoding == RX_ENC_HT) {
+		stats->msdu_ht++;
+		/* Convert HT MCS to mimic what is done for VHT */
+		nss = status->rate_idx / 8;
+		rix = status->rate_idx - (status->rate_idx * 8);
+	}
+	else {
+		stats->msdu_legacy++;
+	}
+
+	if (nss >= (ARRAY_SIZE(stats->msdu_nss) - 1))
+		stats->msdu_nss[ARRAY_SIZE(stats->msdu_nss) - 1]++;
+	else
+		stats->msdu_nss[nss]++;
+
+	if (rix >= (ARRAY_SIZE(stats->msdu_rate_idx) - 1))
+		stats->msdu_rate_idx[ARRAY_SIZE(stats->msdu_rate_idx) - 1]++;
+	else
+		stats->msdu_rate_idx[rix]++;
+#endif
 }
 
 static ieee80211_rx_result debug_noinline
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index aa95db547465..765993802fec 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2680,6 +2680,22 @@ void sta_accum_rx_stats(struct sta_info *sta,
 		for (i = 0; i<=IEEE80211_NUM_TIDS; i++) {
 			rx_stats->msdu[i] += sta_get_tidstats_msdu(cpurxs, i);
 		}
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+		rx_stats->msdu_20 += cpurxs->msdu_20;
+		rx_stats->msdu_40 += cpurxs->msdu_40;
+		rx_stats->msdu_80 += cpurxs->msdu_80;
+		rx_stats->msdu_160 += cpurxs->msdu_160;
+		for (i = 0; i<NL80211_RATE_INFO_HE_RU_ALLOC_LAST; i++)
+			rx_stats->msdu_he_ru_alloc[i] += cpurxs->msdu_he_ru_alloc[i];
+		rx_stats->msdu_he_tot += cpurxs->msdu_he_tot;
+		rx_stats->msdu_vht += cpurxs->msdu_vht;
+		rx_stats->msdu_ht += cpurxs->msdu_ht;
+		rx_stats->msdu_legacy += cpurxs->msdu_legacy;
+		for (i = 0; i < ARRAY_SIZE(rx_stats->msdu_nss); i++)
+			rx_stats->msdu_nss[i] += cpurxs->msdu_nss[i];
+		for (i = 0; i < ARRAY_SIZE(rx_stats->msdu_rate_idx); i++)
+			rx_stats->msdu_rate_idx[i] += cpurxs->msdu_rate_idx[i];
+#endif
 	}
 }
 
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index a6b13d749ffa..e205a8a06ae7 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -436,6 +436,23 @@ struct ieee80211_sta_rx_stats {
 	struct u64_stats_sync syncp;
 	u64 bytes;
 	u64 msdu[IEEE80211_NUM_TIDS + 1];
+
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+	/* these take liberty with how things are defined, and are
+	 * designed to give a rough idea of how things are going.
+	 */
+	u32 msdu_20;
+	u32 msdu_40;
+	u32 msdu_80;
+	u32 msdu_160;
+	u32 msdu_he_ru_alloc[NL80211_RATE_INFO_HE_RU_ALLOC_LAST];
+	u32 msdu_he_tot;
+	u32 msdu_vht;
+	u32 msdu_ht;
+	u32 msdu_legacy;
+	u32 msdu_nss[8];
+	u32 msdu_rate_idx[13];
+#endif
 };
 
 /*
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH-v2 4/6] mac80211:  Add counters for specific HE encoding types.
  2021-03-24 18:14 [PATCH-v2 1/6] mac80211: Fix station rx-packets counters greearb
  2021-03-24 18:14 ` [PATCH-v2 2/6] mac80211: Provide per-station stats in debugfs greearb
  2021-03-24 18:14 ` [PATCH-v2 3/6] mac80211: Provide detailed station rx stats greearb
@ 2021-03-24 18:14 ` greearb
  2021-03-24 18:14 ` [PATCH-v2 5/6] mac80211: Add some additional tx-stats to debugfs greearb
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: greearb @ 2021-03-24 18:14 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

So we can get counters of SU, SU-EXT, MU, Trigger
frame types.  Drivers use a convoluted way to pass this
up the stack, encoding the info in radiotap headers prepended
on the skb.  So, do a bit of hopefully-correct math to find
the radiotap_he header again in mac80211 and store it for
stats gathering.  This only applies if you have enabled
verbose mac80211 station stats.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 net/mac80211/debugfs_sta.c |  4 ++++
 net/mac80211/ieee80211_i.h |  5 +++++
 net/mac80211/rx.c          | 39 +++++++++++++++++++++++++++++++++-----
 net/mac80211/sta_info.c    |  4 ++++
 net/mac80211/sta_info.h    |  4 ++++
 5 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index f29e937aec5c..9dd29fe94bde 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -188,6 +188,10 @@ static ssize_t sta_stats_read(struct file *file, char __user *userbuf,
 	PRINT_MY_STATS("rx-bw-160", rx_stats.msdu_160);
 
 	PRINT_MY_STATS("rx-he-total", rx_stats.msdu_he_tot);
+	PRINT_MY_STATS("rx-he-su", rx_stats.msdu_he_su);
+	PRINT_MY_STATS("rx-he-ext-su", rx_stats.msdu_he_ext_su);
+	PRINT_MY_STATS("rx-he-mu", rx_stats.msdu_he_mu);
+	PRINT_MY_STATS("rx-he-trigger", rx_stats.msdu_he_trigger);
 	PRINT_MY_STATS("rx-vht", rx_stats.msdu_vht);
 	PRINT_MY_STATS("rx-ht", rx_stats.msdu_ht);
 	PRINT_MY_STATS("rx-legacy", rx_stats.msdu_legacy);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 7951c6377fc8..b75a2ae5f2e9 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -244,6 +244,11 @@ struct ieee80211_rx_data {
 
 	u32 tkip_iv32;
 	u16 tkip_iv16;
+
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+	/* for stats gathering */
+	struct ieee80211_radiotap_he radiotap_he;
+#endif
 };
 
 struct ieee80211_csa_settings {
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 01117e2d1f27..c83428b5bb5a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -735,8 +735,8 @@ ieee80211_make_monitor_skb(struct ieee80211_local *local,
  * radiotap header the driver might have added.
  */
 static struct sk_buff *
-ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
-		     struct ieee80211_rate *rate)
+ieee80211_rx_monitor(struct ieee80211_radiotap_he *radiotap_he, struct ieee80211_local *local,
+		     struct sk_buff *origskb, struct ieee80211_rate *rate)
 {
 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
 	struct ieee80211_sub_if_data *sdata;
@@ -796,6 +796,19 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
 		return NULL;
 	}
 
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+	if (status->flag & RX_FLAG_RADIOTAP_HE) {
+		/* Store this for later so we can gather stats.
+		 * This depends on drivers putting the radiotap_he header
+		 * on the skb first.  Seems all drivers do at this point.
+		 */
+		struct ieee80211_radiotap_he *he;
+		he = (struct ieee80211_radiotap_he *)(origskb->data + (rtap_space - sizeof(*he)));
+		*radiotap_he = *he;
+	}
+#endif
+
+
 	only_monitor = should_drop_frame(origskb, present_fcs_len, rtap_space);
 
 	if (!local->monitors || (status->flag & RX_FLAG_SKIP_MONITOR)) {
@@ -1763,6 +1776,17 @@ static void ieee80211_update_data_rx_stats(struct ieee80211_rx_data *rx,
 
 	if (status->encoding == RX_ENC_HE) {
 		stats->msdu_he_tot++;
+		if (status->flag & RX_FLAG_RADIOTAP_HE) {
+			u8 he_type = rx->radiotap_he.data1 & 0x3;
+			if (he_type == 0x0)
+				stats->msdu_he_su++;
+			if (he_type == 0x1)
+				stats->msdu_he_ext_su++;
+			if (he_type == 0x2)
+				stats->msdu_he_mu++;
+			if (he_type == 0x3)
+				stats->msdu_he_trigger++;
+		}
 	}
 	else if (status->encoding == RX_ENC_VHT) {
 		stats->msdu_vht++;
@@ -4601,7 +4625,8 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
 static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 					 struct ieee80211_sta *pubsta,
 					 struct sk_buff *skb,
-					 struct list_head *list)
+					 struct list_head *list,
+					 struct ieee80211_radiotap_he *radiotap_he)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
 	struct ieee80211_sub_if_data *sdata;
@@ -4617,6 +4642,9 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 	rx.skb = skb;
 	rx.local = local;
 	rx.list = list;
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+	rx.radiotap_he = *radiotap_he;
+#endif
 
 	if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
 		I802_DEBUG_INC(local->dot11ReceivedFragmentCount);
@@ -4748,6 +4776,7 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
 	struct ieee80211_rate *rate = NULL;
 	struct ieee80211_supported_band *sband;
 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+	struct ieee80211_radiotap_he radiotap_he;
 
 	WARN_ON_ONCE(softirq_count() == 0);
 
@@ -4841,13 +4870,13 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
 	 * if it was previously present.
 	 * Also, frames with less than 16 bytes are dropped.
 	 */
-	skb = ieee80211_rx_monitor(local, skb, rate);
+	skb = ieee80211_rx_monitor(&radiotap_he, local, skb, rate);
 	if (skb) {
 		ieee80211_tpt_led_trig_rx(local,
 					  ((struct ieee80211_hdr *)skb->data)->frame_control,
 					  skb->len);
 
-		__ieee80211_rx_handle_packet(hw, pubsta, skb, list);
+		__ieee80211_rx_handle_packet(hw, pubsta, skb, list, &radiotap_he);
 	}
 
 	kcov_remote_stop();
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 765993802fec..6dd62ba40133 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2688,6 +2688,10 @@ void sta_accum_rx_stats(struct sta_info *sta,
 		for (i = 0; i<NL80211_RATE_INFO_HE_RU_ALLOC_LAST; i++)
 			rx_stats->msdu_he_ru_alloc[i] += cpurxs->msdu_he_ru_alloc[i];
 		rx_stats->msdu_he_tot += cpurxs->msdu_he_tot;
+		rx_stats->msdu_he_su += cpurxs->msdu_he_su;
+		rx_stats->msdu_he_ext_su += cpurxs->msdu_he_ext_su;
+		rx_stats->msdu_he_mu += cpurxs->msdu_he_mu;
+		rx_stats->msdu_he_trigger += cpurxs->msdu_he_trigger;
 		rx_stats->msdu_vht += cpurxs->msdu_vht;
 		rx_stats->msdu_ht += cpurxs->msdu_ht;
 		rx_stats->msdu_legacy += cpurxs->msdu_legacy;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index e205a8a06ae7..90fcebf199ad 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -447,6 +447,10 @@ struct ieee80211_sta_rx_stats {
 	u32 msdu_160;
 	u32 msdu_he_ru_alloc[NL80211_RATE_INFO_HE_RU_ALLOC_LAST];
 	u32 msdu_he_tot;
+	u32 msdu_he_su;
+	u32 msdu_he_ext_su;
+	u32 msdu_he_mu;
+	u32 msdu_he_trigger;
 	u32 msdu_vht;
 	u32 msdu_ht;
 	u32 msdu_legacy;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH-v2 5/6] mac80211:  Add some additional tx-stats to debugfs
  2021-03-24 18:14 [PATCH-v2 1/6] mac80211: Fix station rx-packets counters greearb
                   ` (2 preceding siblings ...)
  2021-03-24 18:14 ` [PATCH-v2 4/6] mac80211: Add counters for specific HE encoding types greearb
@ 2021-03-24 18:14 ` greearb
  2021-03-24 18:14 ` [PATCH-v2 6/6] mac80211: last_rate is 32-bit number greearb
  2021-04-01  4:26 ` [PATCH-v2 1/6] mac80211: Fix station rx-packets counters Ben Greear
  5 siblings, 0 replies; 7+ messages in thread
From: greearb @ 2021-03-24 18:14 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

Give a better idea of TX behaviour.  Currently this code does not
deal with HE tx rates properly.  I'm not sure exactly where to
find that info, not sure that ax200 driver that I'm testing properly
provides it up to the tx-status logic.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 net/mac80211/debugfs_sta.c | 24 ++++++++++++++++++-
 net/mac80211/rx.c          |  1 +
 net/mac80211/sta_info.h    | 16 +++++++++++++
 net/mac80211/status.c      | 47 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 9dd29fe94bde..ed6380bb6270 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -107,7 +107,7 @@ static ssize_t sta_stats_read(struct file *file, char __user *userbuf,
 {
 	struct sta_info *sta = file->private_data;
 	unsigned int len = 0;
-	const int buf_len = 8000;
+	const int buf_len = 12000;
 	char *buf = kzalloc(buf_len, GFP_KERNEL);
 	unsigned long sum;
 	char tmp[60];
@@ -186,6 +186,7 @@ static ssize_t sta_stats_read(struct file *file, char __user *userbuf,
 	PRINT_MY_STATS("rx-bw-40", rx_stats.msdu_40);
 	PRINT_MY_STATS("rx-bw-80", rx_stats.msdu_80);
 	PRINT_MY_STATS("rx-bw-160", rx_stats.msdu_160);
+	PRINT_MY_STATS("rx-bw-he-ru", rx_stats.msdu_he_ru);
 
 	PRINT_MY_STATS("rx-he-total", rx_stats.msdu_he_tot);
 	PRINT_MY_STATS("rx-he-su", rx_stats.msdu_he_su);
@@ -213,6 +214,27 @@ static ssize_t sta_stats_read(struct file *file, char __user *userbuf,
 		sprintf(tmp, "rx-rate-idx[%3i]", i);
 		PRINT_MY_STATS(tmp, rx_stats.msdu_rate_idx[i]);
 	}
+
+	len += scnprintf(buf + len, buf_len - len, "\n");
+	PRINT_MY_STATS("tx-bw-20", sta->tx_stats.msdu_20);
+	PRINT_MY_STATS("tx-bw-40", sta->tx_stats.msdu_40);
+	PRINT_MY_STATS("tx-bw-80", sta->tx_stats.msdu_80);
+	PRINT_MY_STATS("tx-bw-160", sta->tx_stats.msdu_160);
+	PRINT_MY_STATS("tx-bw-he-ru", sta->tx_stats.msdu_he_ru);
+
+	PRINT_MY_STATS("tx-vht", sta->tx_stats.msdu_vht);
+	PRINT_MY_STATS("tx-ht", sta->tx_stats.msdu_ht);
+	PRINT_MY_STATS("tx-legacy", sta->tx_stats.msdu_legacy);
+
+	for (i = 0; i < ARRAY_SIZE(sta->tx_stats.msdu_nss); i++) {
+		sprintf(tmp, "tx-msdu-nss[%i]", i);
+		PRINT_MY_STATS(tmp, sta->tx_stats.msdu_nss[i]);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sta->tx_stats.msdu_rate_idx); i++) {
+		sprintf(tmp, "tx-rate-idx[%3i]", i);
+		PRINT_MY_STATS(tmp, sta->tx_stats.msdu_rate_idx[i]);
+	}
 #endif
 
 #undef PRINT_MY_STATS
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c83428b5bb5a..be05abc77292 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1767,6 +1767,7 @@ static void ieee80211_update_data_rx_stats(struct ieee80211_rx_data *rx,
 		stats->msdu_160++;
 		break;
 	case RATE_INFO_BW_HE_RU:
+		stats->msdu_he_ru++;
 		stats->msdu_he_ru_alloc[status->he_ru]++;
 		break;
 	};
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 90fcebf199ad..6fc6ad6248e6 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -445,6 +445,7 @@ struct ieee80211_sta_rx_stats {
 	u32 msdu_40;
 	u32 msdu_80;
 	u32 msdu_160;
+	u32 msdu_he_ru;
 	u32 msdu_he_ru_alloc[NL80211_RATE_INFO_HE_RU_ALLOC_LAST];
 	u32 msdu_he_tot;
 	u32 msdu_he_su;
@@ -636,6 +637,21 @@ struct sta_info {
 		struct ieee80211_tx_rate last_rate;
 		struct rate_info last_rate_info;
 		u64 msdu[IEEE80211_NUM_TIDS + 1];
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+		/* these take liberty with how things are defined, and are
+		 * designed to give a rough idea of how things are going.
+		 */
+		u32 msdu_20;
+		u32 msdu_40;
+		u32 msdu_80;
+		u32 msdu_160;
+		u32 msdu_he_ru;
+		u32 msdu_vht;
+		u32 msdu_ht;
+		u32 msdu_legacy;
+		u32 msdu_nss[8];
+		u32 msdu_rate_idx[13];
+#endif
 	} tx_stats;
 	u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
 
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 3460154cf4fe..e7ee13f82355 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -1112,6 +1112,9 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
 
 	if (pubsta) {
 		struct ieee80211_sub_if_data *sdata = sta->sdata;
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+		bool do_stats = false;
+#endif
 
 		if (!acked && !noack_success)
 			sta->status_stats.retry_failed++;
@@ -1124,6 +1127,9 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
 							acked, info->status.tx_time);
 
 			if (acked) {
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+				do_stats = true;
+#endif
 				sta->status_stats.last_ack = jiffies;
 
 				if (sta->status_stats.lost_packets)
@@ -1154,11 +1160,52 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
 				return;
 			} else if (noack_success) {
 				/* nothing to do here, do not account as lost */
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+				do_stats = true;
+#endif
 			} else {
 				ieee80211_lost_packet(sta, info);
 			}
 		}
 
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+		if (do_stats && (rates_idx != -1)) {
+			u8 nss = 0;
+			u8 mcs = 0;
+			struct ieee80211_tx_rate *txrt = &(info->status.rates[rates_idx]);
+			if (txrt->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+				sta->tx_stats.msdu_40++;
+			else if (txrt->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
+				sta->tx_stats.msdu_80++;
+			else if (txrt->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
+				sta->tx_stats.msdu_160++;
+			else
+				sta->tx_stats.msdu_20++;
+
+			if (txrt->flags & IEEE80211_TX_RC_MCS) {
+				nss = (txrt->idx / 8);
+				mcs = txrt->idx - (nss * 8);
+				sta->tx_stats.msdu_ht++;
+			}
+			else if (txrt->flags & IEEE80211_TX_RC_VHT_MCS) {
+				mcs = ieee80211_rate_get_vht_mcs(txrt);
+				nss = ieee80211_rate_get_vht_nss(txrt);
+				nss -= 1;
+				sta->tx_stats.msdu_vht++;
+			}
+			else {
+				mcs = txrt->idx;
+				sta->tx_stats.msdu_legacy++;
+			}
+
+			if (nss > (ARRAY_SIZE(sta->tx_stats.msdu_nss) - 1))
+				nss = ARRAY_SIZE(sta->tx_stats.msdu_nss) - 1;
+			if (mcs > (ARRAY_SIZE(sta->tx_stats.msdu_rate_idx) - 1))
+				mcs = ARRAY_SIZE(sta->tx_stats.msdu_rate_idx) - 1;
+			sta->tx_stats.msdu_nss[nss]++;
+			sta->tx_stats.msdu_rate_idx[mcs]++;
+		}
+#endif
 		rate_control_tx_status(local, sband, status);
 		if (ieee80211_vif_is_mesh(&sta->sdata->vif))
 			ieee80211s_update_metric(local, sta, status);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH-v2 6/6] mac80211:  last_rate is 32-bit number.
  2021-03-24 18:14 [PATCH-v2 1/6] mac80211: Fix station rx-packets counters greearb
                   ` (3 preceding siblings ...)
  2021-03-24 18:14 ` [PATCH-v2 5/6] mac80211: Add some additional tx-stats to debugfs greearb
@ 2021-03-24 18:14 ` greearb
  2021-04-01  4:26 ` [PATCH-v2 1/6] mac80211: Fix station rx-packets counters Ben Greear
  5 siblings, 0 replies; 7+ messages in thread
From: greearb @ 2021-03-24 18:14 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

Assign it to 32-bit holding variable instead of 16 when processing
the rx rate.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 net/mac80211/sta_info.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 6dd62ba40133..a28a562a8fb4 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2246,7 +2246,7 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate,
 
 static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
 {
-	u16 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate);
+	u32 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate);
 
 	if (rate == STA_STATS_RATE_INVALID)
 		return -EINVAL;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH-v2 1/6] mac80211: Fix station rx-packets counters.
  2021-03-24 18:14 [PATCH-v2 1/6] mac80211: Fix station rx-packets counters greearb
                   ` (4 preceding siblings ...)
  2021-03-24 18:14 ` [PATCH-v2 6/6] mac80211: last_rate is 32-bit number greearb
@ 2021-04-01  4:26 ` Ben Greear
  5 siblings, 0 replies; 7+ messages in thread
From: Ben Greear @ 2021-04-01  4:26 UTC (permalink / raw)
  To: linux-wireless

On 3/24/21 11:14 AM, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
> 
> I noticed 'iw dev wlan6 station dump' showed almost no rx-packets
> one one of my radios.  The rx-amsdu path did not appear to gather
> any stats, and after code inspection, neither did the rx-data
> handler.
> 
> Add common method to deal with these stats.  Verified in AX
> and /a mode, stats look at least generally correct now.
> 
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---

> @@ -2706,6 +2727,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
>   	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
>   	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
>   	__le16 fc = hdr->frame_control;
> +	ieee80211_rx_result rv;
> +	int orig_len = skb->len;
>   
>   	if (!(status->rx_flags & IEEE80211_RX_AMSDU))
>   		return RX_CONTINUE;
> @@ -2734,7 +2757,12 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
>   	if (is_multicast_ether_addr(hdr->addr1))
>   		return RX_DROP_UNUSABLE;
>   
> -	return __ieee80211_rx_h_amsdu(rx, 0);
> +	rv = __ieee80211_rx_h_amsdu(rx, 0);
> +	if ((rv == RX_QUEUED) && (rx->sta)) {
> +		struct ieee80211_sta_rx_stats *stats = &rx->sta->rx_stats;
> +		ieee80211_update_data_rx_stats(rx, stats, status, orig_len);
> +	}
> +	return rv;
>   }

I noticed this is buggy in several ways (potential use-after-free, bogus
status field).

I noticed too that upcoming changes changed some API that made later patches
in this series not apply cleanly..needed a bit of re-work.

Maybe best if I wait and rebase it against 5.13 when it is ready, unless
someone is actually interested enough in this to want to apply it earlier?

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-04-01  4:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-24 18:14 [PATCH-v2 1/6] mac80211: Fix station rx-packets counters greearb
2021-03-24 18:14 ` [PATCH-v2 2/6] mac80211: Provide per-station stats in debugfs greearb
2021-03-24 18:14 ` [PATCH-v2 3/6] mac80211: Provide detailed station rx stats greearb
2021-03-24 18:14 ` [PATCH-v2 4/6] mac80211: Add counters for specific HE encoding types greearb
2021-03-24 18:14 ` [PATCH-v2 5/6] mac80211: Add some additional tx-stats to debugfs greearb
2021-03-24 18:14 ` [PATCH-v2 6/6] mac80211: last_rate is 32-bit number greearb
2021-04-01  4:26 ` [PATCH-v2 1/6] mac80211: Fix station rx-packets counters Ben Greear

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.