AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/09/06 05:47 flow patch-triage
1m Args:
null

Results:
{
  "EnableConfigs": [
    "ATH9K_COMMON_SPECTRAL",
    "ATH9K_HTC_DEBUGFS",
    "ATH9K_HTC",
    "ATH9K_DEBUGFS",
    "ATH9K"
  ],
  "FocusSymbols": [
    "ath_cmn_process_fft",
    "ath9k_cmn_spectral_init_debug",
    "ath9k_htc_init_debug",
    "ath9k_init_debug"
  ],
  "KMSANReasoning": "The patch fixes a type confusion issue between ath9k and ath9k_htc drivers in shared spectral scanning code (common-spectral.c), where common-\u003epriv was previously cast unconditionally to struct ath_softc *. The fix passes the driver-specific ath_rx_stats pointer during debug initialization and increments stats through spec_priv-\u003erx_stats with a NULL check.\n\nThis change only affects pointer assignment and statistic counter increments. It does not introduce or expose uninitialized memory, allocate uninitialized buffers, or perform copies to user space of uninitialized data. Any memory safety concerns (such as invalid pointer dereferences or type confusion) are adequately covered by KASAN. Therefore, a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false,
  "Reasoning": "The patch modifies the spectral scan debug initialization and FFT sample processing in the ath9k and ath9k_htc drivers. ath9k_htc is a USB-based wireless driver accessible in standard virtualized environments via USB emulation. The changes alter how spectral sample statistics are tracked and initialized across drivers sharing common spectral scan code, making it worth fuzzing.",
  "WorthFuzzing": true
}

1/1 2026/09/06 05:47 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 2937e854b8655b12e5b2d1cb764d00abfe4f9eb0\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Sun Sep 6 05:47:31 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c\nindex ca01a07f6630c..d8be24ebcd247 100644\n--- a/drivers/net/wireless/ath/ath9k/common-spectral.c\n+++ b/drivers/net/wireless/ath/ath9k/common-spectral.c\n@@ -465,6 +465,20 @@ ath_cmn_is_fft_buf_full(struct ath_spec_scan_priv *spec_priv)\n \t\treturn 0;\n }\n \n+static void ath_cmn_count_fft_sample(struct ath_spec_scan_priv *spec_priv,\n+\t\t\t\t     int ret)\n+{\n+\tstruct ath_rx_stats *rx_stats = spec_priv-\u003erx_stats;\n+\n+\tif (!rx_stats)\n+\t\treturn;\n+\n+\tif (ret == 0)\n+\t\trx_stats-\u003erx_spectral_sample_good++;\n+\telse\n+\t\trx_stats-\u003erx_spectral_sample_err++;\n+}\n+\n /* returns 1 if this was a spectral frame, even if not handled. */\n int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr,\n \t\t    struct ath_rx_status *rs, u64 tsf)\n@@ -472,7 +486,6 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h\n \tu8 sample_buf[SPECTRAL_SAMPLE_MAX_LEN] = {0};\n \tstruct ath_hw *ah = spec_priv-\u003eah;\n \tstruct ath_common *common = ath9k_hw_common(spec_priv-\u003eah);\n-\tstruct ath_softc *sc = common-\u003epriv;\n \tu8 num_bins, *vdata = (u8 *)hdr;\n \tstruct ath_radar_info *radar_info;\n \tint len = rs-\u003ers_datalen;\n@@ -624,10 +637,7 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h\n \t\t\t\tret = fft_handler(rs, spec_priv, sample_buf,\n \t\t\t\t\t\t  tsf, freq, chan_type);\n \n-\t\t\t\tif (ret == 0)\n-\t\t\t\t\tRX_STAT_INC(sc, rx_spectral_sample_good);\n-\t\t\t\telse\n-\t\t\t\t\tRX_STAT_INC(sc, rx_spectral_sample_err);\n+\t\t\t\tath_cmn_count_fft_sample(spec_priv, ret);\n \n \t\t\t\t/* Mix the received bins to the /dev/random\n \t\t\t\t * pool\n@@ -642,10 +652,7 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h\n \t\t\t\tret = fft_handler(rs, spec_priv, sample_start,\n \t\t\t\t\t\t  tsf, freq, chan_type);\n \n-\t\t\t\tif (ret == 0)\n-\t\t\t\t\tRX_STAT_INC(sc, rx_spectral_sample_good);\n-\t\t\t\telse\n-\t\t\t\t\tRX_STAT_INC(sc, rx_spectral_sample_err);\n+\t\t\t\tath_cmn_count_fft_sample(spec_priv, ret);\n \n \t\t\t\t/* Mix the received bins to the /dev/random\n \t\t\t\t * pool\n@@ -1052,8 +1059,10 @@ void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)\n EXPORT_SYMBOL(ath9k_cmn_spectral_deinit_debug);\n \n void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,\n-\t\t\t\t   struct dentry *debugfs_phy)\n+\t\t\t\t   struct dentry *debugfs_phy,\n+\t\t\t\t   struct ath_rx_stats *rx_stats)\n {\n+\tspec_priv-\u003erx_stats = rx_stats;\n \tspec_priv-\u003erfs_chan_spec_scan = relay_open(\"spectral_scan\",\n \t\t\t\t\t    debugfs_phy,\n \t\t\t\t\t    1024, 256, \u0026rfs_spec_scan_cb,\ndiff --git a/drivers/net/wireless/ath/ath9k/common-spectral.h b/drivers/net/wireless/ath/ath9k/common-spectral.h\nindex 011d8ab8b9744..0e2c7d6d34874 100644\n--- a/drivers/net/wireless/ath/ath9k/common-spectral.h\n+++ b/drivers/net/wireless/ath/ath9k/common-spectral.h\n@@ -94,12 +94,16 @@ struct ath_ht20_40_fft_packet {\n \tstruct ath_radar_info radar_info;\n } __packed;\n \n+struct ath_rx_stats;\n+\n struct ath_spec_scan_priv {\n \tstruct ath_hw *ah;\n \t/* relay(fs) channel for spectral scan */\n \tstruct rchan *rfs_chan_spec_scan;\n \tenum spectral_mode spectral_mode;\n \tstruct ath_spec_scan spec_config;\n+\t/* driver's RX statistics to account samples into, if any */\n+\tstruct ath_rx_stats *rx_stats;\n };\n \n #define SPECTRAL_HT20_40_TOTAL_DATA_LEN\t(sizeof(struct ath_ht20_40_fft_packet))\n@@ -169,7 +173,9 @@ static inline u8 spectral_bitmap_weight(u8 *bins)\n }\n \n #ifdef CONFIG_ATH9K_COMMON_SPECTRAL\n-void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy);\n+void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,\n+\t\t\t\t   struct dentry *debugfs_phy,\n+\t\t\t\t   struct ath_rx_stats *rx_stats);\n void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv);\n \n void ath9k_cmn_spectral_scan_trigger(struct ath_common *common,\n@@ -181,7 +187,8 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h\n \t\t    struct ath_rx_status *rs, u64 tsf);\n #else\n static inline void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,\n-\t\t\t\t\t\t struct dentry *debugfs_phy)\n+\t\t\t\t\t\t struct dentry *debugfs_phy,\n+\t\t\t\t\t\t struct ath_rx_stats *rx_stats)\n {\n }\n \ndiff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c\nindex 74a0134075cf9..042a4f542a943 100644\n--- a/drivers/net/wireless/ath/ath9k/debug.c\n+++ b/drivers/net/wireless/ath/ath9k/debug.c\n@@ -1389,7 +1389,8 @@ int ath9k_init_debug(struct ath_hw *ah)\n \n \tath9k_dfs_init_debug(sc);\n \tath9k_tx99_init_debug(sc);\n-\tath9k_cmn_spectral_init_debug(\u0026sc-\u003espec_priv, sc-\u003edebug.debugfs_phy);\n+\tath9k_cmn_spectral_init_debug(\u0026sc-\u003espec_priv, sc-\u003edebug.debugfs_phy,\n+\t\t\t\t      \u0026sc-\u003edebug.stats.rxstats);\n \n \tdebugfs_create_devm_seqfile(sc-\u003edev, \"dma\", sc-\u003edebug.debugfs_phy,\n \t\t\t\t    read_file_dma);\ndiff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c\nindex 9437d69877cc5..9d354b1d929c8 100644\n--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c\n+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c\n@@ -487,7 +487,8 @@ int ath9k_htc_init_debug(struct ath_hw *ah)\n \tpriv-\u003edebug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,\n \t\t\t\t\t     priv-\u003ehw-\u003ewiphy-\u003edebugfsdir);\n \n-\tath9k_cmn_spectral_init_debug(\u0026priv-\u003espec_priv, priv-\u003edebug.debugfs_phy);\n+\tath9k_cmn_spectral_init_debug(\u0026priv-\u003espec_priv, priv-\u003edebug.debugfs_phy,\n+\t\t\t\t      \u0026priv-\u003edebug.rx_stats);\n \n \tdebugfs_create_file(\"tgt_int_stats\", 0400, priv-\u003edebug.debugfs_phy,\n \t\t\t    priv, \u0026fops_tgt_int_stats);\n"
}

2/1 2026/09/06 05:47 agent patch-evaluator
1m Model:
core

Args:
null

Results:
{
  "EnableConfigs": [
    "ATH9K_COMMON_SPECTRAL",
    "ATH9K_HTC_DEBUGFS",
    "ATH9K_HTC",
    "ATH9K_DEBUGFS",
    "ATH9K"
  ],
  "FocusSymbols": [
    "ath_cmn_process_fft",
    "ath9k_cmn_spectral_init_debug",
    "ath9k_htc_init_debug",
    "ath9k_init_debug"
  ],
  "Reasoning": "The patch modifies the spectral scan debug initialization and FFT sample processing in the ath9k and ath9k_htc drivers. ath9k_htc is a USB-based wireless driver accessible in standard virtualized environments via USB emulation. The changes alter how spectral sample statistics are tracked and initialized across drivers sharing common spectral scan code, making it worth fuzzing.",
  "WorthFuzzing": true
}

Instruction:
You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.

================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.

- REACHABILITY IS THE PRIMARY GATE:
  Fuzzing can only discover bugs in code that can actually execute in standard virtualized
  environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
  If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
  regardless of whether it adds assertions or complex logic.

- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
  Patch authors routinely label changes as "cleanups", "refactorings", or state
  "No functional change intended". Do NOT take these claims at face value.
  Code refactorings that rearrange logic, introduce helper functions, or alter state management
  in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
  If reachable executable code is modified or refactored, it MUST be fuzzed.

- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
  When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
  BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
  Even if the author believes the invariant always holds, fuzzing is essential to verify whether
  an unusual sequence of operations can violate it.

================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:

- Non-kernel and non-executable changes:
  * Modifications to Documentation/, comments, or spelling fixes.
  * User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
    that do not affect the compiled kernel image (vmlinux) or kernel modules.
  * Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
    that do not alter control flow or data structures.
  * Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
  * Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
    ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
  * Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
    physical PCI hot-unplug or manual sysfs driver unbinding.
  * Code paths exclusive to architectures other than the target architecture.

================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
  * Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
    BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
  * Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
  * Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
  * Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).

================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:

- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
  Do NOT list generic, ubiquitous functions called by almost every program in the corpus
  (including, but not limited to: general memory allocators and deallocators, page fault
  and trap handlers, or core synchronization primitives; this is not an exhaustive list).
  Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
  which severely dilutes fuzzing effort away from the actual changes.

- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
  List functions that specifically implement the logic being added or altered, or direct API entrypoints
  for the subsystem feature under review.

- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
  Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
  distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
  If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
  functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).

================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
Target architecture: amd64

For your convenience, here is the diff of the changes:
commit 2937e854b8655b12e5b2d1cb764d00abfe4f9eb0
Author: syz-cluster <triage@syzkaller.com>
Date:   Sun Sep 6 05:47:31 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c
index ca01a07f6630c..d8be24ebcd247 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 011d8ab8b9744..0e2c7d6d34874 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 74a0134075cf9..042a4f542a943 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 9437d69877cc5..9d354b1d929c8 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);

3/2 2026/09/06 05:47 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 5057
							output: 26
							thoughts: 231
						

Thoughts:
**Analyzing the Patch for Syzkaller Fuzzing Potential**

Okay, let's break this down. My initial thought is to figure out if this patch is even *worth* fuzzing with syzkaller. The patch is touching files in `drivers/net/wireless/ath/ath9k/`, specifically `common-spectral.c`, `common-spectral.h`, `debug.c`, and `htc_drv_debug.c`. Alright, that's the scope. Now, the key question: is `ath9k` accessible via the syzkaller framework?

First, I need to know the driver type. Is it PCI, USB, or both? A quick check reveals `ath9k` itself is PCI/SoC, but `ath9k_htc` is USB! Bingo! USB drivers are absolutely within syzkaller's wheelhouse, particularly via raw_gadget, dummy_hcd, or vhci for emulation. This looks promising. The fact that the patch touches `htc_drv_debug.c` further reinforces the connection to USB.

Now, I'll need to dig deeper. I'll need to examine `htc_drv_debug.c` specifically, and how the `ath9k_htc` driver functions. I can use my preferred tools, like grepper or reading the file, to find out how it will work with syzkaller. Let's start the search and understand if the `ath9k_htc` can be fuzzed!



4/2 2026/09/06 05:48 tool grepper
0m Args:
{
  "Expression": "ath9k_cmn_spectral_init_debug"
}

Results:
{
  "Output": "drivers/net/wireless/ath/ath9k/common-spectral.c=1059=EXPORT_SYMBOL(ath9k_cmn_spectral_deinit_debug);\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1060-\ndrivers/net/wireless/ath/ath9k/common-spectral.c:1061:void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1062-\t\t\t\t   struct dentry *debugfs_phy,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1093-}\ndrivers/net/wireless/ath/ath9k/common-spectral.c:1094:EXPORT_SYMBOL(ath9k_cmn_spectral_init_debug);\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.h=170=static inline u8 spectral_bitmap_weight(u8 *bins)\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.h-175-#ifdef CONFIG_ATH9K_COMMON_SPECTRAL\ndrivers/net/wireless/ath/ath9k/common-spectral.h:176:void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,\ndrivers/net/wireless/ath/ath9k/common-spectral.h-177-\t\t\t\t   struct dentry *debugfs_phy,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.h=186=int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.h-188-#else\ndrivers/net/wireless/ath/ath9k/common-spectral.h:189:static inline void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,\ndrivers/net/wireless/ath/ath9k/common-spectral.h-190-\t\t\t\t\t\t struct dentry *debugfs_phy,\n--\ndrivers/net/wireless/ath/ath9k/debug.c=1377=int ath9k_init_debug(struct ath_hw *ah)\n--\ndrivers/net/wireless/ath/ath9k/debug.c-1391-\tath9k_tx99_init_debug(sc);\ndrivers/net/wireless/ath/ath9k/debug.c:1392:\tath9k_cmn_spectral_init_debug(\u0026sc-\u003espec_priv, sc-\u003edebug.debugfs_phy,\ndrivers/net/wireless/ath/ath9k/debug.c-1393-\t\t\t\t      \u0026sc-\u003edebug.stats.rxstats);\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c=482=int ath9k_htc_init_debug(struct ath_hw *ah)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c-489-\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c:490:\tath9k_cmn_spectral_init_debug(\u0026priv-\u003espec_priv, priv-\u003edebug.debugfs_phy,\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c-491-\t\t\t\t      \u0026priv-\u003edebug.rx_stats);\n"
}

5/2 2026/09/06 05:48 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 6535
							output: 36
							thoughts: 520
						

Thoughts:
**Analyzing a Patch: A Deep Dive into Driver Data Structures and Potential Memory Corruption**

Alright, let's dissect this patch and figure out the reasoning behind the changes. First, I need to understand what's happening within the `ath_cmn_process_fft` function. Taking a look at the code before the patch, I see an access pattern that immediately raises a flag:

```c
struct ath_hw *ah = spec_priv->ah;
struct ath_common *common = ath9k_hw_common(spec_priv->ah);
struct ath_softc *sc = common->priv;
...
if (ret == 0)
    RX_STAT_INC(sc, rx_spectral_sample_good);
else
    RX_STAT_INC(sc, rx_spectral_sample_err);
```

Specifically, the line where `common->priv` is cast to a `struct ath_softc *sc`. I know, from my experience with the `ath9k` driver, that `common->priv` is indeed a `struct ath_softc *`. But, this is a shared file between `ath9k` and `ath9k_htc`. What if this access is used in `ath9k_htc` as well? I need to check what `ath9k_htc` actually sets `common->priv` to. Or, rather, what the type of the struct pointed to by `common->priv` is.

Bingo! In `ath9k_htc`, `common->priv` is actually a `struct ath9k_htc_priv *priv`. So, the `RX_STAT_INC(sc, ...)` macro is likely incrementing a member of a structure pointed to by `sc`.

The implications of this are immediate and significant. If `sc` is treated as a `struct ath_softc *` when it's actually a `struct ath9k_htc_priv *`, then we have a classic case of memory corruption or invalid struct member access! This would depend on the size of the 2 structs, and which fields the increment targets.

This patch, then, is a bugfix. It addresses a shared code problem where `common-spectral.c` was being used by both `ath9k` and `ath9k_htc`, but `ath_cmn_process_fft` assumed a `struct ath_softc *` for `common->priv`.

Now, I see the corrected code. `ath9k_cmn_spectral_init_debug` now receives a pointer to `struct ath_rx_stats *rx_stats`, stored in `spec_priv->rx_stats`. Consequently, `ath_cmn_count_fft_sample` safely updates `rx_stats->rx_spectral_sample_good++` or `rx_stats->rx_spectral_sample_err++`. This is a much cleaner and safer approach, eliminating the potential for those nasty memory-related bugs.

I'm curious: is `ath9k_htc` a USB driver? And does syzkaller fuzz the `ath9k_htc` driver, or the `ath9k` driver? I'll check the Kconfig files for both `ath9k` and `ath9k_htc` just to see if there is any interesting information in them.



6/2 2026/09/06 05:48 tool grepper
0m Args:
{
  "Expression": "ATH9K_HTC",
  "PathPrefix": "drivers/net/wireless/ath/ath9k"
}

Results:
{
  "Output": "drivers/net/wireless/ath/ath9k/Kconfig=13=config ATH9K_BTCOEX_SUPPORT\ndrivers/net/wireless/ath/ath9k/Kconfig-14-\tbool \"Atheros bluetooth coexistence support\"\ndrivers/net/wireless/ath/ath9k/Kconfig:15:\tdepends on (ATH9K || ATH9K_HTC)\ndrivers/net/wireless/ath/ath9k/Kconfig-16-\tdefault y\n--\ndrivers/net/wireless/ath/ath9k/Kconfig=156=config ATH9K_PCI_NO_EEPROM\n--\ndrivers/net/wireless/ath/ath9k/Kconfig-171-\ndrivers/net/wireless/ath/ath9k/Kconfig:172:config ATH9K_HTC\ndrivers/net/wireless/ath/ath9k/Kconfig-173-\ttristate \"Atheros HTC based wireless cards support\"\n--\ndrivers/net/wireless/ath/ath9k/Kconfig-186-\ndrivers/net/wireless/ath/ath9k/Kconfig:187:config ATH9K_HTC_DEBUGFS\ndrivers/net/wireless/ath/ath9k/Kconfig-188-\tbool \"Atheros ath9k_htc debugging\"\ndrivers/net/wireless/ath/ath9k/Kconfig:189:\tdepends on ATH9K_HTC \u0026\u0026 DEBUG_FS\ndrivers/net/wireless/ath/ath9k/Kconfig-190-\tselect ATH9K_COMMON_DEBUG\n--\ndrivers/net/wireless/ath/ath9k/Kconfig=206=config ATH9K_COMMON_SPECTRAL\ndrivers/net/wireless/ath/ath9k/Kconfig-207-\tbool \"Atheros ath9k/ath9k_htc spectral scan support\"\ndrivers/net/wireless/ath/ath9k/Kconfig:208:\tdepends on ATH9K_DEBUGFS || ATH9K_HTC_DEBUGFS\ndrivers/net/wireless/ath/ath9k/Kconfig-209-\tselect RELAY\n--\ndrivers/net/wireless/ath/ath9k/Makefile=68=ath9k_htc-y +=\thtc_hst.o \\\n--\ndrivers/net/wireless/ath/ath9k/Makefile-76-\ndrivers/net/wireless/ath/ath9k/Makefile:77:ath9k_htc-$(CONFIG_ATH9K_HTC_DEBUGFS) += htc_drv_debug.o\ndrivers/net/wireless/ath/ath9k/Makefile-78-\ndrivers/net/wireless/ath/ath9k/Makefile:79:obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o\ndrivers/net/wireless/ath/ath9k/Makefile-80-\n--\ndrivers/net/wireless/ath/ath9k/ar9003_eeprom.c=3390=static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)\n--\ndrivers/net/wireless/ath/ath9k/ar9003_eeprom.c-3400-\ndrivers/net/wireless/ath/ath9k/ar9003_eeprom.c:3401:#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)\ndrivers/net/wireless/ath/ath9k/ar9003_eeprom.c-3402-static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,\n--\ndrivers/net/wireless/ath/ath9k/hif_usb.c=232=static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev,\n--\ndrivers/net/wireless/ath/ath9k/hif_usb.c-238-\twhile ((skb = __skb_dequeue(queue)) != NULL) {\ndrivers/net/wireless/ath/ath9k/hif_usb.c:239:#ifdef CONFIG_ATH9K_HTC_DEBUGFS\ndrivers/net/wireless/ath/ath9k/hif_usb.c-240-\t\tint ln = skb-\u003elen;\n--\ndrivers/net/wireless/ath/ath9k/hif_usb.c=376=static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb)\n--\ndrivers/net/wireless/ath/ath9k/hif_usb.c-399-\t/* Mgmt/Beacon frames don't use the TX buffer pool */\ndrivers/net/wireless/ath/ath9k/hif_usb.c:400:\tif ((tx_ctl-\u003etype == ATH9K_HTC_MGMT) ||\ndrivers/net/wireless/ath/ath9k/hif_usb.c:401:\t    (tx_ctl-\u003etype == ATH9K_HTC_BEACON)) {\ndrivers/net/wireless/ath/ath9k/hif_usb.c-402-\t\tret = hif_usb_send_mgmt(hif_dev, skb);\n--\ndrivers/net/wireless/ath/ath9k/hif_usb.c-406-\ndrivers/net/wireless/ath/ath9k/hif_usb.c:407:\tif ((tx_ctl-\u003etype == ATH9K_HTC_NORMAL) ||\ndrivers/net/wireless/ath/ath9k/hif_usb.c:408:\t    (tx_ctl-\u003etype == ATH9K_HTC_AMPDU)) {\ndrivers/net/wireless/ath/ath9k/hif_usb.c-409-\t\t__skb_queue_tail(\u0026hif_dev-\u003etx.tx_skb_queue, skb);\n--\ndrivers/net/wireless/ath/ath9k/hif_usb.c=487=static inline bool check_index(struct sk_buff *skb, u8 idx)\n--\ndrivers/net/wireless/ath/ath9k/hif_usb.c-492-\ndrivers/net/wireless/ath/ath9k/hif_usb.c:493:\tif ((tx_ctl-\u003etype == ATH9K_HTC_AMPDU) \u0026\u0026\ndrivers/net/wireless/ath/ath9k/hif_usb.c-494-\t    (tx_ctl-\u003esta_idx == idx))\n--\ndrivers/net/wireless/ath/ath9k/htc.h=56=enum htc_opmode {\n--\ndrivers/net/wireless/ath/ath9k/htc.h-64-\ndrivers/net/wireless/ath/ath9k/htc.h:65:#define ATH9K_HTC_AMPDU  1\ndrivers/net/wireless/ath/ath9k/htc.h:66:#define ATH9K_HTC_NORMAL 2\ndrivers/net/wireless/ath/ath9k/htc.h:67:#define ATH9K_HTC_BEACON 3\ndrivers/net/wireless/ath/ath9k/htc.h:68:#define ATH9K_HTC_MGMT   4\ndrivers/net/wireless/ath/ath9k/htc.h-69-\ndrivers/net/wireless/ath/ath9k/htc.h:70:#define ATH9K_HTC_TX_CTSONLY      0x1\ndrivers/net/wireless/ath/ath9k/htc.h:71:#define ATH9K_HTC_TX_RTSCTS       0x2\ndrivers/net/wireless/ath/ath9k/htc.h-72-\ndrivers/net/wireless/ath/ath9k/htc.h=73=struct tx_frame_hdr {\n--\ndrivers/net/wireless/ath/ath9k/htc.h-77-\tu8 tidno;\ndrivers/net/wireless/ath/ath9k/htc.h:78:\t__be32 flags; /* ATH9K_HTC_TX_* */\ndrivers/net/wireless/ath/ath9k/htc.h-79-\tu8 key_type;\n--\ndrivers/net/wireless/ath/ath9k/htc.h=194=struct ath9k_htc_target_rx_stats {\n--\ndrivers/net/wireless/ath/ath9k/htc.h-199-\ndrivers/net/wireless/ath/ath9k/htc.h:200:#define ATH9K_HTC_MAX_VIF 2\ndrivers/net/wireless/ath/ath9k/htc.h:201:#define ATH9K_HTC_MAX_BCN_VIF 2\ndrivers/net/wireless/ath/ath9k/htc.h-202-\n--\ndrivers/net/wireless/ath/ath9k/htc.h=249=struct ath9k_vif_iter_data {\n--\ndrivers/net/wireless/ath/ath9k/htc.h-253-\ndrivers/net/wireless/ath/ath9k/htc.h:254:#define ATH9K_HTC_MAX_STA 8\ndrivers/net/wireless/ath/ath9k/htc.h:255:#define ATH9K_HTC_MAX_TID 8\ndrivers/net/wireless/ath/ath9k/htc.h-256-\n--\ndrivers/net/wireless/ath/ath9k/htc.h=264=struct ath9k_htc_sta {\ndrivers/net/wireless/ath/ath9k/htc.h-265-\tu8 index;\ndrivers/net/wireless/ath/ath9k/htc.h:266:\tenum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];\ndrivers/net/wireless/ath/ath9k/htc.h-267-\tstruct work_struct rc_update_work;\n--\ndrivers/net/wireless/ath/ath9k/htc.h-270-\ndrivers/net/wireless/ath/ath9k/htc.h:271:#define ATH9K_HTC_RXBUF 256\ndrivers/net/wireless/ath/ath9k/htc.h-272-#define HTC_RX_FRAME_HEADER_SIZE 40\n--\ndrivers/net/wireless/ath/ath9k/htc.h=281=struct ath9k_htc_rx {\n--\ndrivers/net/wireless/ath/ath9k/htc.h-286-\ndrivers/net/wireless/ath/ath9k/htc.h:287:#define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */\ndrivers/net/wireless/ath/ath9k/htc.h:288:#define ATH9K_HTC_TX_TIMEOUT_INTERVAL 3000 /* ms */\ndrivers/net/wireless/ath/ath9k/htc.h:289:#define ATH9K_HTC_TX_RESERVE 10\ndrivers/net/wireless/ath/ath9k/htc.h:290:#define ATH9K_HTC_TX_TIMEOUT_COUNT 40\ndrivers/net/wireless/ath/ath9k/htc.h:291:#define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE)\ndrivers/net/wireless/ath/ath9k/htc.h-292-\ndrivers/net/wireless/ath/ath9k/htc.h:293:#define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0)\ndrivers/net/wireless/ath/ath9k/htc.h:294:#define ATH9K_HTC_OP_TX_DRAIN       BIT(1)\ndrivers/net/wireless/ath/ath9k/htc.h-295-\n--\ndrivers/net/wireless/ath/ath9k/htc.h=311=struct ath9k_htc_tx_ctl {\ndrivers/net/wireless/ath/ath9k/htc.h:312:\tu8 type; /* ATH9K_HTC_* */\ndrivers/net/wireless/ath/ath9k/htc.h-313-\tu8 epid;\n--\ndrivers/net/wireless/ath/ath9k/htc.h=319=static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)\n--\ndrivers/net/wireless/ath/ath9k/htc.h-327-\ndrivers/net/wireless/ath/ath9k/htc.h:328:#ifdef CONFIG_ATH9K_HTC_DEBUGFS\ndrivers/net/wireless/ath/ath9k/htc.h-329-#define __STAT_SAFE(hif_dev, expr)\tdo { ((hif_dev)-\u003ehtc_handle-\u003edrv_priv ? (expr) : 0); } while (0)\n--\ndrivers/net/wireless/ath/ath9k/htc.h=388=static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc.h-392-\ndrivers/net/wireless/ath/ath9k/htc.h:393:#endif /* CONFIG_ATH9K_HTC_DEBUGFS */\ndrivers/net/wireless/ath/ath9k/htc.h-394-\n--\ndrivers/net/wireless/ath/ath9k/htc.h=409=struct htc_beacon {\n--\ndrivers/net/wireless/ath/ath9k/htc.h-415-\ndrivers/net/wireless/ath/ath9k/htc.h:416:\tstruct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF];\ndrivers/net/wireless/ath/ath9k/htc.h-417-\tu32 bmisscnt;\n--\ndrivers/net/wireless/ath/ath9k/htc.h=456=struct ath9k_htc_priv {\n--\ndrivers/net/wireless/ath/ath9k/htc.h-478-\tu8 sta_slot;\ndrivers/net/wireless/ath/ath9k/htc.h:479:\tu8 vif_sta_pos[ATH9K_HTC_MAX_VIF];\ndrivers/net/wireless/ath/ath9k/htc.h-480-\tu8 num_ibss_vif;\n--\ndrivers/net/wireless/ath/ath9k/htc.h-535-\tstruct delayed_work duty_cycle_work;\ndrivers/net/wireless/ath/ath9k/htc.h:536:#ifdef CONFIG_ATH9K_HTC_DEBUGFS\ndrivers/net/wireless/ath/ath9k/htc.h-537-\tstruct ath9k_debug debug;\n--\ndrivers/net/wireless/ath/ath9k/htc.h=641=int ath9k_htc_resume(struct htc_target *htc_handle);\ndrivers/net/wireless/ath/ath9k/htc.h-642-#endif\ndrivers/net/wireless/ath/ath9k/htc.h:643:#ifdef CONFIG_ATH9K_HTC_DEBUGFS\ndrivers/net/wireless/ath/ath9k/htc.h-644-int ath9k_htc_init_debug(struct ath_hw *ah);\n--\ndrivers/net/wireless/ath/ath9k/htc.h=648=static inline void ath9k_htc_deinit_debug(struct ath9k_htc_priv *priv)\n--\ndrivers/net/wireless/ath/ath9k/htc.h-650-}\ndrivers/net/wireless/ath/ath9k/htc.h:651:#endif /* CONFIG_ATH9K_HTC_DEBUGFS */\ndrivers/net/wireless/ath/ath9k/htc.h-652-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c=111=static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-116-\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c:117:\tath9k_cmn_beacon_config_ap(ah, conf, ATH9K_HTC_MAX_BCN_VIF);\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-118-\tath9k_htc_beacon_init(priv, conf, false);\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c=191=static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-242-\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c:243:\ttx_ctl-\u003etype = ATH9K_HTC_BEACON;\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-244-\ttx_ctl-\u003eepid = priv-\u003ebeacon_ep;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c=264=static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-276-\ttsftu = TSF_TO_TU(tsf \u003e\u003e 32, tsf);\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c:277:\tslot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval;\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c:278:\tslot = ATH9K_HTC_MAX_BCN_VIF - slot - 1;\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-279-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c=325=void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-332-\tspin_lock_bh(\u0026priv-\u003ebeacon_lock);\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c:333:\tfor (i = 0; i \u003c ATH9K_HTC_MAX_BCN_VIF; i++) {\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-334-\t\tif (priv-\u003ebeacon.bslot[i] == NULL) {\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c=365=void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-380-\t */\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c:381:\ttsfadjust = cur_conf-\u003ebeacon_interval * avp-\u003ebslot / ATH9K_HTC_MAX_BCN_VIF;\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-382-\tavp-\u003etsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust));\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c=398=static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = {\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c-418-};\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c:419:#define ATH9K_HTC_SSTATS_LEN ARRAY_SIZE(ath9k_htc_gstrings_stats)\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c-420-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c=430=int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c-433-\tif (sset == ETH_SS_STATS)\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c:434:\t\treturn ATH9K_HTC_SSTATS_LEN;\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c-435-\treturn 0;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c=448=void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c-473-\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c:474:\tWARN_ON(i != ATH9K_HTC_SSTATS_LEN);\ndrivers/net/wireless/ath/ath9k/htc_drv_debug.c-475-}\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_init.c=606=static int ath9k_init_priv(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_init.c-673-\ndrivers/net/wireless/ath/ath9k/htc_drv_init.c:674:\tfor (i = 0; i \u003c ATH9K_HTC_MAX_BCN_VIF; i++)\ndrivers/net/wireless/ath/ath9k/htc_drv_init.c-675-\t\tpriv-\u003ebeacon.bslot[i] = NULL;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c=184=void ath9k_htc_reset(struct ath9k_htc_priv *priv)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-233-\tmod_timer(\u0026priv-\u003etx.cleanup_timer,\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:234:\t\t  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-235-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c=240=static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-311-\tmod_timer(\u0026priv-\u003etx.cleanup_timer,\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:312:\t\t  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-313-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c=350=static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-357-\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:358:\tif ((priv-\u003envifs \u003e= ATH9K_HTC_MAX_VIF) ||\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:359:\t    (priv-\u003enstations \u003e= ATH9K_HTC_MAX_STA)) {\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-360-\t\tret = -ENOBUFS;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-364-\tsta_idx = ffz(priv-\u003esta_slot);\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:365:\tif ((sta_idx \u003c 0) || (sta_idx \u003e ATH9K_HTC_MAX_STA)) {\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-366-\t\tret = -ENOBUFS;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c=466=static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-477-\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:478:\tif (priv-\u003enstations \u003e= ATH9K_HTC_MAX_STA)\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-479-\t\treturn -ENOBUFS;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-481-\tsta_idx = ffz(priv-\u003esta_slot);\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:482:\tif ((sta_idx \u003c 0) || (sta_idx \u003e ATH9K_HTC_MAX_STA))\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-483-\t\treturn -ENOBUFS;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c=702=static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-713-\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:714:\tif (tid \u003e= ATH9K_HTC_MAX_TID)\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-715-\t\treturn -EINVAL;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c=907=static int ath9k_htc_start(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-960-\tspin_lock_bh(\u0026priv-\u003etx.tx_lock);\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:961:\tpriv-\u003etx.flags \u0026= ~ATH9K_HTC_OP_TX_QUEUES_STOP;\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-962-\tspin_unlock_bh(\u0026priv-\u003etx.tx_lock);\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-966-\tmod_timer(\u0026priv-\u003etx.cleanup_timer,\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:967:\t\t  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-968-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c=1658=static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-1688-\tcase IEEE80211_AMPDU_TX_OPERATIONAL:\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:1689:\t\tif (tid \u003e= ATH9K_HTC_MAX_TID) {\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-1690-\t\t\tret = -EINVAL;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c=1874=struct ieee80211_ops ath9k_htc_ops = {\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-1906-\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c:1907:#ifdef CONFIG_ATH9K_HTC_DEBUGFS\ndrivers/net/wireless/ath/ath9k/htc_drv_main.c-1908-\t.get_et_sset_count  = ath9k_htc_get_et_sset_count,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=23=static const int subtype_txq_to_hwq[] = {\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-29-\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:30:#define ATH9K_HTC_INIT_TXQ(subtype) do {\t\t\t\\\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-31-\t\tqi.tqi_subtype = subtype_txq_to_hwq[subtype];\t\\\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=56=void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-59-\tpriv-\u003etx.queued_cnt++;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:60:\tif ((priv-\u003etx.queued_cnt \u003e= ATH9K_HTC_TX_THRESHOLD) \u0026\u0026\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:61:\t    !(priv-\u003etx.flags \u0026 ATH9K_HTC_OP_TX_QUEUES_STOP)) {\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:62:\t\tpriv-\u003etx.flags |= ATH9K_HTC_OP_TX_QUEUES_STOP;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-63-\t\tieee80211_stop_queues(priv-\u003ehw);\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=68=void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-70-\tspin_lock_bh(\u0026priv-\u003etx.tx_lock);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:71:\tif ((priv-\u003etx.queued_cnt \u003c ATH9K_HTC_TX_THRESHOLD) \u0026\u0026\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:72:\t    (priv-\u003etx.flags \u0026 ATH9K_HTC_OP_TX_QUEUES_STOP)) {\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:73:\t\tpriv-\u003etx.flags \u0026= ~ATH9K_HTC_OP_TX_QUEUES_STOP;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-74-\t\tieee80211_wake_queues(priv-\u003ehw);\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=214=static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-240-\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:241:\ttx_ctl-\u003etype = ATH9K_HTC_MGMT;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-242-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=260=static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-292-\tif (tx_info-\u003eflags \u0026 IEEE80211_TX_CTL_AMPDU) {\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:293:\t\ttx_ctl-\u003etype = ATH9K_HTC_AMPDU;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:294:\t\ttx_hdr.data_type = ATH9K_HTC_AMPDU;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-295-\t} else {\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:296:\t\ttx_ctl-\u003etype = ATH9K_HTC_NORMAL;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:297:\t\ttx_hdr.data_type = ATH9K_HTC_NORMAL;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-298-\t}\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-312-\t\tif (skb-\u003elen \u003e priv-\u003ehw-\u003ewiphy-\u003erts_threshold)\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:313:\t\t\tflags |= ATH9K_HTC_TX_RTSCTS;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-314-\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-315-\t/* CTS-to-self */\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:316:\tif (!(flags \u0026 ATH9K_HTC_TX_RTSCTS) \u0026\u0026\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-317-\t    (vif \u0026\u0026 vif-\u003ebss_conf.use_cts_prot))\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:318:\t\tflags |= ATH9K_HTC_TX_CTSONLY;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-319-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=392=static inline bool __ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-397-\tspin_lock_bh(\u0026priv-\u003etx.tx_lock);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:398:\tif ((tid \u003c ATH9K_HTC_MAX_TID) \u0026\u0026 (ista-\u003etid_state[tid] == AGGR_STOP))\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-399-\t\tret = true;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=445=static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-478-\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:479:\tif (txs-\u003ets_flags \u0026 ATH9K_HTC_TXSTAT_ACK) {\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-480-\t\ttx_info-\u003eflags |= IEEE80211_TX_STAT_ACK;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-484-\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:485:\tif (txs-\u003ets_flags \u0026 ATH9K_HTC_TXSTAT_FILT)\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-486-\t\ttx_info-\u003eflags |= IEEE80211_TX_STAT_TX_FILTERED;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-487-\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:488:\tif (txs-\u003ets_flags \u0026 ATH9K_HTC_TXSTAT_RTC_CTS)\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-489-\t\trate-\u003eflags |= IEEE80211_TX_RC_USE_RTS_CTS;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-491-\trate-\u003ecount = 1;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:492:\trate-\u003eidx = MS(txs-\u003ets_rate, ATH9K_HTC_TXSTAT_RATE);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-493-\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:494:\tif (txs-\u003ets_flags \u0026 ATH9K_HTC_TXSTAT_MCS) {\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-495-\t\trate-\u003eflags |= IEEE80211_TX_RC_MCS;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-496-\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:497:\t\tif (txs-\u003ets_flags \u0026 ATH9K_HTC_TXSTAT_CW40)\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-498-\t\t\trate-\u003eflags |= IEEE80211_TX_RC_40_MHZ_WIDTH;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:499:\t\tif (txs-\u003ets_flags \u0026 ATH9K_HTC_TXSTAT_SGI)\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-500-\t\t\trate-\u003eflags |= IEEE80211_TX_RC_SHORT_GI;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=539=void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-543-\tspin_lock_bh(\u0026priv-\u003etx.tx_lock);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:544:\tpriv-\u003etx.flags |= ATH9K_HTC_OP_TX_DRAIN;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-545-\tspin_unlock_bh(\u0026priv-\u003etx.tx_lock);\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-573-\tspin_lock_bh(\u0026priv-\u003etx.tx_lock);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:574:\tpriv-\u003etx.flags \u0026= ~ATH9K_HTC_OP_TX_DRAIN;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-575-\tspin_unlock_bh(\u0026priv-\u003etx.tx_lock);\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=578=void ath9k_tx_failed_tasklet(struct tasklet_struct *t)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-582-\tspin_lock(\u0026priv-\u003etx.tx_lock);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:583:\tif (priv-\u003etx.flags \u0026 ATH9K_HTC_OP_TX_DRAIN) {\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-584-\t\tspin_unlock(\u0026priv-\u003etx.tx_lock);\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=618=static struct sk_buff* ath9k_htc_tx_get_packet(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-624-\tunsigned long flags;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:625:\tu8 epid = MS(txs-\u003ets_rate, ATH9K_HTC_TXSTAT_EPID);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-626-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=716=static inline bool check_packet(struct ath9k_htc_priv *priv, struct sk_buff *skb)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-724-\t\t       tx_ctl-\u003etimestamp +\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:725:\t\t       msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) {\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-726-\t\tath_dbg(common, XMIT, \"Dropping a packet due to TX timeout\\n\");\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=761=void ath9k_htc_tx_cleanup_timer(struct timer_list *t)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-776-\t\t\t\tevent-\u003etxs.cookie,\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:777:\t\t\t\tMS(event-\u003etxs.ts_rate, ATH9K_HTC_TXSTAT_EPID));\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-778-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-784-\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:785:\t\tif (++event-\u003ecount \u003e= ATH9K_HTC_TX_TIMEOUT_COUNT) {\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-786-\t\t\tlist_del(\u0026event-\u003elist);\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-805-\tmod_timer(\u0026priv-\u003etx.cleanup_timer,\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:806:\t\t  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-807-}\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=827=bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-834-\tmemset(\u0026qi, 0, sizeof(qi));\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:835:\tATH9K_HTC_INIT_TXQ(subtype);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-836-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=852=int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-856-\tmemset(\u0026qi, 0, sizeof(qi));\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:857:\tATH9K_HTC_INIT_TXQ(0);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-858-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=1187=int ath9k_rx_init(struct ath9k_htc_priv *priv)\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-1193-\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:1194:\tfor (i = 0; i \u003c ATH9K_HTC_RXBUF; i++) {\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-1195-\t\tstruct ath9k_htc_rxbuf *rxbuf =\n--\ndrivers/net/wireless/ath/ath9k/wmi.c=138=void ath9k_wmi_event_tasklet(struct tasklet_struct *t)\n--\ndrivers/net/wireless/ath/ath9k/wmi.c-178-\t\t\tspin_lock_bh(\u0026priv-\u003etx.tx_lock);\ndrivers/net/wireless/ath/ath9k/wmi.c:179:\t\t\tif (priv-\u003etx.flags \u0026 ATH9K_HTC_OP_TX_DRAIN) {\ndrivers/net/wireless/ath/ath9k/wmi.c-180-\t\t\t\tspin_unlock_bh(\u0026priv-\u003etx.tx_lock);\n--\ndrivers/net/wireless/ath/ath9k/wmi.h=39=struct wmi_event_swba {\n--\ndrivers/net/wireless/ath/ath9k/wmi.h-50-\ndrivers/net/wireless/ath/ath9k/wmi.h:51:#define ATH9K_HTC_TXSTAT_ACK        BIT(0)\ndrivers/net/wireless/ath/ath9k/wmi.h:52:#define ATH9K_HTC_TXSTAT_FILT       BIT(1)\ndrivers/net/wireless/ath/ath9k/wmi.h:53:#define ATH9K_HTC_TXSTAT_RTC_CTS    BIT(2)\ndrivers/net/wireless/ath/ath9k/wmi.h:54:#define ATH9K_HTC_TXSTAT_MCS        BIT(3)\ndrivers/net/wireless/ath/ath9k/wmi.h:55:#define ATH9K_HTC_TXSTAT_CW40       BIT(4)\ndrivers/net/wireless/ath/ath9k/wmi.h:56:#define ATH9K_HTC_TXSTAT_SGI        BIT(5)\ndrivers/net/wireless/ath/ath9k/wmi.h-57-\n--\ndrivers/net/wireless/ath/ath9k/wmi.h-63- */\ndrivers/net/wireless/ath/ath9k/wmi.h:64:#define ATH9K_HTC_TXSTAT_RATE       0x0f\ndrivers/net/wireless/ath/ath9k/wmi.h:65:#define ATH9K_HTC_TXSTAT_RATE_S     0\ndrivers/net/wireless/ath/ath9k/wmi.h-66-\ndrivers/net/wireless/ath/ath9k/wmi.h:67:#define ATH9K_HTC_TXSTAT_EPID       0xf0\ndrivers/net/wireless/ath/ath9k/wmi.h:68:#define ATH9K_HTC_TXSTAT_EPID_S     4\ndrivers/net/wireless/ath/ath9k/wmi.h-69-\n"
}

7/2 2026/09/06 05:48 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 20277
							output: 22
							thoughts: 29
						

Thoughts:
Here's my take on those thoughts:

**Analyzing `ath_cmn_process_fft` Calls in ath9k and ath9k_htc**

Okay, so I need to dig into the usage of `ath_cmn_process_fft`. My initial goal is to understand how it's implemented and, more importantly, *where* it's being called within the `ath9k` and `ath9k_htc` drivers. I suspect there will be differences between the two, given the architectural distinctions (PCI vs. USB). I need to determine if it's being used for channel estimation, data demodulation, or perhaps some other signal processing stage. I will look for calls to this function, keeping in mind the hardware differences. I anticipate there will be differences in the calling context and parameters used in each driver. Armed with this knowledge, I can start forming a more holistic understanding of the role `ath_cmn_process_fft` plays in these drivers.



8/2 2026/09/06 05:48 tool grepper
0m Args:
{
  "Expression": "ath_cmn_process_fft"
}

Results:
{
  "Output": "drivers/net/wireless/ath/ath9k/common-spectral.c=468=static void ath_cmn_count_fft_sample(struct ath_spec_scan_priv *spec_priv,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.c-482-/* returns 1 if this was a spectral frame, even if not handled. */\ndrivers/net/wireless/ath/ath9k/common-spectral.c:483:int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr,\ndrivers/net/wireless/ath/ath9k/common-spectral.c-484-\t\t    struct ath_rx_status *rs, u64 tsf)\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.c-690-}\ndrivers/net/wireless/ath/ath9k/common-spectral.c:691:EXPORT_SYMBOL(ath_cmn_process_fft);\ndrivers/net/wireless/ath/ath9k/common-spectral.c-692-\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.h=183=int ath9k_cmn_spectral_scan_config(struct ath_common *common,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.h-185-\t\t\t       enum spectral_mode spectral_mode);\ndrivers/net/wireless/ath/ath9k/common-spectral.h:186:int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr,\ndrivers/net/wireless/ath/ath9k/common-spectral.h-187-\t\t    struct ath_rx_status *rs, u64 tsf);\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.h=199=static inline void ath9k_cmn_spectral_scan_trigger(struct ath_common *common,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.h-203-\ndrivers/net/wireless/ath/ath9k/common-spectral.h:204:static inline int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv,\ndrivers/net/wireless/ath/ath9k/common-spectral.h-205-\t\t\t\t      struct ieee80211_hdr *hdr,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=972=static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-1047-\t\t/* TODO: Not using DFS processing now. */\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:1048:\t\tif (ath_cmn_process_fft(\u0026priv-\u003espec_priv, hdr,\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-1049-\t\t\t\t    \u0026rx_stats, rx_status-\u003emactime)) {\n--\ndrivers/net/wireless/ath/ath9k/recv.c=806=static int ath9k_rx_skb_preprocess(struct ath_softc *sc,\n--\ndrivers/net/wireless/ath/ath9k/recv.c-883-\t\t} else if (sc-\u003espec_priv.spectral_mode != SPECTRAL_DISABLED \u0026\u0026\ndrivers/net/wireless/ath/ath9k/recv.c:884:\t\t\t   ath_cmn_process_fft(\u0026sc-\u003espec_priv, hdr, rx_stats,\ndrivers/net/wireless/ath/ath9k/recv.c-885-\t\t\t\t\t       rx_status-\u003emactime)) {\n"
}

9/2 2026/09/06 05:48 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 21510
							output: 42
							thoughts: 404
						

Thoughts:
**Analyzing the `ath9k_htc` USB Wireless Driver**

Okay, so `ath9k_htc` – that's a USB wireless driver, right? Interesting. This means I can probably reach it in virtualized environments. Think QEMU with USB emulation, or even raw_gadget setups. And of course, there's syzkaller with its USB fuzzing capabilities, especially the `syz_usb_connect` call. Now, the key question is: has syzkaller actually *fuzzed* `ath9k_htc`? I need to check if syzkaller has descriptions for it. Or, even simpler, if USB devices are known to probe `ath9k_htc`.

Right, let's see. In the Linux kernel, I know that `drivers/net/wireless/ath/ath9k/hif_usb.c` is the likely location because it registers a `usb_driver`. Time to dig into `hif_usb.c`. I'm looking for USB IDs – specific VID/PIDs. Ah, there they are: AR9271, AR7010, the usual suspects (USB_DEVICE(0x0cf3, 0x9271), and so on). That's the hook.

So, when a USB device matching those VID/PIDs gets connected – like through syzkaller's `syz_usb_connect` – the driver *should* probe. Then, it sets up `debugfs` if `CONFIG_ATH9K_HTC_DEBUGFS` or `CONFIG_ATH9K_COMMON_SPECTRAL` are enabled. And from there, it's all about receiving packets via USB URBs (`ath9k_htc_rx_msg`, `ath9k_rx_prepare`), and processing those spectral scan FFT frames (`ath_cmn_process_fft`).

Hold on... I just remembered something important. Spectral scan configuration or relay files within `debugfs` can also be directly triggered from user space. I need to keep that in mind.

Okay, I need to understand the configuration requirements and dependencies more. Time to dive into the Kconfig for `ath9k`: `drivers/net/wireless/ath/ath9k/Kconfig`. I'll focus on `CONFIG_ATH9K_COMMON_SPECTRAL`, `CONFIG_ATH9K`, `CONFIG_ATH9K_HTC`, `CONFIG_ATH9K_DEBUGFS`, and `CONFIG_ATH9K_HTC_DEBUGFS` to get the full picture.



10/2 2026/09/06 05:48 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/ath/ath9k/Kconfig",
  "FirstLine": 165,
  "LineCount": 55
}

Results:
{
  "Contents": " 165:\t\t  of reach for the ath9k chip.\n 166:\t\n 167:\t\t  These devices are usually various network appliances, routers or\n 168:\t\t  access Points and such.\n 169:\t\n 170:\t\t  If unsure say N.\n 171:\t\n 172:\tconfig ATH9K_HTC\n 173:\t\ttristate \"Atheros HTC based wireless cards support\"\n 174:\t\tdepends on USB \u0026\u0026 MAC80211\n 175:\t\tselect MAC80211_LEDS if LEDS_CLASS=y || LEDS_CLASS=MAC80211\n 176:\t\tselect ATH9K_HW\n 177:\t\tselect ATH9K_COMMON\n 178:\t\thelp\n 179:\t\t  Support for Atheros HTC based cards.\n 180:\t\t  Chipsets supported: AR9271\n 181:\t\n 182:\t\t  For more information:\n 183:\t\t  https://wireless.wiki.kernel.org/en/users/Drivers/ath9k_htc\n 184:\t\n 185:\t\t  The built module will be ath9k_htc.\n 186:\t\n 187:\tconfig ATH9K_HTC_DEBUGFS\n 188:\t\tbool \"Atheros ath9k_htc debugging\"\n 189:\t\tdepends on ATH9K_HTC \u0026\u0026 DEBUG_FS\n 190:\t\tselect ATH9K_COMMON_DEBUG\n 191:\t\thelp\n 192:\t\t  Say Y, if you need access to ath9k_htc's statistics.\n 193:\t\t  As well as access to the FFT/spectral data.\n 194:\t\n 195:\tconfig ATH9K_HWRNG\n 196:\t\tbool \"Random number generator support\"\n 197:\t\tdepends on ATH9K \u0026\u0026 (HW_RANDOM = y || HW_RANDOM = ATH9K)\n 198:\t\tdefault n\n 199:\t\thelp\n 200:\t\t  This option incorporates the ADC register output as a source of\n 201:\t\t  randomness into Linux entropy pool (/dev/urandom and /dev/random)\n 202:\t\n 203:\t\t  Say Y, feeds the entropy directly from the WiFi driver to the input\n 204:\t\t  pool.\n 205:\t\n 206:\tconfig ATH9K_COMMON_SPECTRAL\n 207:\t\tbool \"Atheros ath9k/ath9k_htc spectral scan support\"\n 208:\t\tdepends on ATH9K_DEBUGFS || ATH9K_HTC_DEBUGFS\n 209:\t\tselect RELAY\n 210:\t\tdefault n\n 211:\t\thelp\n 212:\t\t  Say Y to enable access to the FFT/spectral data via debugfs.\n"
}

11/2 2026/09/06 05:48 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 23247
							output: 42
							thoughts: 17
						

Thoughts:
Here's my summary, as the thought process unfolds:

**Checking the Kconfig for `ATH9K_DEBUGFS`**

Okay, so we're diving into this issue... Let's not just assume where the problem lies. My first instinct is to double-check something that might be easily overlooked. Right now, I'm thinking, "Did we make sure that debugging is enabled?" Let's see if the `ATH9K_DEBUGFS` configuration option is enabled in the Kconfig. A lot of times, debugging features are conditionally compiled, and it's easy to miss that specific config. It's a quick sanity check, but important because if that's not enabled, we're not going to see any relevant debug information from that module. It might seem basic, but it's essential to not skip this step. This check makes sense from the perspective that if the feature is not configured, it's a hard barrier to seeing the information needed. I'll search that Kconfig now.



12/2 2026/09/06 05:48 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/ath/ath9k/Kconfig",
  "FirstLine": 140,
  "LineCount": 35
}

Results:
{
  "Contents": " 140:\t\t  a platform that can toggle the RF-Kill GPIO.\n 141:\t\n 142:\tconfig ATH9K_CHANNEL_CONTEXT\n 143:\t\tbool \"Channel Context support\"\n 144:\t\tdepends on ATH9K\n 145:\t\tdefault n\n 146:\t\thelp\n 147:\t\t  This option enables channel context support in ath9k, which is needed\n 148:\t\t  for multi-channel concurrency. Enable this if P2P PowerSave support\n 149:\t\t  is required.\n 150:\t\n 151:\tconfig ATH9K_PCOEM\n 152:\t\tbool \"Atheros ath9k support for PC OEM cards\" if EXPERT\n 153:\t\tdepends on ATH9K\n 154:\t\tdefault y\n 155:\t\n 156:\tconfig ATH9K_PCI_NO_EEPROM\n 157:\t\ttristate \"Atheros ath9k pci loader for EEPROM-less chips\"\n 158:\t\tdepends on ATH9K_PCI\n 159:\t\tdefault n\n 160:\t\thelp\n 161:\t\t  This separate driver provides a loader in order to support the\n 162:\t\t  AR500X to AR92XX-generation of ath9k PCI(e) WiFi chips, which have\n 163:\t\t  their initialization data (which contains the real PCI Device ID\n 164:\t\t  that ath9k will need) stored together with the calibration data out\n 165:\t\t  of reach for the ath9k chip.\n 166:\t\n 167:\t\t  These devices are usually various network appliances, routers or\n 168:\t\t  access Points and such.\n 169:\t\n 170:\t\t  If unsure say N.\n 171:\t\n 172:\tconfig ATH9K_HTC\n 173:\t\ttristate \"Atheros HTC based wireless cards support\"\n 174:\t\tdepends on USB \u0026\u0026 MAC80211\n"
}

13/2 2026/09/06 05:48 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 24046
							output: 37
							thoughts: 13
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Hunting Down ATH9K_DEBUGFS**

Okay, so I need to track down the `ATH9K_DEBUGFS` configuration option. My immediate strategy is to jump into the `Kconfig` files – that's the canonical place to find these settings and their dependencies. I'll need to figure out where the `ath9k` driver is configured, and from there navigate the dependency chain to locate the relevant option. Hopefully, it's not buried too deep within an obscure sub-menu. Time to get to work.



14/2 2026/09/06 05:48 tool grepper
0m Args:
{
  "Expression": "config ATH9K_DEBUGFS",
  "PathPrefix": "drivers/net/wireless/ath/ath9k"
}

Results:
{
  "Output": "drivers/net/wireless/ath/ath9k/Kconfig=48=config ATH9K_AHB\n--\ndrivers/net/wireless/ath/ath9k/Kconfig-57-\ndrivers/net/wireless/ath/ath9k/Kconfig:58:config ATH9K_DEBUGFS\ndrivers/net/wireless/ath/ath9k/Kconfig-59-\tbool \"Atheros ath9k debugging\"\n"
}

15/2 2026/09/06 05:48 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 24339
							output: 34
							thoughts: 32
						

Thoughts:
Okay, let's dive into this. Here's how I'd approach that:

**Investigating the Build Process for `common-spectral.o` in the ath9k Wireless Driver**

Right, so I need to figure out exactly how `common-spectral.o` gets compiled within the `ath9k` wireless driver. The most logical place to start is the `Makefile` within the relevant directory. Specifically, I'm going to look at `drivers/net/wireless/ath/ath9k/Makefile`. That file is the central orchestrator for how all the components within that specific module are built. It should contain the rules or instructions detailing the compilation process for any object files within that directory. I'm expecting to find either a direct rule for `common-spectral.o` or, more likely, a set of rules and dependencies that will ultimately lead to its creation. Time to crack open that Makefile and see what's what. This should give me a complete view of all dependencies and linking strategies to form the compiled module.



16/2 2026/09/06 05:48 tool grepper
0m Args:
{
  "Expression": "common-spectral",
  "PathPrefix": "drivers/net/wireless/ath/ath9k"
}

Results:
{
  "Output": "drivers/net/wireless/ath/ath9k/Makefile=65=ath9k_common-$(CONFIG_ATH9K_COMMON_DEBUG) += common-debug.o\ndrivers/net/wireless/ath/ath9k/Makefile:66:ath9k_common-$(CONFIG_ATH9K_COMMON_SPECTRAL) += common-spectral.o\ndrivers/net/wireless/ath/ath9k/Makefile-67-\n--\ndrivers/net/wireless/ath/ath9k/common.h-26-#include \"common-debug.h\"\ndrivers/net/wireless/ath/ath9k/common.h:27:#include \"common-spectral.h\"\ndrivers/net/wireless/ath/ath9k/common.h-28-\n"
}

17/2 2026/09/06 05:48 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 24816
							output: 43
							thoughts: 244
						

Thoughts:
**My Assessment of the ath9k_htc Driver for Fuzzing**

Okay, let's break this down. First, `ath9k_common` gets built when `ATH9K_COMMON` is enabled, which is tied to either `ATH9K` or `ATH9K_HTC`. Makes sense. If `ATH9K_COMMON_SPECTRAL` is toggled on, then `common-spectral.o` gets included within `ath9k_common`. Good, that's expected.

Now, `ath9k_htc` itself is a USB driver, which means it hinges on `USB` and `MAC80211`, obviously. The real question is, can we actually reach `ath9k_htc` effectively in syzkaller fuzzing? It's the standard question for this sort of analysis: how accessible is it?

Let me refer back to the Section 1, 2, 3 classifications. From the description, `ath9k_htc` falls under the category of drivers accessible via virtual buses, specifically, USB. This would mean USB emulation like raw_gadget, dummy_hcd, or, crucially, syzkaller USB fuzzing can be leveraged. Excellent, that's a positive sign.

Beyond that, we have debugfs and relay interfaces to explore. The spectral scan functionality within the driver creates debugfs entries like `spectral_scan`, `spectral_scan_ctl`, and `spectral_count`. I need to dig deeper into what debugfs files specifically the `common-spectral` component generates. These interfaces often provide a valuable point of interaction for fuzzing and bug detection.



18/2 2026/09/06 05:48 tool grepper
0m Args:
{
  "Expression": "debugfs_create_file",
  "PathPrefix": "drivers/net/wireless/ath/ath9k/common-spectral.c"
}

Results:
{
  "Output": "drivers/net/wireless/ath/ath9k/common-spectral.c=1019=static struct dentry *create_buf_file_handler(const char *filename,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1026-\ndrivers/net/wireless/ath/ath9k/common-spectral.c:1027:\tbuf_file = debugfs_create_file(filename, mode, parent, buf,\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1028-\t\t\t\t       \u0026relay_file_operations);\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.c=1061=void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1072-\ndrivers/net/wireless/ath/ath9k/common-spectral.c:1073:\tdebugfs_create_file(\"spectral_scan_ctl\",\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1074-\t\t\t    0600,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1076-\t\t\t    \u0026fops_spec_scan_ctl);\ndrivers/net/wireless/ath/ath9k/common-spectral.c:1077:\tdebugfs_create_file(\"spectral_short_repeat\",\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1078-\t\t\t    0600,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1080-\t\t\t    \u0026fops_spectral_short_repeat);\ndrivers/net/wireless/ath/ath9k/common-spectral.c:1081:\tdebugfs_create_file(\"spectral_count\",\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1082-\t\t\t    0600,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1084-\t\t\t    \u0026fops_spectral_count);\ndrivers/net/wireless/ath/ath9k/common-spectral.c:1085:\tdebugfs_create_file(\"spectral_period\",\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1086-\t\t\t    0600,\n--\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1088-\t\t\t    \u0026fops_spectral_period);\ndrivers/net/wireless/ath/ath9k/common-spectral.c:1089:\tdebugfs_create_file(\"spectral_fft_period\",\ndrivers/net/wireless/ath/ath9k/common-spectral.c-1090-\t\t\t    0600,\n"
}

19/2 2026/09/06 05:48 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 26182
							output: 195
							thoughts: 3236
						

Thoughts:
**Analysis of Spectral Scan Packet Processing in ath9k and ath9k_htc Drivers**

Okay, so here's the deal. When spectral scanning is enabled, either through the `spectral_scan_ctl` or mac80211 interfaces, and packets come in (specifically via USB in the `ath9k_htc` driver, which is crucial for our fuzzing strategy), `ath_cmn_process_fft` gets called. This function, in turn, calls `ath_cmn_count_fft_sample`. I need to ensure this is understood within the context of debugfs files, which are prime targets for fuzzing.

My primary focus here is understanding what changed in this code. The key functions I'm zeroing in on are: `ath_cmn_count_fft_sample` (static within `common-spectral.c`), `ath_cmn_process_fft` (non-static and an exported symbol in `common-spectral.c`), `ath9k_cmn_spectral_init_debug` (another exported symbol from `common-spectral.c`), `ath9k_init_debug` (in `debug.c`), and `ath9k_htc_init_debug` (in `htc_drv_debug.c`). I'm looking for any added or modified function calls, and the relationships between them.

The patch itself is the blueprint here. It looks like `ath_cmn_count_fft_sample` is now being used to increment `rx_spectral_sample_good` or `rx_spectral_sample_err` within `ath_cmn_process_fft` depending on the return value of the FFT handler. This is important to understand because that logic is directly exposed to fuzzing. A key modification seems to be the addition of a `struct ath_rx_stats *rx_stats` pointer. This gets set up within debug initialization functions: specifically, `ath9k_cmn_spectral_init_debug` now accepts `rx_stats` as an argument and it now takes and sets `spec_priv->rx_stats` in its initialization routine (which is a core change). It is also called during `ath9k_init_debug` and `ath9k_htc_init_debug`.

Now, the important part: is this reachable? Yes, using USB emulation, syzkaller and raw_gadget, or dummy_hcd which is within our reach for the `ath9k_htc` driver.  The critical configuration options required are `ATH9K_HTC`, `ATH9K_HTC_DEBUGFS`, `ATH9K_COMMON_SPECTRAL`, `ATH9K`, `ATH9K_DEBUGFS`, `USB`, and `MAC80211`.

We need to ensure that the key functions (`ath_cmn_process_fft`, `ath9k_cmn_spectral_init_debug`, `ath9k_htc_init_debug`, and `ath9k_init_debug`) are not lifecycle functions, and specific to the handling of spectral scan and debugfs.  This detailed analysis demonstrates that this is, in fact, the case. `ath_cmn_process_fft` is directly handling FFT frames, and debug initialization functions tie this process to debug interfaces.  The patch modifies stats tracking with the added pointer, and that adds a specific fuzzing target.



20/2 2026/09/06 05:49 tool set-results
0m Args:
{
  "EnableConfigs": [
    "ATH9K_COMMON_SPECTRAL",
    "ATH9K_HTC_DEBUGFS",
    "ATH9K_HTC",
    "ATH9K_DEBUGFS",
    "ATH9K"
  ],
  "FocusSymbols": [
    "ath_cmn_process_fft",
    "ath9k_cmn_spectral_init_debug",
    "ath9k_htc_init_debug",
    "ath9k_init_debug"
  ],
  "Reasoning": "The patch modifies the spectral scan debug initialization and FFT sample processing in the ath9k and ath9k_htc drivers. ath9k_htc is a USB-based wireless driver accessible in standard virtualized environments via USB emulation. The changes alter how spectral sample statistics are tracked and initialized across drivers sharing common spectral scan code, making it worth fuzzing.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "ATH9K_COMMON_SPECTRAL",
    "ATH9K_HTC_DEBUGFS",
    "ATH9K_HTC",
    "ATH9K_DEBUGFS",
    "ATH9K"
  ],
  "FocusSymbols": [
    "ath_cmn_process_fft",
    "ath9k_cmn_spectral_init_debug",
    "ath9k_htc_init_debug",
    "ath9k_init_debug"
  ],
  "Reasoning": "The patch modifies the spectral scan debug initialization and FFT sample processing in the ath9k and ath9k_htc drivers. ath9k_htc is a USB-based wireless driver accessible in standard virtualized environments via USB emulation. The changes alter how spectral sample statistics are tracked and initialized across drivers sharing common spectral scan code, making it worth fuzzing.",
  "WorthFuzzing": true
}

21/1 2026/09/06 05:49 action If
0m Args:
{
  "WorthFuzzing": true
}

Results:
null

22/2 2026/09/06 05:49 agent kmsan-evaluator
0m Model:
core

Args:
null

Results:
{
  "KMSANReasoning": "The patch fixes a type confusion issue between ath9k and ath9k_htc drivers in shared spectral scanning code (common-spectral.c), where common-\u003epriv was previously cast unconditionally to struct ath_softc *. The fix passes the driver-specific ath_rx_stats pointer during debug initialization and increments stats through spec_priv-\u003erx_stats with a NULL check.\n\nThis change only affects pointer assignment and statistic counter increments. It does not introduce or expose uninitialized memory, allocate uninitialized buffers, or perform copies to user space of uninitialized data. Any memory safety concerns (such as invalid pointer dereferences or type confusion) are adequately covered by KASAN. Therefore, a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

Instruction:
You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.

CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
  a comprehensive suite of debugging tools and sanitizers, including KASAN
  (out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
  (locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
  or page allocations) and kernel-to-user memory info-leaks.

Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.

Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.

Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
   attributes, ioctl output arguments, socket options, or BPF buffers) where fields
   or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
   or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
   could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
   uninitialized bytes of existing buffers.

Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
  dereferences, locking deadlocks, or use-after-free bugs (these are already caught
  by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
  or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.

Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
Target architecture: amd64

For your convenience, here is the diff of the changes:
commit 2937e854b8655b12e5b2d1cb764d00abfe4f9eb0
Author: syz-cluster <triage@syzkaller.com>
Date:   Sun Sep 6 05:47:31 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c
index ca01a07f6630c..d8be24ebcd247 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 011d8ab8b9744..0e2c7d6d34874 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 74a0134075cf9..042a4f542a943 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 9437d69877cc5..9d354b1d929c8 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);

23/3 2026/09/06 05:49 llm kmsan-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 4269
							output: 178
							thoughts: 1241
						

Thoughts:
**Analysis of the Wireless Patch: KMSAN Assessment**

Okay, let's break this patch down. My initial assessment is that this is a fix related to shared code between the `ath9k` and `ath9k_htc` drivers. The core issue revolves around how the `common-spectral.c` module, used by both, was incorrectly assuming the type of `common->priv`. This pointer was being cast to `struct ath_softc *`, but in the `ath9k_htc` case, it's actually something different (a `struct ath9k_htc_priv` or similar), leading to out-of-bounds reads/writes when accessing the statistics structure. Basically, a classic type confusion vulnerability.

The patch resolves this by passing the `struct ath_rx_stats *` pointer directly to `ath9k_cmn_spectral_init_debug`.  This pointer then gets stored in `spec_priv->rx_stats`, and this is used for counter increments in `ath_cmn_count_fft_sample`. In `ath9k`, this pointer comes from `sc->debug.stats.rxstats`, and in `ath9k_htc`, it comes from `priv->debug.rx_stats`. The crucial thing here is that the pointer is explicitly passed, not implicitly derived through a potentially incorrect type cast.

My main focus now is on memory safety. Does this introduce any uninitialized memory issues?  I've checked: this patch doesn't copy uninitialized memory to user space, it doesn't read uninitialized variables or struct fields (because `rx_stats` is initialized and checked). It doesn't modify conditional logic based on uninitialized data. The `rx_stats` pointer itself is initialized. This is a very targeted fix, and there are no new risks from uninitialized data.

Let me compare the before and after, to be certain: Before, `common->priv` was being cast to `struct ath_softc *sc`, and the code would increment the statistics directly. In `ath9k_htc`, this caused an invalid memory access. Now, we're passing the correct pointer, `rx_stats` which points to `sc->debug.stats.rxstats` or `priv->debug.rx_stats`. The core functionality (incrementing counters) remains, but the memory access is now done with a correct pointer.

Now, let's address KMSAN directly. The `NeedsKMSAN` rule states it's **false** if the patch primarily fixes issues like out-of-bounds access (which it does), and if all stack/heap structures are initialized.  Everything here *is* initialized. We aren't reading uninitialized memory. There's no info-leak risk. So, the patch meets the conditions for `NeedsKMSAN=false`. Standard sanitizers and KASAN will catch the problems addressed by this patch.

My conclusion is clear: This patch is a memory safety improvement. It fixes a type confusion, preventing out-of-bounds reads/writes and potential crashes.  KMSAN isn't necessary here; KASAN and standard sanitizers handle the risks.  Let's set the results and move on.



24/3 2026/09/06 05:49 tool set-results
0m Args:
{
  "KMSANReasoning": "The patch fixes a type confusion issue between ath9k and ath9k_htc drivers in shared spectral scanning code (common-spectral.c), where common-\u003epriv was previously cast unconditionally to struct ath_softc *. The fix passes the driver-specific ath_rx_stats pointer during debug initialization and increments stats through spec_priv-\u003erx_stats with a NULL check.\n\nThis change only affects pointer assignment and statistic counter increments. It does not introduce or expose uninitialized memory, allocate uninitialized buffers, or perform copies to user space of uninitialized data. Any memory safety concerns (such as invalid pointer dereferences or type confusion) are adequately covered by KASAN. Therefore, a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

Results:
{
  "KMSANReasoning": "The patch fixes a type confusion issue between ath9k and ath9k_htc drivers in shared spectral scanning code (common-spectral.c), where common-\u003epriv was previously cast unconditionally to struct ath_softc *. The fix passes the driver-specific ath_rx_stats pointer during debug initialization and increments stats through spec_priv-\u003erx_stats with a NULL check.\n\nThis change only affects pointer assignment and statistic counter increments. It does not introduce or expose uninitialized memory, allocate uninitialized buffers, or perform copies to user space of uninitialized data. Any memory safety concerns (such as invalid pointer dereferences or type confusion) are adequately covered by KASAN. Therefore, a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)