From eac6bea547505fc6545014755e8e529fd804df42 Mon Sep 17 00:00:00 2001
From: Maharaja Kennadyrajan <quic_mkenna@quicinc.com>
Date: Tue, 18 Apr 2023 14:41:05 +0530
Subject: [PATCH 1/3] mac80211: Get valid last_rate for rx_bitrate from cpu
 stats

Get the valid last_rate from the cpu rx_stats while filling the
rx_bitrate in the station dump. This helps to avoid the missing
rx bitrate field in the iw station dump.

Signed-off-by: Tamizh Chelvam Raja <quic_tamizhr@quicinc.com>
Signed-off-by: Maharaja Kennadyrajan <quic_mkenna@quicinc.com>
---
 net/mac80211/sta_info.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2407,7 +2407,7 @@ void ieee80211_sta_update_pending_airtim
 }
 
 static struct ieee80211_sta_rx_stats *
-sta_get_last_rx_stats(struct sta_info *sta)
+sta_get_last_rx_stats(struct sta_info *sta, bool is_rx_bitrate)
 {
 	struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats;
 	int cpu;
@@ -2420,8 +2420,13 @@ sta_get_last_rx_stats(struct sta_info *s
 
 	for_each_possible_cpu(cpu) {
 		struct ieee80211_sta_rx_stats *cpustats;
+		u16 rate;
 
 		cpustats = per_cpu_ptr(sta->deflink.pcpu_rx_stats, cpu);
+		rate = READ_ONCE(cpustats->last_rate);
+
+		if(!cpustats->last_rx || (is_rx_bitrate && (rate == STA_STATS_RATE_INVALID)))
+			continue;
 
 		if (time_after(cpustats->last_rx, stats->last_rx))
 			stats = cpustats;
@@ -2498,7 +2503,7 @@ static void sta_stats_decode_rate(struct
 
 static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
 {
-	u32 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate);
+	u32 rate = READ_ONCE(sta_get_last_rx_stats(sta, true)->last_rate);
 
 	if (rate == STA_STATS_RATE_INVALID)
 		return -EINVAL;
@@ -2598,7 +2603,7 @@ void sta_set_sinfo(struct sta_info *sta,
 	int i, ac, cpu;
 	struct ieee80211_sta_rx_stats *last_rxstats;
 
-	last_rxstats = sta_get_last_rx_stats(sta);
+	last_rxstats = sta_get_last_rx_stats(sta, false);
 
 	sinfo->generation = sdata->local->sta_generation;
 
@@ -2882,7 +2887,7 @@ u32 sta_get_expected_throughput(struct s
 
 unsigned long ieee80211_sta_last_active(struct sta_info *sta)
 {
-	struct ieee80211_sta_rx_stats *stats = sta_get_last_rx_stats(sta);
+	struct ieee80211_sta_rx_stats *stats = sta_get_last_rx_stats(sta, false);
 
 	if (!sta->deflink.status_stats.last_ack ||
 	    time_after(stats->last_rx, sta->deflink.status_stats.last_ack))
