* [PATCH ath-next v2 0/8] wifi: ath12k: extend device DP stats for TX and RX observability
@ 2026-08-06 12:09 Pardeep Kaur
2026-08-06 12:09 ` [PATCH ath-next v2 1/8] wifi: ath12k: fix out-of-bounds access on TX stats arrays Pardeep Kaur
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Pardeep Kaur @ 2026-08-06 12:09 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Pardeep Kaur
From: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
Extend ath12k device DP stats for TX and RX path observability.
Patch 1 fixes out-of-bounds array access on TX stats arrays
fw_tx_status[], tx_wbm_rel_source[] and tqm_rel_reason[] by adding
likely()/WARN_ON_ONCE() bounds checks before each increment.
Patch 2 renames the local variable wbm_status to htt_status in
ath12k_dp_tx_process_htt_tx_complete() to accurately reflect the field
origin, and simplifies ts.acked to use true directly.
Patch 3 adds a per-pool TX descriptor allocation failure counter
txbuf_na[] indexed by pool_id to track which traffic class ran out of
TX descriptors, and exposes it in device_dp_stats debugfs.
Patch 4 adds a write handler to device_dp_stats debugfs so that writing
'reset' clears all device DP stats counters without reloading the driver.
Patch 5 introduces a new dp_stats.h header with the
ath12k_wbm_err_drop_reason enum, adds per-drop-reason counters in the
WBM RX error path, and exposes them in device_dp_stats debugfs.
Patch 6 adds a 2D sent_to_stack[ring_id][device_id] counter to track
successful MSDU deliveries to the network stack, attributed to the ring
owner's dp so it is directly comparable with reo_rx[] in the same
debugfs file in MLO configurations.
Patch 7 fixes the REO Rx Received debugfs output to use 0-based ring
indexing and lowercase "ring%d:" consistent with other ring counters.
Patch 8 adds a dedicated sw_desc_fallback counter to track how often the
WBM RX error path falls back to SW descriptor retrieval when HW CC is
not done, distinct from actual packet drops.
v2 changes:
- Fix txbuf_na[] indexing: use pool_id instead of ring_id so the counter
tracks TX descriptor pool exhaustion per traffic class, not per CPU
ring (patch 3).
- Fix sent_to_stack[] to use a 2D array [ring_id][device_id] attributed
to the ring owner's dp, making it directly comparable with reo_rx[] in
the same debugfs file in MLO configurations (patch 6).
- Fix double-counting of WBM_ERR_DROP_RXDMA_GENERIC: move the increment
inside rxdma_err()'s default: branch so it counts only unhandled RXDMA
errors, consistent with WBM_ERR_DROP_REO_GENERIC (patch 5).
- Remove WBM_ERR_INV_PEER_ID, WBM_ERR_DROP_INV_COOKIE and
WBM_ERR_DROP_INV_PUSH_RSN from the drop reason enum; these have no
corresponding increment sites in the datapath (patch 5).
- Remove leading space from "WBM Rx Drop Count" section header (patch 5).
- Add likely()/WARN_ON_ONCE() bounds check on ring_id before indexing
sent_to_stack[] (patch 6).
- Update commit messages for patches 3 and 6 to reflect corrected
semantics.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1
Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com>
---
Aniruddha Mishra (2):
wifi: ath12k: add WBM RX error drop statistics
wifi: ath12k: add WBM SW desc fallback counter
Hariharan Ramanathan (4):
wifi: ath12k: rename wbm_status to htt_status in HTT TX completion
wifi: ath12k: add TCL ring TX buffer allocation failure counter
wifi: ath12k: add device DP stats reset support via debugfs
wifi: ath12k: track per-ring RX sent-to-stack count
Pardeep Kaur (2):
wifi: ath12k: fix out-of-bounds access on TX stats arrays
wifi: ath12k: fix 1-based ring index in REO Rx Received debugfs output
drivers/net/wireless/ath/ath12k/debugfs.c | 79 ++++++++++++++++++-
drivers/net/wireless/ath/ath12k/dp.h | 14 +++-
drivers/net/wireless/ath/ath12k/dp_stats.h | 25 ++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 52 +++++++++---
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 29 ++++---
.../net/wireless/ath/ath12k/wifi7/hal_rx.c | 5 +-
6 files changed, 178 insertions(+), 26 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/dp_stats.h
base-commit: 691e5e43b2aa5da35b044532845a3b230e540894
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH ath-next v2 1/8] wifi: ath12k: fix out-of-bounds access on TX stats arrays 2026-08-06 12:09 [PATCH ath-next v2 0/8] wifi: ath12k: extend device DP stats for TX and RX observability Pardeep Kaur @ 2026-08-06 12:09 ` Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 2/8] wifi: ath12k: rename wbm_status to htt_status in HTT TX completion Pardeep Kaur ` (4 subsequent siblings) 5 siblings, 0 replies; 8+ messages in thread From: Pardeep Kaur @ 2026-08-06 12:09 UTC (permalink / raw) To: ath12k; +Cc: linux-wireless, Pardeep Kaur From: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> The fw_tx_status[], tx_wbm_rel_source[], and tqm_rel_reason[] arrays are indexed directly by values read from hardware without bounds checks. Values at or beyond MAX_FW_TX_STATUS, HAL_WBM_REL_SRC_MODULE_MAX, or MAX_TQM_RELEASE_REASON respectively would write past the end of the arrays causing memory corruption. Add bounds checks using likely() and WARN_ON_ONCE() before incrementing each counter, consistent with the existing pattern used elsewhere in the ath12k codebase. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1 Fixes: c5c62287e690 ("wifi: ath12k: Add device dp stats support") Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> --- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 587d58eeccfa..632230e77802 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -582,7 +582,10 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_dp *dp, void *desc, wbm_status = le32_get_bits(status_desc->info0, HTT_TX_WBM_COMP_INFO0_STATUS); - dp->device_stats.fw_tx_status[wbm_status]++; + if (likely(wbm_status < MAX_FW_TX_STATUS)) + dp->device_stats.fw_tx_status[wbm_status]++; + else + WARN_ON_ONCE(1); switch (wbm_status) { case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK: @@ -984,11 +987,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 base-commit: 691e5e43b2aa -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH ath-next v2 2/8] wifi: ath12k: rename wbm_status to htt_status in HTT TX completion 2026-08-06 12:09 [PATCH ath-next v2 0/8] wifi: ath12k: extend device DP stats for TX and RX observability Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 1/8] wifi: ath12k: fix out-of-bounds access on TX stats arrays Pardeep Kaur @ 2026-08-06 12:09 ` Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 3/8] wifi: ath12k: add TCL ring TX buffer allocation failure counter Pardeep Kaur ` (3 subsequent siblings) 5 siblings, 0 replies; 8+ messages in thread From: Pardeep Kaur @ 2026-08-06 12:09 UTC (permalink / raw) To: ath12k; +Cc: linux-wireless, Hariharan Ramanathan, Pardeep Kaur From: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com> The variable wbm_status in ath12k_dp_tx_process_htt_tx_complete() holds a value from the HTT TX WBM completion status field, not a generic WBM status. Rename it to htt_status to accurately reflect the field origin and improve code clarity. Also fix ts.acked assignment inside the HAL_WBM_REL_HTT_TX_COMP_STATUS_OK case to use true directly since the condition is always true within that case branch. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1 Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com> Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> --- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 632230e77802..d46a3d14f018 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -575,21 +575,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); - if (likely(wbm_status < MAX_FW_TX_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); @@ -611,7 +611,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; } } -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH ath-next v2 3/8] wifi: ath12k: add TCL ring TX buffer allocation failure counter 2026-08-06 12:09 [PATCH ath-next v2 0/8] wifi: ath12k: extend device DP stats for TX and RX observability Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 1/8] wifi: ath12k: fix out-of-bounds access on TX stats arrays Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 2/8] wifi: ath12k: rename wbm_status to htt_status in HTT TX completion Pardeep Kaur @ 2026-08-06 12:09 ` Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 4/8] wifi: ath12k: add device DP stats reset support via debugfs Pardeep Kaur ` (2 subsequent siblings) 5 siblings, 0 replies; 8+ messages in thread From: Pardeep Kaur @ 2026-08-06 12:09 UTC (permalink / raw) To: ath12k; +Cc: linux-wireless, Hariharan Ramanathan, Pardeep Kaur From: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com> When ath12k_dp_tx_assign_buffer() fails, the TX path returns -ENOMEM silently with no visibility into which traffic class is affected. Without a counter, TX descriptor pool exhaustion is invisible during debugging. Add txbuf_na[] indexed by pool_id to ath12k_device_dp_tx_err_stats to track TX descriptor pool allocation failures per traffic class and increment it on assign failure in the TX path. Expose the per-pool counts in debugfs under a new 'TX Descriptor Pool Alloc Failures' section. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1 Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com> Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> --- drivers/net/wireless/ath/ath12k/debugfs.c | 5 +++++ drivers/net/wireless/ath/ath12k/dp.h | 2 ++ drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 4 +++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index d54995b7adb2..ec49692107a8 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -1117,6 +1117,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)); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index bef0f2ba0560..16675210806a 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -429,6 +429,8 @@ 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. */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index d46a3d14f018..f572aa581d11 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); -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH ath-next v2 4/8] wifi: ath12k: add device DP stats reset support via debugfs 2026-08-06 12:09 [PATCH ath-next v2 0/8] wifi: ath12k: extend device DP stats for TX and RX observability Pardeep Kaur ` (2 preceding siblings ...) 2026-08-06 12:09 ` [PATCH ath-next v2 3/8] wifi: ath12k: add TCL ring TX buffer allocation failure counter Pardeep Kaur @ 2026-08-06 12:09 ` Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 5/8] wifi: ath12k: add WBM RX error drop statistics Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 6/8] wifi: ath12k: track per-ring RX sent-to-stack count Pardeep Kaur 5 siblings, 0 replies; 8+ messages in thread From: Pardeep Kaur @ 2026-08-06 12:09 UTC (permalink / raw) To: ath12k; +Cc: linux-wireless, Hariharan Ramanathan, Pardeep Kaur From: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com> There is no way to reset device DP stats counters without reloading the driver, making it difficult to isolate issues to a specific time window during debugging. Add a write handler to the device_dp_stats debugfs file so that writing 'reset' clears all device DP stats counters. Change the file mode from 0400 to 0600 to allow write access. Use strcmp() with newline stripping to match the input, consistent with the existing pattern in debugfs.c. Return -EINVAL on unrecognised input. No lock is taken around the memset since the counters are updated locklessly in the datapath; taking dp_lock would be misleading as it does not protect device_stats updates. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1 Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com> Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> --- drivers/net/wireless/ath/ath12k/debugfs.c | 35 ++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index ec49692107a8..0e446a666f4c 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -1220,8 +1220,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, @@ -1232,7 +1265,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); } -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH ath-next v2 5/8] wifi: ath12k: add WBM RX error drop statistics 2026-08-06 12:09 [PATCH ath-next v2 0/8] wifi: ath12k: extend device DP stats for TX and RX observability Pardeep Kaur ` (3 preceding siblings ...) 2026-08-06 12:09 ` [PATCH ath-next v2 4/8] wifi: ath12k: add device DP stats reset support via debugfs Pardeep Kaur @ 2026-08-06 12:09 ` Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 6/8] wifi: ath12k: track per-ring RX sent-to-stack count Pardeep Kaur 5 siblings, 0 replies; 8+ messages in thread From: Pardeep Kaur @ 2026-08-06 12:09 UTC (permalink / raw) To: ath12k; +Cc: linux-wireless, Aniruddha Mishra, Pardeep Kaur From: Aniruddha Mishra <aniruddha.mishra@oss.qualcomm.com> Without fine-grained drop counters, diagnosing RX failures in the WBM error path requires intrusive debugging. Introduce per-drop-reason counters to track exactly where and why packets are dropped during WBM RX error handling. Introduce a new dp_stats.h header and define ath12k_wbm_err_drop_reason enum there covering all drop points in the WBM RX error path: descriptor parse failures, SW descriptor retrieval errors, null partner DP, invalid HW link ID, null pdev/ar, CAC running, scatter-gather drops, and invalid NWifi header length. The new header is included by dp.h which is already included by all consumers. Add ath12k_device_dp_rx_wbm_err_stats struct grouping rxdma_error[], reo_error[], and the new drop[] counters, replacing the flat arrays previously in ath12k_device_dp_stats. Add bounds checks before indexing rxdma_error[] and reo_error[] with hardware-supplied err_code values to prevent out-of-bounds writes, using the same likely/WARN_ON_ONCE pattern as the TX stats bounds fixes. Add ath12k_wifi7_dp_rx_wbm_err_free_skb() helper to combine drop stat increment and skb free at each drop site, reducing repetition. Define the helper at the top of dp_rx.c before its first use. Increment WBM_ERR_DROP_RXDMA_GENERIC only inside rxdma_err()'s default: branch so it counts only unhandled RXDMA errors, not every RXDMA drop - consistent with how WBM_ERR_DROP_REO_GENERIC is counted. Expose WBM RX drop counts in the device_dp_stats debugfs file under a new 'WBM Rx Drop Count' section. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1 Signed-off-by: Aniruddha Mishra <aniruddha.mishra@oss.qualcomm.com> Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> --- drivers/net/wireless/ath/ath12k/debugfs.c | 23 +++++++++- drivers/net/wireless/ath/ath12k/dp.h | 10 +++- drivers/net/wireless/ath/ath12k/dp_stats.h | 25 ++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 46 +++++++++++++++---- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 5 +- 5 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/dp_stats.h diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index 0e446a666f4c..f9653fb7b038 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,18 @@ 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, "\nHAL REO errors:\n"); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 16675210806a..9b57b2170b60 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" @@ -437,13 +438,18 @@ struct ath12k_device_dp_tx_err_stats { 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]; +}; + 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]; 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 000000000000..04d3892acff3 --- /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 95d87dd67872..b203513d63cc 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) @@ -1614,6 +1623,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 +1659,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 +1775,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 +1795,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 +1812,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 +1832,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 +1955,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; @@ -1946,6 +1967,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp, if (!desc_info) { 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 +1983,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 +2030,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 +2092,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 +2102,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/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 49c693289709..60e7a36097f1 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) { -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH ath-next v2 6/8] wifi: ath12k: track per-ring RX sent-to-stack count 2026-08-06 12:09 [PATCH ath-next v2 0/8] wifi: ath12k: extend device DP stats for TX and RX observability Pardeep Kaur ` (4 preceding siblings ...) 2026-08-06 12:09 ` [PATCH ath-next v2 5/8] wifi: ath12k: add WBM RX error drop statistics Pardeep Kaur @ 2026-08-06 12:09 ` Pardeep Kaur 5 siblings, 0 replies; 8+ messages in thread From: Pardeep Kaur @ 2026-08-06 12:09 UTC (permalink / raw) To: ath12k; +Cc: linux-wireless, Hariharan Ramanathan, Pardeep Kaur From: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com> The device DP stats provide visibility into RX errors and drops but lack a counter for successfully delivered packets. Without this, it is difficult to correlate REO ring activity with actual stack delivery during debugging or performance analysis. Add sent_to_stack[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES] to ath12k_device_dp_stats to track successful deliveries per REO ring per device. The counter is attributed to the ring owner's dp and indexed by partner_dp->device_id, keeping it in the same debugfs file as reo_rx[] for direct comparison in MLO configurations. Increment the counter just before each MSDU is handed off to the stack via ath12k_dp_rx_deliver_msdu(). Add a likely()/WARN_ON_ONCE() bounds check on ring_id before indexing sent_to_stack[], consistent with all other new stat arrays in this series. Expose the per-ring per-device counts in the device_dp_stats debugfs file under a new 'REO sent to stack' section. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1 Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com> Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> --- drivers/net/wireless/ath/ath12k/debugfs.c | 10 ++++++++++ drivers/net/wireless/ath/ath12k/dp.h | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 5 ++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index f9653fb7b038..216a1af22898 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -1122,6 +1122,16 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file, 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, "\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"); for (i = 0; i < DP_REO_DST_RING_MAX; i++) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 9b57b2170b60..5cfe2096c633 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -458,6 +458,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/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index b203513d63cc..60489cfd4e54 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -651,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); } -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH ath-next v2 0/8] wifi: ath12k: extend device DP stats for TX and RX observability @ 2026-08-06 13:24 Pardeep Kaur 2026-08-06 13:24 ` [PATCH ath-next v2 6/8] wifi: ath12k: track per-ring RX sent-to-stack count Pardeep Kaur 0 siblings, 1 reply; 8+ messages in thread From: Pardeep Kaur @ 2026-08-06 13:24 UTC (permalink / raw) To: ath12k; +Cc: linux-wireless, Pardeep Kaur From: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> Extend ath12k device DP stats for TX and RX path observability. Patch 1 fixes out-of-bounds array access on TX stats arrays fw_tx_status[], tx_wbm_rel_source[] and tqm_rel_reason[] by adding likely()/WARN_ON_ONCE() bounds checks before each increment. Patch 2 renames the local variable wbm_status to htt_status in ath12k_dp_tx_process_htt_tx_complete() to accurately reflect the field origin, and simplifies ts.acked to use true directly. Patch 3 adds a per-pool TX descriptor allocation failure counter txbuf_na[] indexed by pool_id to track which traffic class ran out of TX descriptors, and exposes it in device_dp_stats debugfs. Patch 4 adds a write handler to device_dp_stats debugfs so that writing 'reset' clears all device DP stats counters without reloading the driver. Patch 5 introduces a new dp_stats.h header with the ath12k_wbm_err_drop_reason enum, adds per-drop-reason counters in the WBM RX error path, and exposes them in device_dp_stats debugfs. Patch 6 adds a 2D sent_to_stack[ring_id][device_id] counter to track successful MSDU deliveries to the network stack, attributed to the ring owner's dp so it is directly comparable with reo_rx[] in the same debugfs file in MLO configurations. Patch 7 fixes the REO Rx Received debugfs output to use 0-based ring indexing and lowercase "ring%d:" consistent with other ring counters. Patch 8 adds a dedicated sw_desc_fallback counter to track how often the WBM RX error path falls back to SW descriptor retrieval when HW CC is not done, distinct from actual packet drops. v2 changes: - Fix txbuf_na[] indexing: use pool_id instead of ring_id so the counter tracks TX descriptor pool exhaustion per traffic class, not per CPU ring (patch 3). - Fix sent_to_stack[] to use a 2D array [ring_id][device_id] attributed to the ring owner's dp, making it directly comparable with reo_rx[] in the same debugfs file in MLO configurations (patch 6). - Fix double-counting of WBM_ERR_DROP_RXDMA_GENERIC: move the increment inside rxdma_err()'s default: branch so it counts only unhandled RXDMA errors, consistent with WBM_ERR_DROP_REO_GENERIC (patch 5). - Remove WBM_ERR_INV_PEER_ID, WBM_ERR_DROP_INV_COOKIE and WBM_ERR_DROP_INV_PUSH_RSN from the drop reason enum; these have no corresponding increment sites in the datapath (patch 5). - Remove leading space from "WBM Rx Drop Count" section header (patch 5). - Add likely()/WARN_ON_ONCE() bounds check on ring_id before indexing sent_to_stack[] (patch 6). - Update commit messages for patches 3 and 6 to reflect corrected semantics. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1 Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> --- Aniruddha Mishra (2): wifi: ath12k: add WBM RX error drop statistics wifi: ath12k: add WBM SW desc fallback counter Hariharan Ramanathan (4): wifi: ath12k: rename wbm_status to htt_status in HTT TX completion wifi: ath12k: add TCL ring TX buffer allocation failure counter wifi: ath12k: add device DP stats reset support via debugfs wifi: ath12k: track per-ring RX sent-to-stack count Pardeep Kaur (2): wifi: ath12k: fix out-of-bounds access on TX stats arrays wifi: ath12k: fix 1-based ring index in REO Rx Received debugfs output drivers/net/wireless/ath/ath12k/debugfs.c | 79 ++++++++++++++++++- drivers/net/wireless/ath/ath12k/dp.h | 14 +++- drivers/net/wireless/ath/ath12k/dp_stats.h | 25 ++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 52 +++++++++--- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 29 ++++--- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 5 +- 6 files changed, 178 insertions(+), 26 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/dp_stats.h base-commit: 691e5e43b2aa5da35b044532845a3b230e540894 -- 2.34.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH ath-next v2 6/8] wifi: ath12k: track per-ring RX sent-to-stack count 2026-08-06 13:24 [PATCH ath-next v2 0/8] wifi: ath12k: extend device DP stats for TX and RX observability Pardeep Kaur @ 2026-08-06 13:24 ` Pardeep Kaur 0 siblings, 0 replies; 8+ messages in thread From: Pardeep Kaur @ 2026-08-06 13:24 UTC (permalink / raw) To: ath12k; +Cc: linux-wireless, Hariharan Ramanathan, Pardeep Kaur From: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com> The device DP stats provide visibility into RX errors and drops but lack a counter for successfully delivered packets. Without this, it is difficult to correlate REO ring activity with actual stack delivery during debugging or performance analysis. Add sent_to_stack[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES] to ath12k_device_dp_stats to track successful deliveries per REO ring per device. The counter is attributed to the ring owner's dp and indexed by partner_dp->device_id, keeping it in the same debugfs file as reo_rx[] for direct comparison in MLO configurations. Increment the counter just before each MSDU is handed off to the stack via ath12k_dp_rx_deliver_msdu(). Add a likely()/WARN_ON_ONCE() bounds check on ring_id before indexing sent_to_stack[], consistent with all other new stat arrays in this series. Expose the per-ring per-device counts in the device_dp_stats debugfs file under a new 'REO sent to stack' section. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6.r1-00402-QCAHKSWPL_SILICONZ-1 Signed-off-by: Hariharan Ramanathan <hariharan.ramanathan@oss.qualcomm.com> Co-developed-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> Signed-off-by: Pardeep Kaur <pardeep.kaur@oss.qualcomm.com> --- drivers/net/wireless/ath/ath12k/debugfs.c | 10 ++++++++++ drivers/net/wireless/ath/ath12k/dp.h | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 5 ++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index f9653fb7b038..216a1af22898 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -1122,6 +1122,16 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file, 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, "\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"); for (i = 0; i < DP_REO_DST_RING_MAX; i++) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 9b57b2170b60..5cfe2096c633 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -458,6 +458,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/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index b203513d63cc..60489cfd4e54 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -651,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); } -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-08-06 13:25 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-06 12:09 [PATCH ath-next v2 0/8] wifi: ath12k: extend device DP stats for TX and RX observability Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 1/8] wifi: ath12k: fix out-of-bounds access on TX stats arrays Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 2/8] wifi: ath12k: rename wbm_status to htt_status in HTT TX completion Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 3/8] wifi: ath12k: add TCL ring TX buffer allocation failure counter Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 4/8] wifi: ath12k: add device DP stats reset support via debugfs Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 5/8] wifi: ath12k: add WBM RX error drop statistics Pardeep Kaur 2026-08-06 12:09 ` [PATCH ath-next v2 6/8] wifi: ath12k: track per-ring RX sent-to-stack count Pardeep Kaur -- strict thread matches above, loose matches on Subject: below -- 2026-08-06 13:24 [PATCH ath-next v2 0/8] wifi: ath12k: extend device DP stats for TX and RX observability Pardeep Kaur 2026-08-06 13:24 ` [PATCH ath-next v2 6/8] wifi: ath12k: track per-ring RX sent-to-stack count Pardeep Kaur
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox