| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/08/06 15:57 | flow | patch-triage |
12mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the ath12k driver, which is a vendor-specific driver for Qualcomm Wi-Fi 7 devices. This driver requires physical PCIe or AHB hardware that is not emulated in standard QEMU environments, making the code unreachable during generic fuzzing. Furthermore, the changes primarily involve debugfs statistics and bounds checking for those statistics.",
"WorthFuzzing": false
} |
| 1/1 | 2026/08/06 15:57 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 60d0fecda7c4d0348db4faf74ef4552e8b26482b\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Thu Aug 6 15:57:21 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c\nindex d54995b7adb27..ed7045a2a3803 100644\n--- a/drivers/net/wireless/ath/ath12k/debugfs.c\n+++ b/drivers/net/wireless/ath/ath12k/debugfs.c\n@@ -1071,6 +1071,20 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,\n \t\t[HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET] = \"PN err\",\n \t\t[HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED] = \"Desc blocked\"};\n \n+\tstatic const char *wbm_rx_drop[WBM_ERR_DROP_MAX] = {\n+\t\t[WBM_ERR_GET_SW_DESC] = \"SW desc error\",\n+\t\t[WBM_ERR_DESC_PARSE] = \"Desc parse error\",\n+\t\t[WBM_ERR_DROP_INV_HW_ID] = \"Invalid hw id\",\n+\t\t[WBM_ERR_DROP_NULL_PRTNR_DP] = \"Null Partner dp\",\n+\t\t[WBM_ERR_DROP_NULL_PROC_DP] = \"Process Null Partner dp\",\n+\t\t[WBM_ERR_DROP_NULL_PDEV] = \"Null Pdev\",\n+\t\t[WBM_ERR_DROP_NULL_AR] = \"Null ar\",\n+\t\t[WBM_ERR_DROP_CAC_RUNNING] = \"CAC Running\",\n+\t\t[WBM_ERR_DROP_SG] = \"Scatter Gather\",\n+\t\t[WBM_ERR_DROP_INV_NWIFI_HDR] = \"Invalid NWifi Hdr len\",\n+\t\t[WBM_ERR_DROP_REO_GENERIC] = \"REO Generic\",\n+\t\t[WBM_ERR_DROP_RXDMA_GENERIC] = \"RXDMA Generic\"};\n+\n \tstatic const char *wbm_rel_src[HAL_WBM_REL_SRC_MODULE_MAX] = {\n \t\t[HAL_WBM_REL_SRC_MODULE_TQM] = \"TQM\",\n \t\t[HAL_WBM_REL_SRC_MODULE_RXDMA] = \"Rxdma\",\n@@ -1095,13 +1109,32 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,\n \n \tfor (i = 0; i \u003c HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)\n \t\tlen += scnprintf(buf + len, size - len, \"%s: %u\\n\",\n-\t\t\t\t rxdma_err[i], device_stats-\u003erxdma_error[i]);\n+\t\t\t\t rxdma_err[i], device_stats-\u003ewbm_err.rxdma_error[i]);\n \n \tlen += scnprintf(buf + len, size - len, \"\\nREO errors:\\n\");\n \n \tfor (i = 0; i \u003c HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)\n \t\tlen += scnprintf(buf + len, size - len, \"%s: %u\\n\",\n-\t\t\t\t reo_err[i], device_stats-\u003ereo_error[i]);\n+\t\t\t\t reo_err[i], device_stats-\u003ewbm_err.reo_error[i]);\n+\n+\tlen += scnprintf(buf + len, size - len, \"\\nWBM Rx Drop Count:\\n\");\n+\tfor (i = 0; i \u003c WBM_ERR_DROP_MAX; i++)\n+\t\tlen += scnprintf(buf + len, size - len, \"%s: %u\\n\",\n+\t\t\t\t wbm_rx_drop[i], device_stats-\u003ewbm_err.drop[i]);\n+\n+\tlen += scnprintf(buf + len, size - len,\n+\t\t\t \"\\nWBM SW desc fallback (HW CC not done): %u\\n\",\n+\t\t\t device_stats-\u003ewbm_err.sw_desc_fallback);\n+\n+\tlen += scnprintf(buf + len, size - len, \"\\nREO sent to stack\\n\");\n+\tfor (i = 0; i \u003c DP_REO_DST_RING_MAX; i++) {\n+\t\tlen += scnprintf(buf + len, size - len, \"ring%d:\", i);\n+\t\tfor (j = 0; j \u003c ab-\u003eag-\u003enum_devices; j++)\n+\t\t\tlen += scnprintf(buf + len, size - len,\n+\t\t\t\t\t \"\\t%d:%u\", j,\n+\t\t\t\t\t device_stats-\u003esent_to_stack[i][j]);\n+\t\tlen += scnprintf(buf + len, size - len, \"\\n\");\n+\t}\n \n \tlen += scnprintf(buf + len, size - len, \"\\nHAL REO errors:\\n\");\n \n@@ -1117,6 +1150,11 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,\n \t\tlen += scnprintf(buf + len, size - len, \"ring%d: %u\\n\",\n \t\t\t\t i, device_stats-\u003etx_err.desc_na[i]);\n \n+\tlen += scnprintf(buf + len, size - len, \"\\nTX Descriptor Pool Alloc Failures:\\n\");\n+\tfor (i = 0; i \u003c ATH12K_HW_MAX_QUEUES; i++)\n+\t\tlen += scnprintf(buf + len, size - len, \"pool%d: %u\\n\",\n+\t\t\t\t i, device_stats-\u003etx_err.txbuf_na[i]);\n+\n \tlen += scnprintf(buf + len, size - len,\n \t\t\t \"\\nMisc Transmit Failures: %d\\n\",\n \t\t\t atomic_read(\u0026device_stats-\u003etx_err.misc_fail));\n@@ -1181,7 +1219,7 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,\n \tlen += scnprintf(buf + len, size - len, \"\\nREO Rx Received:\\n\");\n \n \tfor (i = 0; i \u003c DP_REO_DST_RING_MAX; i++) {\n-\t\tlen += scnprintf(buf + len, size - len, \"Ring%d:\", i + 1);\n+\t\tlen += scnprintf(buf + len, size - len, \"ring%d:\", i);\n \n \t\tfor (j = 0; j \u003c ab-\u003eag-\u003enum_devices; j++) {\n \t\t\tlen += scnprintf(buf + len, size - len,\n@@ -1215,8 +1253,41 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,\n \treturn ret;\n }\n \n+static ssize_t\n+ath12k_debugfs_write_device_dp_stats(struct file *file,\n+\t\t\t\t const char __user *user_buf,\n+\t\t\t\t size_t count, loff_t *ppos)\n+{\n+\tstruct ath12k_base *ab = file-\u003eprivate_data;\n+\tstruct ath12k_dp *dp = ath12k_ab_to_dp(ab);\n+\tstruct ath12k_device_dp_stats *device_stats = \u0026dp-\u003edevice_stats;\n+\tchar buf[20] = {};\n+\tint ret;\n+\n+\tif (count \u003e= sizeof(buf))\n+\t\treturn -EINVAL;\n+\n+\tret = copy_from_user(buf, user_buf, count);\n+\tif (ret)\n+\t\treturn -EFAULT;\n+\n+\t/* drop the possible '\\n' from the end */\n+\tif (count \u003e 0 \u0026\u0026 buf[count - 1] == '\\n')\n+\t\tbuf[count - 1] = '\\0';\n+\n+\tif (!strcmp(buf, \"reset\")) {\n+\t\tmemset(device_stats, 0, sizeof(*device_stats));\n+\t\treturn count;\n+\t}\n+\n+\tath12k_warn(ab, \"unsupported command: %s\\n\", buf);\n+\n+\treturn -EINVAL;\n+}\n+\n static const struct file_operations fops_device_dp_stats = {\n \t.read = ath12k_debugfs_dump_device_dp_stats,\n+\t.write = ath12k_debugfs_write_device_dp_stats,\n \t.open = simple_open,\n \t.owner = THIS_MODULE,\n \t.llseek = default_llseek,\n@@ -1227,7 +1298,7 @@ void ath12k_debugfs_pdev_create(struct ath12k_base *ab)\n \tdebugfs_create_file(\"simulate_fw_crash\", 0600, ab-\u003edebugfs_soc, ab,\n \t\t\t \u0026fops_simulate_fw_crash);\n \n-\tdebugfs_create_file(\"device_dp_stats\", 0400, ab-\u003edebugfs_soc, ab,\n+\tdebugfs_create_file(\"device_dp_stats\", 0600, ab-\u003edebugfs_soc, ab,\n \t\t\t \u0026fops_device_dp_stats);\n }\n \ndiff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h\nindex bef0f2ba0560f..289aede6dabb6 100644\n--- a/drivers/net/wireless/ath/ath12k/dp.h\n+++ b/drivers/net/wireless/ath/ath12k/dp.h\n@@ -7,6 +7,7 @@\n #ifndef ATH12K_DP_H\n #define ATH12K_DP_H\n \n+#include \"dp_stats.h\"\n #include \"hw.h\"\n #include \"dp_htt.h\"\n #include \"dp_cmn.h\"\n@@ -429,19 +430,27 @@ struct ath12k_dp_arch_ops {\n struct ath12k_device_dp_tx_err_stats {\n \t/* TCL Ring Descriptor unavailable */\n \tu32 desc_na[DP_TCL_NUM_RING_MAX];\n+\t/* TX descriptor pool exhausted (per pool_id / traffic class) */\n+\tu32 txbuf_na[ATH12K_HW_MAX_QUEUES];\n \t/* Other failures during dp_tx due to mem allocation failure\n \t * idr unavailable etc.\n \t */\n \tatomic_t misc_fail;\n };\n \n+struct ath12k_device_dp_rx_wbm_err_stats {\n+\tu32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];\n+\tu32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX];\n+\tu32 drop[WBM_ERR_DROP_MAX];\n+\tu32 sw_desc_fallback;\n+};\n+\n struct ath12k_device_dp_stats {\n \tu32 err_ring_pkts;\n \tu32 invalid_rbm;\n-\tu32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];\n-\tu32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX];\n \tu32 hal_reo_error[DP_REO_DST_RING_MAX];\n \tstruct ath12k_device_dp_tx_err_stats tx_err;\n+\tstruct ath12k_device_dp_rx_wbm_err_stats wbm_err;\n \tu32 reo_rx[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES];\n \tu32 rx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX][ATH12K_MAX_DEVICES];\n \tu32 tqm_rel_reason[MAX_TQM_RELEASE_REASON];\n@@ -450,6 +459,7 @@ struct ath12k_device_dp_stats {\n \tu32 tx_enqueued[DP_TCL_NUM_RING_MAX];\n \tu32 tx_completed[DP_TCL_NUM_RING_MAX];\n \tu32 reo_excep_msdu_buf_type;\n+\tu32 sent_to_stack[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES];\n };\n \n struct ath12k_dp {\ndiff --git a/drivers/net/wireless/ath/ath12k/dp_stats.h b/drivers/net/wireless/ath/ath12k/dp_stats.h\nnew file mode 100644\nindex 0000000000000..04d3892acff32\n--- /dev/null\n+++ b/drivers/net/wireless/ath/ath12k/dp_stats.h\n@@ -0,0 +1,25 @@\n+/* SPDX-License-Identifier: BSD-3-Clause-Clear */\n+/*\n+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.\n+ */\n+\n+#ifndef ATH12K_DP_STATS_H\n+#define ATH12K_DP_STATS_H\n+\n+enum ath12k_wbm_err_drop_reason {\n+\tWBM_ERR_GET_SW_DESC,\n+\tWBM_ERR_DESC_PARSE,\n+\tWBM_ERR_DROP_INV_HW_ID,\n+\tWBM_ERR_DROP_NULL_PRTNR_DP,\n+\tWBM_ERR_DROP_NULL_PROC_DP,\n+\tWBM_ERR_DROP_NULL_PDEV,\n+\tWBM_ERR_DROP_NULL_AR,\n+\tWBM_ERR_DROP_CAC_RUNNING,\n+\tWBM_ERR_DROP_SG,\n+\tWBM_ERR_DROP_INV_NWIFI_HDR,\n+\tWBM_ERR_DROP_REO_GENERIC,\n+\tWBM_ERR_DROP_RXDMA_GENERIC,\n+\tWBM_ERR_DROP_MAX,\n+};\n+\n+#endif /* ATH12K_DP_STATS_H */\ndiff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c\nindex 95d87dd67872f..d96d8301565cb 100644\n--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c\n+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c\n@@ -12,6 +12,15 @@\n #include \"hal_wcn7850.h\"\n #include \"hal_qcc2072.h\"\n \n+static void\n+ath12k_wifi7_dp_rx_wbm_err_free_skb(struct ath12k_dp *dp,\n+\t\t\t\t struct sk_buff *msdu,\n+\t\t\t\t enum ath12k_wbm_err_drop_reason drop_reason)\n+{\n+\tdp-\u003edevice_stats.wbm_err.drop[drop_reason]++;\n+\tdev_kfree_skb_any(msdu);\n+}\n+\n static u16 ath12k_wifi7_dp_rx_get_peer_id(struct ath12k_dp *dp,\n \t\t\t\t\t enum ath12k_peer_metadata_version ver,\n \t\t\t\t\t __le32 peer_metadata)\n@@ -642,7 +651,10 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_dp *dp,\n \t\t\tdev_kfree_skb_any(msdu);\n \t\t\tcontinue;\n \t\t}\n-\n+\t\tif (likely(ring_id \u003c DP_REO_DST_RING_MAX))\n+\t\t\tdp-\u003edevice_stats.sent_to_stack[ring_id][partner_dp-\u003edevice_id]++;\n+\t\telse\n+\t\t\tWARN_ON_ONCE(1);\n \t\tath12k_dp_rx_deliver_msdu(dp_pdev, napi, msdu, \u0026rx_info);\n \t}\n \n@@ -1614,6 +1626,7 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k_pdev_dp *dp_pdev,\n \t\t/* First buffer will be freed by the caller, so deduct it's length */\n \t\tmsdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz);\n \t\tath12k_wifi7_dp_rx_null_q_desc_sg_drop(dp, msdu_len, msdu_list);\n+\t\tdp-\u003edevice_stats.wbm_err.drop[WBM_ERR_DROP_SG]++;\n \t\treturn -EINVAL;\n \t}\n \n@@ -1649,8 +1662,10 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k_pdev_dp *dp_pdev,\n \t\tskb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);\n \t\tskb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);\n \t}\n-\tif (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, msdu, rx_info)))\n+\tif (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, msdu, rx_info))) {\n+\t\tdp-\u003edevice_stats.wbm_err.drop[WBM_ERR_DROP_INV_NWIFI_HDR]++;\n \t\treturn -EINVAL;\n+\t}\n \n \tath12k_dp_rx_h_ppdu(dp_pdev, rx_info);\n \tret = ath12k_wifi7_dp_rx_h_mpdu(dp_pdev, msdu, rx_info);\n@@ -1763,7 +1778,10 @@ static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev,\n \tstruct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);\n \tbool drop = false;\n \n-\tdp-\u003edevice_stats.rxdma_error[rxcb-\u003eerr_code]++;\n+\tif (likely(rxcb-\u003eerr_code \u003c HAL_REO_ENTR_RING_RXDMA_ECODE_MAX))\n+\t\tdp-\u003edevice_stats.wbm_err.rxdma_error[rxcb-\u003eerr_code]++;\n+\telse\n+\t\tWARN_ON_ONCE(1);\n \n \tswitch (rxcb-\u003eerr_code) {\n \tcase HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR:\n@@ -1780,6 +1798,7 @@ static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev,\n \t\t/* TODO: Review other rxdma error code to check if anything is\n \t\t * worth reporting to mac80211\n \t\t */\n+\t\tdp-\u003edevice_stats.wbm_err.drop[WBM_ERR_DROP_RXDMA_GENERIC]++;\n \t\tdrop = true;\n \t\tbreak;\n \t}\n@@ -1796,7 +1815,10 @@ static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k_pdev_dp *dp_pdev,\n \tstruct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);\n \tbool drop = false;\n \n-\tdp-\u003edevice_stats.reo_error[rxcb-\u003eerr_code]++;\n+\tif (likely(rxcb-\u003eerr_code \u003c HAL_REO_DEST_RING_ERROR_CODE_MAX))\n+\t\tdp-\u003edevice_stats.wbm_err.reo_error[rxcb-\u003eerr_code]++;\n+\telse\n+\t\tWARN_ON_ONCE(1);\n \n \tswitch (rxcb-\u003eerr_code) {\n \tcase HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO:\n@@ -1813,6 +1835,7 @@ static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k_pdev_dp *dp_pdev,\n \t\t/* TODO: Review other errors and process them to mac80211\n \t\t * as appropriate.\n \t\t */\n+\t\tdp-\u003edevice_stats.wbm_err.drop[WBM_ERR_DROP_REO_GENERIC]++;\n \t\tdrop = true;\n \t\tbreak;\n \t}\n@@ -1935,6 +1958,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,\n \t\tret = ath12k_wifi7_hal_wbm_desc_parse_err(dp, rx_desc,\n \t\t\t\t\t\t\t \u0026err_info);\n \t\tif (ret) {\n+\t\t\tdp-\u003edevice_stats.wbm_err.drop[WBM_ERR_DESC_PARSE]++;\n \t\t\tath12k_warn(ab, \"failed to parse rx error in wbm_rel ring desc %d\\n\",\n \t\t\t\t ret);\n \t\t\tcontinue;\n@@ -1944,8 +1968,10 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,\n \n \t\t/* retry manual desc retrieval if hw cc is not done */\n \t\tif (!desc_info) {\n+\t\t\tdp-\u003edevice_stats.wbm_err.sw_desc_fallback++;\n \t\t\tdesc_info = ath12k_dp_get_rx_desc(dp, err_info.cookie);\n \t\t\tif (!desc_info) {\n+\t\t\t\tdp-\u003edevice_stats.wbm_err.drop[WBM_ERR_GET_SW_DESC]++;\n \t\t\t\tath12k_warn(ab, \"Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\\n\",\n \t\t\t\t\t err_info.cookie);\n \t\t\t\tcontinue;\n@@ -1961,7 +1987,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,\n \t\tdevice_id = desc_info-\u003edevice_id;\n \t\tpartner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id);\n \t\tif (unlikely(!partner_dp)) {\n-\t\t\tdev_kfree_skb_any(msdu);\n+\t\t\tath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,\n+\t\t\t\t\t\t\t WBM_ERR_DROP_NULL_PRTNR_DP);\n \n \t\t\t/* In any case continuation bit is set\n \t\t\t * in the previous record, cleanup scatter_msdu_list\n@@ -2007,7 +2034,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,\n \t\thw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_dp-\u003ehal,\n \t\t\t\t\t\t\t msdu_data);\n \t\tif (hw_link_id \u003e= ATH12K_GROUP_MAX_RADIO) {\n-\t\t\tdev_kfree_skb_any(msdu);\n+\t\t\tath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,\n+\t\t\t\t\t\t\t WBM_ERR_DROP_INV_HW_ID);\n \n \t\t\t/* In any case continuation bit is set\n \t\t\t * in the previous record, cleanup scatter_msdu_list\n@@ -2068,7 +2096,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,\n \t\t\tath12k_dbg(ab, ATH12K_DBG_DATA,\n \t\t\t\t \"Unable to process WBM error msdu due to invalid hw link id %d device id %d\\n\",\n \t\t\t\t hw_link_id, device_id);\n-\t\t\tdev_kfree_skb_any(msdu);\n+\t\t\tath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,\n+\t\t\t\t\t\t\t WBM_ERR_DROP_NULL_PROC_DP);\n \t\t\tcontinue;\n \t\t}\n \n@@ -2077,18 +2106,21 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,\n \n \t\tdp_pdev = ath12k_dp_to_pdev_dp(partner_dp, pdev_idx);\n \t\tif (!dp_pdev) {\n-\t\t\tdev_kfree_skb_any(msdu);\n+\t\t\tath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,\n+\t\t\t\t\t\t\t WBM_ERR_DROP_NULL_PDEV);\n \t\t\tcontinue;\n \t\t}\n \t\tar = ath12k_pdev_dp_to_ar(dp_pdev);\n \n \t\tif (!ar || !rcu_dereference(ar-\u003eab-\u003epdevs_active[pdev_idx])) {\n-\t\t\tdev_kfree_skb_any(msdu);\n+\t\t\tath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,\n+\t\t\t\t\t\t\t WBM_ERR_DROP_NULL_AR);\n \t\t\tcontinue;\n \t\t}\n \n \t\tif (test_bit(ATH12K_FLAG_CAC_RUNNING, \u0026ar-\u003edev_flags)) {\n-\t\t\tdev_kfree_skb_any(msdu);\n+\t\t\tath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,\n+\t\t\t\t\t\t\t WBM_ERR_DROP_CAC_RUNNING);\n \t\t\tcontinue;\n \t\t}\n \ndiff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c\nindex 587d58eeccfa5..f572aa581d117 100644\n--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c\n+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c\n@@ -167,8 +167,10 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a\n \ttx_ring = \u0026dp-\u003etx_ring[ti.ring_id];\n \n \ttx_desc = ath12k_dp_tx_assign_buffer(dp, pool_id);\n-\tif (!tx_desc)\n+\tif (!tx_desc) {\n+\t\tdp-\u003edevice_stats.tx_err.txbuf_na[pool_id]++;\n \t\treturn -ENOMEM;\n+\t}\n \n \tdp_link_vif = ath12k_dp_vif_to_dp_link_vif(\u0026ahvif-\u003edp_vif, arvif-\u003elink_id);\n \n@@ -575,18 +577,21 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_dp *dp, void *desc,\n {\n \tstruct htt_tx_wbm_completion *status_desc;\n \tstruct ath12k_dp_htt_wbm_tx_status ts = {};\n-\tenum hal_wbm_htt_tx_comp_status wbm_status;\n+\tenum hal_wbm_htt_tx_comp_status htt_status;\n \tu16 peer_id;\n \n \tstatus_desc = desc;\n \n-\twbm_status = le32_get_bits(status_desc-\u003einfo0,\n+\thtt_status = le32_get_bits(status_desc-\u003einfo0,\n \t\t\t\t HTT_TX_WBM_COMP_INFO0_STATUS);\n-\tdp-\u003edevice_stats.fw_tx_status[wbm_status]++;\n+\tif (likely(htt_status \u003c MAX_FW_TX_STATUS))\n+\t\tdp-\u003edevice_stats.fw_tx_status[htt_status]++;\n+\telse\n+\t\tWARN_ON_ONCE(1);\n \n-\tswitch (wbm_status) {\n+\tswitch (htt_status) {\n \tcase HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:\n-\t\tts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK);\n+\t\tts.acked = true;\n \t\tts.ack_rssi = le32_get_bits(status_desc-\u003einfo2,\n \t\t\t\t\t HTT_TX_WBM_COMP_INFO2_ACK_RSSI);\n \n@@ -608,7 +613,7 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_dp *dp, void *desc,\n \t\t */\n \t\tbreak;\n \tdefault:\n-\t\tath12k_warn(dp-\u003eab, \"Unknown htt wbm tx status %d\\n\", wbm_status);\n+\t\tath12k_warn(dp-\u003eab, \"Unknown htt tx status %d\\n\", htt_status);\n \t\tbreak;\n \t}\n }\n@@ -984,11 +989,17 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_dp *dp, int ring_id)\n \t\t/* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */\n \t\tbuf_rel_source = le32_get_bits(tx_status-\u003einfo0,\n \t\t\t\t\t HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE);\n-\t\tdp-\u003edevice_stats.tx_wbm_rel_source[buf_rel_source]++;\n+\t\tif (likely(buf_rel_source \u003c HAL_WBM_REL_SRC_MODULE_MAX))\n+\t\t\tdp-\u003edevice_stats.tx_wbm_rel_source[buf_rel_source]++;\n+\t\telse\n+\t\t\tWARN_ON_ONCE(1);\n \n \t\trel_status = le32_get_bits(tx_status-\u003einfo0,\n \t\t\t\t\t HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON);\n-\t\tdp-\u003edevice_stats.tqm_rel_reason[rel_status]++;\n+\t\tif (likely(rel_status \u003c MAX_TQM_RELEASE_REASON))\n+\t\t\tdp-\u003edevice_stats.tqm_rel_reason[rel_status]++;\n+\t\telse\n+\t\t\tWARN_ON_ONCE(1);\n \n \t\t/* Release descriptor as soon as extracting necessary info\n \t\t * to reduce contention\ndiff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c\nindex 49c6932897094..60e7a36097f12 100644\n--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c\n+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c\n@@ -329,7 +329,10 @@ int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_dp *dp,\n \t\t\t\t HAL_REO_DEST_RING_INFO0_PUSH_REASON);\n \terr_code = le32_get_bits(desc-\u003einfo0,\n \t\t\t\t HAL_REO_DEST_RING_INFO0_ERROR_CODE);\n-\tdp-\u003edevice_stats.reo_error[err_code]++;\n+\tif (likely(err_code \u003c HAL_REO_DEST_RING_ERROR_CODE_MAX))\n+\t\tdp-\u003edevice_stats.wbm_err.reo_error[err_code]++;\n+\telse\n+\t\tWARN_ON_ONCE(1);\n \n \tif (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED \u0026\u0026\n \t push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {\n"
} |
| 2/1 | 2026/08/06 15:57 | agent | patch-evaluator |
12mModel:best-expensive Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the ath12k driver, which is a vendor-specific driver for Qualcomm Wi-Fi 7 devices. This driver requires physical PCIe or AHB hardware that is not emulated in standard QEMU environments, making the code unreachable during generic fuzzing. Furthermore, the changes primarily involve debugfs statistics and bounds checking for those statistics.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU. - Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove) that are executed only during PCI hot-unplug or sysfs driver unbind operations. If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. Prefer non-static, non-inlined API entrypoint functions over internal static helper functions (which are inlined by the compiler and do not have distinct symbol addresses). 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs output array, and DO NOT add a '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: For your convenience, here is the diff of the changes:
commit 60d0fecda7c4d0348db4faf74ef4552e8b26482b
Author: syz-cluster <triage@syzkaller.com>
Date: Thu Aug 6 15:57:21 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c
index d54995b7adb27..ed7045a2a3803 100644
--- a/drivers/net/wireless/ath/ath12k/debugfs.c
+++ b/drivers/net/wireless/ath/ath12k/debugfs.c
@@ -1071,6 +1071,20 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
[HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET] = "PN err",
[HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED] = "Desc blocked"};
+ static const char *wbm_rx_drop[WBM_ERR_DROP_MAX] = {
+ [WBM_ERR_GET_SW_DESC] = "SW desc error",
+ [WBM_ERR_DESC_PARSE] = "Desc parse error",
+ [WBM_ERR_DROP_INV_HW_ID] = "Invalid hw id",
+ [WBM_ERR_DROP_NULL_PRTNR_DP] = "Null Partner dp",
+ [WBM_ERR_DROP_NULL_PROC_DP] = "Process Null Partner dp",
+ [WBM_ERR_DROP_NULL_PDEV] = "Null Pdev",
+ [WBM_ERR_DROP_NULL_AR] = "Null ar",
+ [WBM_ERR_DROP_CAC_RUNNING] = "CAC Running",
+ [WBM_ERR_DROP_SG] = "Scatter Gather",
+ [WBM_ERR_DROP_INV_NWIFI_HDR] = "Invalid NWifi Hdr len",
+ [WBM_ERR_DROP_REO_GENERIC] = "REO Generic",
+ [WBM_ERR_DROP_RXDMA_GENERIC] = "RXDMA Generic"};
+
static const char *wbm_rel_src[HAL_WBM_REL_SRC_MODULE_MAX] = {
[HAL_WBM_REL_SRC_MODULE_TQM] = "TQM",
[HAL_WBM_REL_SRC_MODULE_RXDMA] = "Rxdma",
@@ -1095,13 +1109,32 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
len += scnprintf(buf + len, size - len, "%s: %u\n",
- rxdma_err[i], device_stats->rxdma_error[i]);
+ rxdma_err[i], device_stats->wbm_err.rxdma_error[i]);
len += scnprintf(buf + len, size - len, "\nREO errors:\n");
for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
len += scnprintf(buf + len, size - len, "%s: %u\n",
- reo_err[i], device_stats->reo_error[i]);
+ reo_err[i], device_stats->wbm_err.reo_error[i]);
+
+ len += scnprintf(buf + len, size - len, "\nWBM Rx Drop Count:\n");
+ for (i = 0; i < WBM_ERR_DROP_MAX; i++)
+ len += scnprintf(buf + len, size - len, "%s: %u\n",
+ wbm_rx_drop[i], device_stats->wbm_err.drop[i]);
+
+ len += scnprintf(buf + len, size - len,
+ "\nWBM SW desc fallback (HW CC not done): %u\n",
+ device_stats->wbm_err.sw_desc_fallback);
+
+ len += scnprintf(buf + len, size - len, "\nREO sent to stack\n");
+ for (i = 0; i < DP_REO_DST_RING_MAX; i++) {
+ len += scnprintf(buf + len, size - len, "ring%d:", i);
+ for (j = 0; j < ab->ag->num_devices; j++)
+ len += scnprintf(buf + len, size - len,
+ "\t%d:%u", j,
+ device_stats->sent_to_stack[i][j]);
+ len += scnprintf(buf + len, size - len, "\n");
+ }
len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
@@ -1117,6 +1150,11 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
len += scnprintf(buf + len, size - len, "ring%d: %u\n",
i, device_stats->tx_err.desc_na[i]);
+ len += scnprintf(buf + len, size - len, "\nTX Descriptor Pool Alloc Failures:\n");
+ for (i = 0; i < ATH12K_HW_MAX_QUEUES; i++)
+ len += scnprintf(buf + len, size - len, "pool%d: %u\n",
+ i, device_stats->tx_err.txbuf_na[i]);
+
len += scnprintf(buf + len, size - len,
"\nMisc Transmit Failures: %d\n",
atomic_read(&device_stats->tx_err.misc_fail));
@@ -1181,7 +1219,7 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
len += scnprintf(buf + len, size - len, "\nREO Rx Received:\n");
for (i = 0; i < DP_REO_DST_RING_MAX; i++) {
- len += scnprintf(buf + len, size - len, "Ring%d:", i + 1);
+ len += scnprintf(buf + len, size - len, "ring%d:", i);
for (j = 0; j < ab->ag->num_devices; j++) {
len += scnprintf(buf + len, size - len,
@@ -1215,8 +1253,41 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
return ret;
}
+static ssize_t
+ath12k_debugfs_write_device_dp_stats(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath12k_base *ab = file->private_data;
+ struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
+ struct ath12k_device_dp_stats *device_stats = &dp->device_stats;
+ char buf[20] = {};
+ int ret;
+
+ if (count >= sizeof(buf))
+ return -EINVAL;
+
+ ret = copy_from_user(buf, user_buf, count);
+ if (ret)
+ return -EFAULT;
+
+ /* drop the possible '\n' from the end */
+ if (count > 0 && buf[count - 1] == '\n')
+ buf[count - 1] = '\0';
+
+ if (!strcmp(buf, "reset")) {
+ memset(device_stats, 0, sizeof(*device_stats));
+ return count;
+ }
+
+ ath12k_warn(ab, "unsupported command: %s\n", buf);
+
+ return -EINVAL;
+}
+
static const struct file_operations fops_device_dp_stats = {
.read = ath12k_debugfs_dump_device_dp_stats,
+ .write = ath12k_debugfs_write_device_dp_stats,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
@@ -1227,7 +1298,7 @@ void ath12k_debugfs_pdev_create(struct ath12k_base *ab)
debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
&fops_simulate_fw_crash);
- debugfs_create_file("device_dp_stats", 0400, ab->debugfs_soc, ab,
+ debugfs_create_file("device_dp_stats", 0600, ab->debugfs_soc, ab,
&fops_device_dp_stats);
}
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index bef0f2ba0560f..289aede6dabb6 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -7,6 +7,7 @@
#ifndef ATH12K_DP_H
#define ATH12K_DP_H
+#include "dp_stats.h"
#include "hw.h"
#include "dp_htt.h"
#include "dp_cmn.h"
@@ -429,19 +430,27 @@ struct ath12k_dp_arch_ops {
struct ath12k_device_dp_tx_err_stats {
/* TCL Ring Descriptor unavailable */
u32 desc_na[DP_TCL_NUM_RING_MAX];
+ /* TX descriptor pool exhausted (per pool_id / traffic class) */
+ u32 txbuf_na[ATH12K_HW_MAX_QUEUES];
/* Other failures during dp_tx due to mem allocation failure
* idr unavailable etc.
*/
atomic_t misc_fail;
};
+struct ath12k_device_dp_rx_wbm_err_stats {
+ u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];
+ u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX];
+ u32 drop[WBM_ERR_DROP_MAX];
+ u32 sw_desc_fallback;
+};
+
struct ath12k_device_dp_stats {
u32 err_ring_pkts;
u32 invalid_rbm;
- u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];
- u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX];
u32 hal_reo_error[DP_REO_DST_RING_MAX];
struct ath12k_device_dp_tx_err_stats tx_err;
+ struct ath12k_device_dp_rx_wbm_err_stats wbm_err;
u32 reo_rx[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES];
u32 rx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX][ATH12K_MAX_DEVICES];
u32 tqm_rel_reason[MAX_TQM_RELEASE_REASON];
@@ -450,6 +459,7 @@ struct ath12k_device_dp_stats {
u32 tx_enqueued[DP_TCL_NUM_RING_MAX];
u32 tx_completed[DP_TCL_NUM_RING_MAX];
u32 reo_excep_msdu_buf_type;
+ u32 sent_to_stack[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES];
};
struct ath12k_dp {
diff --git a/drivers/net/wireless/ath/ath12k/dp_stats.h b/drivers/net/wireless/ath/ath12k/dp_stats.h
new file mode 100644
index 0000000000000..04d3892acff32
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/dp_stats.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef ATH12K_DP_STATS_H
+#define ATH12K_DP_STATS_H
+
+enum ath12k_wbm_err_drop_reason {
+ WBM_ERR_GET_SW_DESC,
+ WBM_ERR_DESC_PARSE,
+ WBM_ERR_DROP_INV_HW_ID,
+ WBM_ERR_DROP_NULL_PRTNR_DP,
+ WBM_ERR_DROP_NULL_PROC_DP,
+ WBM_ERR_DROP_NULL_PDEV,
+ WBM_ERR_DROP_NULL_AR,
+ WBM_ERR_DROP_CAC_RUNNING,
+ WBM_ERR_DROP_SG,
+ WBM_ERR_DROP_INV_NWIFI_HDR,
+ WBM_ERR_DROP_REO_GENERIC,
+ WBM_ERR_DROP_RXDMA_GENERIC,
+ WBM_ERR_DROP_MAX,
+};
+
+#endif /* ATH12K_DP_STATS_H */
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index 95d87dd67872f..d96d8301565cb 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -12,6 +12,15 @@
#include "hal_wcn7850.h"
#include "hal_qcc2072.h"
+static void
+ath12k_wifi7_dp_rx_wbm_err_free_skb(struct ath12k_dp *dp,
+ struct sk_buff *msdu,
+ enum ath12k_wbm_err_drop_reason drop_reason)
+{
+ dp->device_stats.wbm_err.drop[drop_reason]++;
+ dev_kfree_skb_any(msdu);
+}
+
static u16 ath12k_wifi7_dp_rx_get_peer_id(struct ath12k_dp *dp,
enum ath12k_peer_metadata_version ver,
__le32 peer_metadata)
@@ -642,7 +651,10 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_dp *dp,
dev_kfree_skb_any(msdu);
continue;
}
-
+ if (likely(ring_id < DP_REO_DST_RING_MAX))
+ dp->device_stats.sent_to_stack[ring_id][partner_dp->device_id]++;
+ else
+ WARN_ON_ONCE(1);
ath12k_dp_rx_deliver_msdu(dp_pdev, napi, msdu, &rx_info);
}
@@ -1614,6 +1626,7 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k_pdev_dp *dp_pdev,
/* First buffer will be freed by the caller, so deduct it's length */
msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz);
ath12k_wifi7_dp_rx_null_q_desc_sg_drop(dp, msdu_len, msdu_list);
+ dp->device_stats.wbm_err.drop[WBM_ERR_DROP_SG]++;
return -EINVAL;
}
@@ -1649,8 +1662,10 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k_pdev_dp *dp_pdev,
skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
}
- if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, msdu, rx_info)))
+ if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, msdu, rx_info))) {
+ dp->device_stats.wbm_err.drop[WBM_ERR_DROP_INV_NWIFI_HDR]++;
return -EINVAL;
+ }
ath12k_dp_rx_h_ppdu(dp_pdev, rx_info);
ret = ath12k_wifi7_dp_rx_h_mpdu(dp_pdev, msdu, rx_info);
@@ -1763,7 +1778,10 @@ static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev,
struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
bool drop = false;
- dp->device_stats.rxdma_error[rxcb->err_code]++;
+ if (likely(rxcb->err_code < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX))
+ dp->device_stats.wbm_err.rxdma_error[rxcb->err_code]++;
+ else
+ WARN_ON_ONCE(1);
switch (rxcb->err_code) {
case HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR:
@@ -1780,6 +1798,7 @@ static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev,
/* TODO: Review other rxdma error code to check if anything is
* worth reporting to mac80211
*/
+ dp->device_stats.wbm_err.drop[WBM_ERR_DROP_RXDMA_GENERIC]++;
drop = true;
break;
}
@@ -1796,7 +1815,10 @@ static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k_pdev_dp *dp_pdev,
struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
bool drop = false;
- dp->device_stats.reo_error[rxcb->err_code]++;
+ if (likely(rxcb->err_code < HAL_REO_DEST_RING_ERROR_CODE_MAX))
+ dp->device_stats.wbm_err.reo_error[rxcb->err_code]++;
+ else
+ WARN_ON_ONCE(1);
switch (rxcb->err_code) {
case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO:
@@ -1813,6 +1835,7 @@ static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k_pdev_dp *dp_pdev,
/* TODO: Review other errors and process them to mac80211
* as appropriate.
*/
+ dp->device_stats.wbm_err.drop[WBM_ERR_DROP_REO_GENERIC]++;
drop = true;
break;
}
@@ -1935,6 +1958,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
ret = ath12k_wifi7_hal_wbm_desc_parse_err(dp, rx_desc,
&err_info);
if (ret) {
+ dp->device_stats.wbm_err.drop[WBM_ERR_DESC_PARSE]++;
ath12k_warn(ab, "failed to parse rx error in wbm_rel ring desc %d\n",
ret);
continue;
@@ -1944,8 +1968,10 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
/* retry manual desc retrieval if hw cc is not done */
if (!desc_info) {
+ dp->device_stats.wbm_err.sw_desc_fallback++;
desc_info = ath12k_dp_get_rx_desc(dp, err_info.cookie);
if (!desc_info) {
+ dp->device_stats.wbm_err.drop[WBM_ERR_GET_SW_DESC]++;
ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n",
err_info.cookie);
continue;
@@ -1961,7 +1987,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
device_id = desc_info->device_id;
partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id);
if (unlikely(!partner_dp)) {
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_NULL_PRTNR_DP);
/* In any case continuation bit is set
* in the previous record, cleanup scatter_msdu_list
@@ -2007,7 +2034,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_dp->hal,
msdu_data);
if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) {
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_INV_HW_ID);
/* In any case continuation bit is set
* in the previous record, cleanup scatter_msdu_list
@@ -2068,7 +2096,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
ath12k_dbg(ab, ATH12K_DBG_DATA,
"Unable to process WBM error msdu due to invalid hw link id %d device id %d\n",
hw_link_id, device_id);
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_NULL_PROC_DP);
continue;
}
@@ -2077,18 +2106,21 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
dp_pdev = ath12k_dp_to_pdev_dp(partner_dp, pdev_idx);
if (!dp_pdev) {
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_NULL_PDEV);
continue;
}
ar = ath12k_pdev_dp_to_ar(dp_pdev);
if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_idx])) {
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_NULL_AR);
continue;
}
if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) {
- dev_kfree_skb_any(msdu);
+ ath12k_wifi7_dp_rx_wbm_err_free_skb(dp, msdu,
+ WBM_ERR_DROP_CAC_RUNNING);
continue;
}
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
index 587d58eeccfa5..f572aa581d117 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
@@ -167,8 +167,10 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a
tx_ring = &dp->tx_ring[ti.ring_id];
tx_desc = ath12k_dp_tx_assign_buffer(dp, pool_id);
- if (!tx_desc)
+ if (!tx_desc) {
+ dp->device_stats.tx_err.txbuf_na[pool_id]++;
return -ENOMEM;
+ }
dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, arvif->link_id);
@@ -575,18 +577,21 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_dp *dp, void *desc,
{
struct htt_tx_wbm_completion *status_desc;
struct ath12k_dp_htt_wbm_tx_status ts = {};
- enum hal_wbm_htt_tx_comp_status wbm_status;
+ enum hal_wbm_htt_tx_comp_status htt_status;
u16 peer_id;
status_desc = desc;
- wbm_status = le32_get_bits(status_desc->info0,
+ htt_status = le32_get_bits(status_desc->info0,
HTT_TX_WBM_COMP_INFO0_STATUS);
- dp->device_stats.fw_tx_status[wbm_status]++;
+ if (likely(htt_status < MAX_FW_TX_STATUS))
+ dp->device_stats.fw_tx_status[htt_status]++;
+ else
+ WARN_ON_ONCE(1);
- switch (wbm_status) {
+ switch (htt_status) {
case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:
- ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK);
+ ts.acked = true;
ts.ack_rssi = le32_get_bits(status_desc->info2,
HTT_TX_WBM_COMP_INFO2_ACK_RSSI);
@@ -608,7 +613,7 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_dp *dp, void *desc,
*/
break;
default:
- ath12k_warn(dp->ab, "Unknown htt wbm tx status %d\n", wbm_status);
+ ath12k_warn(dp->ab, "Unknown htt tx status %d\n", htt_status);
break;
}
}
@@ -984,11 +989,17 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_dp *dp, int ring_id)
/* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */
buf_rel_source = le32_get_bits(tx_status->info0,
HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE);
- dp->device_stats.tx_wbm_rel_source[buf_rel_source]++;
+ if (likely(buf_rel_source < HAL_WBM_REL_SRC_MODULE_MAX))
+ dp->device_stats.tx_wbm_rel_source[buf_rel_source]++;
+ else
+ WARN_ON_ONCE(1);
rel_status = le32_get_bits(tx_status->info0,
HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON);
- dp->device_stats.tqm_rel_reason[rel_status]++;
+ if (likely(rel_status < MAX_TQM_RELEASE_REASON))
+ dp->device_stats.tqm_rel_reason[rel_status]++;
+ else
+ WARN_ON_ONCE(1);
/* Release descriptor as soon as extracting necessary info
* to reduce contention
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
index 49c6932897094..60e7a36097f12 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
@@ -329,7 +329,10 @@ int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_dp *dp,
HAL_REO_DEST_RING_INFO0_PUSH_REASON);
err_code = le32_get_bits(desc->info0,
HAL_REO_DEST_RING_INFO0_ERROR_CODE);
- dp->device_stats.reo_error[err_code]++;
+ if (likely(err_code < HAL_REO_DEST_RING_ERROR_CODE_MAX))
+ dp->device_stats.wbm_err.reo_error[err_code]++;
+ else
+ WARN_ON_ONCE(1);
if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED &&
push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
|
| 3/2 | 2026/08/06 15:57 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 10151 output: 25 thoughts: 676 Thoughts: **Fuzzing Feasibility Assessment: ath12k Driver Patch** Okay, so I've got this patch affecting a handful of `ath12k` files: `debugfs.c`, `dp.h`, `dp_stats.h`, and some `wifi7` files. Looks like it's adding new stats to `ath12k_device_dp_stats` and updating the debugfs interface to handle dumping and resetting these stats. Crucially, I see that they've added bounds checking before incrementing the stats arrays, which is great. Things like `if (likely(rxcb->err_code < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX))` before incrementing an array entry. They're also throwing in a `WARN_ON_ONCE(1)` if those bounds are violated, which is solid defensive programming. There are also some new drop reasons tracked. Now, the important question: is this fuzzable? The changes are basically: debugfs read/write functions for `device_dp_stats`, the bounds checks I mentioned, and stats counter increments. The bounds checking is the key part for fuzzing potential, but it *prevents* out-of-bounds writes. Specifically, they've added checks like this to prevent buffer overflows during stats incrementing. The example code snippet is very clear – they're making sure `rxcb->err_code` is within the array bounds before accessing `dp->device_stats.wbm_err.rxdma_error[rxcb->err_code]`. That fixes a potential vulnerability. But here's the kicker: this is an `ath12k` driver. It's for Qualcomm Wi-Fi 7 devices, meaning PCI or AHB hardware. Wi-Fi drivers often require physical hardware, or at least they aren't directly emulated in standard QEMU. I'm racking my brain, does QEMU even *emulate* `ath12k`? Nope. Not that I'm aware of. `mac80211_hwsim` *emulates* Wi-Fi in a general way, but `ath12k` is a specific hardware driver. Can `ath12k` be probed without that hardware? Let me check… nope, it's a PCI/AHB driver. And no, I'm not finding any software emulation layer specifically for `ath12k`. Okay, the prompt is very clear: "Return WorthFuzzing=false if the patch only contains code in vendor-specific PCIe switch, SmartNIC, or GPU drivers... that require physical PCIe hardware cards not emulated in standard QEMU." `ath12k` is *exactly* that – vendor-specific, PCIe/AHB (so that means PCIe-like), Wi-Fi driver. It needs actual hardware. So, given the constraints and the hardware requirement, I must conclude that this specific patch is *not* worth fuzzing within the given parameters. The very nature of the driver's target hardware makes it unreachable in standard QEMU environments. |
| 4/2 | 2026/08/06 15:57 | tool | grepper |
0mArgs:{
"Expression": "pci_register_driver.*ath12k"
}Results: {
"Output": "drivers/net/wireless/ath/ath12k/pci.c=1812=static const struct dev_pm_ops __maybe_unused ath12k_pci_pm_ops = {\n--\ndrivers/net/wireless/ath/ath12k/pci.c-1818-\ndrivers/net/wireless/ath/ath12k/pci.c:1819:int ath12k_pci_register_driver(const enum ath12k_device_family device_id,\ndrivers/net/wireless/ath/ath12k/pci.c-1820-\t\t\t struct ath12k_pci_driver *driver)\n--\ndrivers/net/wireless/ath/ath12k/pci.h=176=void ath12k_pci_power_down(struct ath12k_base *ab, bool is_suspend);\ndrivers/net/wireless/ath/ath12k/pci.h:177:int ath12k_pci_register_driver(const enum ath12k_device_family device_id,\ndrivers/net/wireless/ath/ath12k/pci.h-178-\t\t\t struct ath12k_pci_driver *driver);\n"
} |
| 5/2 | 2026/08/06 15:57 | llm | patch-evaluator |
3mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11847 output: 22 thoughts: 15 Thoughts: Okay, here's my attempt at summarizing that thought process, keeping in mind I'm speaking to a fellow expert and using a first-person perspective: **Investigating Potential Atypical Hemolytic Uremic Syndrome (aHUS) or Similar Conditions** Alright, so we're seeing something that has me thinking about AHB. But I can't jump to conclusions just yet. We need to be thorough and rule out other possibilities, or at least consider them. Let's make sure it isn't something else *alongside* or *instead of* AHB. I want to approach this systematically, with a broad differential diagnosis in mind, and not miss a trick. So, my thought is: Let's investigate whether this is strictly AHB, or if there's more to the story. I need to dig deeper and cast a wider net in my thinking. |
| 6/2 | 2026/08/06 16:00 | tool | grepper |
0mArgs:{
"Expression": "module_init.*ath12k"
}Results: {
"Output": "drivers/net/wireless/ath/ath12k/wifi7/core.c=55=static void ath12k_wifi7_exit(void)\n--\ndrivers/net/wireless/ath/ath12k/wifi7/core.c-63-\ndrivers/net/wireless/ath/ath12k/wifi7/core.c:64:module_init(ath12k_wifi7_init);\ndrivers/net/wireless/ath/ath12k/wifi7/core.c-65-module_exit(ath12k_wifi7_exit);\n"
} |
| 7/2 | 2026/08/06 16:00 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 12220 output: 23 thoughts: 18 Thoughts: Okay, let's dive into this `ath12k_wifi7_init` function. I need to understand its role. What's the initialization process for a WiFi 7 device like in this context? I'm familiar with the ath10k and ath11k families; I wonder what architectural differences they've introduced for WiFi 7 and how those are reflected in this initialization routine. Is it hardware-specific, driver-specific, or both? Are there any new registers or data structures being set up here that are unique to the 802.11be standard, or is it building upon existing code? I'll probably be able to glean quite a bit from the variable names and function calls. Let's see if the authors have included any comments. |
| 8/2 | 2026/08/06 16:01 | tool | grepper |
0mArgs:{
"Expression": "ath12k_wifi7_init"
}Results: {
"Output": "drivers/net/wireless/ath/ath12k/wifi7/core.c=33=void ath12k_wifi7_arch_deinit(struct ath12k_base *ab)\n--\ndrivers/net/wireless/ath/ath12k/wifi7/core.c-38-\ndrivers/net/wireless/ath/ath12k/wifi7/core.c:39:static int ath12k_wifi7_init(void)\ndrivers/net/wireless/ath/ath12k/wifi7/core.c-40-{\n--\ndrivers/net/wireless/ath/ath12k/wifi7/core.c=55=static void ath12k_wifi7_exit(void)\n--\ndrivers/net/wireless/ath/ath12k/wifi7/core.c-63-\ndrivers/net/wireless/ath/ath12k/wifi7/core.c:64:module_init(ath12k_wifi7_init);\ndrivers/net/wireless/ath/ath12k/wifi7/core.c-65-module_exit(ath12k_wifi7_exit);\n"
} |
| 9/2 | 2026/08/06 16:01 | llm | patch-evaluator |
8mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 12717 output: 46 thoughts: 15 Thoughts: Okay, here's my interpretation of what's going through my mind as I approach this `ath12k_wifi7_init` code, formatted as requested: **Diving into the Ath12k WiFi 7 Initialization** Alright, let's get into this. `ath12k_wifi7_init`. Immediately, the "init" part signals that this is the primary setup function for the WiFi 7 functionality within the ath12k driver. I'm expecting this to be the core entry point, the one that orchestrates the initial device configuration. I need to understand how the driver integrates with the hardware, configures the radio, and sets up the foundational data structures for WiFi 7 operations. I bet this is where the power-up sequence, PHY initialization, and possibly firmware loading are handled. I'll be looking for things like register settings, clock configurations, memory allocation for driver structures, and error handling. I'll need to pay close attention to the data structures involved, the sequence of calls, and any hardware-specific dependencies. I'm especially keen to see how the new features of WiFi 7, like the 320 MHz channels, multi-link operation, and improved modulation schemes, are integrated at the very start. I'll be trying to grasp the architectural decisions made here to enable this new standard. It's likely going to be a complex dance between hardware initialization and driver setup, I need to see how they come together. Let's dig in and see. |
| 10/2 | 2026/08/06 16:09 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/ath/ath12k/wifi7/core.c",
"FirstLine": 39,
"LineCount": 20
}Results: {
"Contents": " 39:\tstatic int ath12k_wifi7_init(void)\n 40:\t{\n 41:\t\tahb_err = ath12k_wifi7_ahb_init();\n 42:\t\tif (ahb_err)\n 43:\t\t\tpr_warn(\"Failed to initialize ath12k Wi-Fi 7 AHB device: %d\\n\",\n 44:\t\t\t\tahb_err);\n 45:\t\n 46:\t\tpci_err = ath12k_wifi7_pci_init();\n 47:\t\tif (pci_err)\n 48:\t\t\tpr_warn(\"Failed to initialize ath12k Wi-Fi 7 PCI device: %d\\n\",\n 49:\t\t\t\tpci_err);\n 50:\t\n 51:\t\t/* If both failed, return one of the failures (arbitrary) */\n 52:\t\treturn ahb_err \u0026\u0026 pci_err ? ahb_err : 0;\n 53:\t}\n 54:\t\n 55:\tstatic void ath12k_wifi7_exit(void)\n 56:\t{\n 57:\t\tif (!pci_err)\n 58:\t\t\tath12k_wifi7_pci_exit();\n"
} |
| 11/2 | 2026/08/06 16:09 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 13424 output: 103 thoughts: 135 Thoughts: **Assessment of Fuzzing Viability** Okay, let's break this down. My initial impression is that this particular patch isn't a good candidate for fuzzing, and here's why. The core of this patch seems to be focused on initialization and management of hardware-specific resources. Specifically, it mentions both AHB and PCI devices. Now, I know from experience that both of these interfaces are tied to actual, physical hardware. While AHB *could* theoretically be represented through device tree nodes, standard QEMU doesn't offer these generic AHB device tree nodes. It is highly unlikely to be possible to emulate. Moreover, the patch itself appears to be adding statistics collection and some bounds checking around those statistics. That sounds innocuous on its own, but context is everything. Because it's a vendor-specific driver—in this case, for Qualcomm's Wi-Fi 7 hardware (ath12k)—it's reasonable to assume a degree of hardware dependency. We know it requires real PCIe and/or AHB hardware, and standard QEMU doesn't have good emulation of this. Therefore, given the hardware dependencies and the type of changes, it's not practical to proceed with fuzzing this. Returning WorthFuzzing=false seems like the correct choice with the justification being that this is a vendor-specific Wi-Fi hardware driver that relies on physical PCIe/AHB hardware not realistically emulated within a standard QEMU environment. |
| 12/2 | 2026/08/06 16:09 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch modifies the ath12k driver, which is a vendor-specific driver for Qualcomm Wi-Fi 7 devices. This driver requires physical PCIe or AHB hardware that is not emulated in standard QEMU environments, making the code unreachable during generic fuzzing. Furthermore, the changes primarily involve debugfs statistics and bounds checking for those statistics.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the ath12k driver, which is a vendor-specific driver for Qualcomm Wi-Fi 7 devices. This driver requires physical PCIe or AHB hardware that is not emulated in standard QEMU environments, making the code unreachable during generic fuzzing. Furthermore, the changes primarily involve debugfs statistics and bounds checking for those statistics.",
"WorthFuzzing": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|