[PATCH v2] wifi: ath9k: count spectral samples in the driver's own RX stats
From: Nerijus Bendžiūnas <hidden>
Date: 2026-09-04 18:20:10
Also in:
lkml
Subsystem:
atheros ath generic utilities, qualcomm atheros ath9k wireless driver, the rest · Maintainers:
Jeff Johnson, Toke Høiland-Jørgensen, Linus Torvalds
ath_cmn_process_fft() is shared by ath9k and ath9k_htc, but it casts
common->priv to struct ath_softc to reach the rx_spectral_sample_good
and rx_spectral_sample_err counters. On ath9k_htc common->priv is a
struct ath9k_htc_priv, and with CONFIG_ATH9K_DEBUGFS the increment
lands far past the end of that allocation, once per FFT sample. On
x86-64 with a distribution config the structure is 2664 bytes and the
counters sit at offset 11912 of struct ath_softc.
Store a pointer to the driver's struct ath_rx_stats in struct
ath_spec_scan_priv and count through it. Both drivers pass their own
stats to ath9k_cmn_spectral_init_debug(), and both print them in the
shared recv debugfs file, so the two counters now also work on
ath9k_htc. A pointer keeps the common code free of driver structures,
which a check on the driver type would not. Without debugfs the
pointer stays NULL and nothing is counted, as before.
Fixes: 03224678c013 ("ath9k: add counters for good and errorneous FFT/spectral frames")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Nerijus Bendžiūnas <redacted>
---
Changes in v2:
- Say where the quoted sizes come from and why a stats pointer rather
than a check on the driver type.
- Add Assisted-by, rewrite the commit message, rebase onto ath-next. No
code change.
.../net/wireless/ath/ath9k/common-spectral.c | 29 ++++++++++++-------
.../net/wireless/ath/ath9k/common-spectral.h | 11 +++++--
drivers/net/wireless/ath/ath9k/debug.c | 3 +-
.../net/wireless/ath/ath9k/htc_drv_debug.c | 3 +-
4 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c
index ca01a07f6630..d8be24ebcd24 100644
--- a/drivers/net/wireless/ath/ath9k/common-spectral.c
+++ b/drivers/net/wireless/ath/ath9k/common-spectral.c@@ -465,6 +465,20 @@ ath_cmn_is_fft_buf_full(struct ath_spec_scan_priv *spec_priv) return 0; } +static void ath_cmn_count_fft_sample(struct ath_spec_scan_priv *spec_priv, + int ret) +{ + struct ath_rx_stats *rx_stats = spec_priv->rx_stats; + + if (!rx_stats) + return; + + if (ret == 0) + rx_stats->rx_spectral_sample_good++; + else + rx_stats->rx_spectral_sample_err++; +} + /* returns 1 if this was a spectral frame, even if not handled. */ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr, struct ath_rx_status *rs, u64 tsf)
@@ -472,7 +486,6 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h u8 sample_buf[SPECTRAL_SAMPLE_MAX_LEN] = {0}; struct ath_hw *ah = spec_priv->ah; struct ath_common *common = ath9k_hw_common(spec_priv->ah); - struct ath_softc *sc = common->priv; u8 num_bins, *vdata = (u8 *)hdr; struct ath_radar_info *radar_info; int len = rs->rs_datalen;
@@ -624,10 +637,7 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h ret = fft_handler(rs, spec_priv, sample_buf, tsf, freq, chan_type); - if (ret == 0) - RX_STAT_INC(sc, rx_spectral_sample_good); - else - RX_STAT_INC(sc, rx_spectral_sample_err); + ath_cmn_count_fft_sample(spec_priv, ret); /* Mix the received bins to the /dev/random * pool
@@ -642,10 +652,7 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h ret = fft_handler(rs, spec_priv, sample_start, tsf, freq, chan_type); - if (ret == 0) - RX_STAT_INC(sc, rx_spectral_sample_good); - else - RX_STAT_INC(sc, rx_spectral_sample_err); + ath_cmn_count_fft_sample(spec_priv, ret); /* Mix the received bins to the /dev/random * pool
@@ -1052,8 +1059,10 @@ void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv) EXPORT_SYMBOL(ath9k_cmn_spectral_deinit_debug); void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, - struct dentry *debugfs_phy) + struct dentry *debugfs_phy, + struct ath_rx_stats *rx_stats) { + spec_priv->rx_stats = rx_stats; spec_priv->rfs_chan_spec_scan = relay_open("spectral_scan", debugfs_phy, 1024, 256, &rfs_spec_scan_cb,
diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.h b/drivers/net/wireless/ath/ath9k/common-spectral.h
index 011d8ab8b974..0e2c7d6d3487 100644
--- a/drivers/net/wireless/ath/ath9k/common-spectral.h
+++ b/drivers/net/wireless/ath/ath9k/common-spectral.h@@ -94,12 +94,16 @@ struct ath_ht20_40_fft_packet { struct ath_radar_info radar_info; } __packed; +struct ath_rx_stats; + struct ath_spec_scan_priv { struct ath_hw *ah; /* relay(fs) channel for spectral scan */ struct rchan *rfs_chan_spec_scan; enum spectral_mode spectral_mode; struct ath_spec_scan spec_config; + /* driver's RX statistics to account samples into, if any */ + struct ath_rx_stats *rx_stats; }; #define SPECTRAL_HT20_40_TOTAL_DATA_LEN (sizeof(struct ath_ht20_40_fft_packet))
@@ -169,7 +173,9 @@ static inline u8 spectral_bitmap_weight(u8 *bins) } #ifdef CONFIG_ATH9K_COMMON_SPECTRAL -void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy); +void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, + struct dentry *debugfs_phy, + struct ath_rx_stats *rx_stats); void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv); void ath9k_cmn_spectral_scan_trigger(struct ath_common *common,
@@ -181,7 +187,8 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h struct ath_rx_status *rs, u64 tsf); #else static inline void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, - struct dentry *debugfs_phy) + struct dentry *debugfs_phy, + struct ath_rx_stats *rx_stats) { }
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 74a0134075cf..042a4f542a94 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c@@ -1389,7 +1389,8 @@ int ath9k_init_debug(struct ath_hw *ah) ath9k_dfs_init_debug(sc); ath9k_tx99_init_debug(sc); - ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy); + ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy, + &sc->debug.stats.rxstats); debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, read_file_dma);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index 9437d69877cc..9d354b1d929c 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c@@ -487,7 +487,8 @@ int ath9k_htc_init_debug(struct ath_hw *ah) priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME, priv->hw->wiphy->debugfsdir); - ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy); + ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy, + &priv->debug.rx_stats); debugfs_create_file("tgt_int_stats", 0400, priv->debug.debugfs_phy, priv, &fops_tgt_int_stats);
base-commit: 1d8e73163ef933624341075f576e2f36ef9133f7 -- 2.55.0