[PATCH ath-next v3 03/13] wifi: ath12k: ng: allocate REO command context before submission

From: Pradeep Kumar Chitrapu

Date: Tue Nov 03 2026 - 20:12:30 EST


The Wi-Fi 7 REO send path submits a hardware command before allocating
the software entry used to match its completion. If the atomic
allocation then fails, the function returns -ENOMEM even though the
command is already in flight. The completion cannot be matched to a
callback, and callers may retry an operation whose first command was
accepted by hardware. This can skip RX TID cleanup or issue duplicate
queue operations under memory pressure.

Allocate and initialize the pending-command context before writing the
REO ring. Free it when hardware submission fails or returns an invalid
command number. Commands without callbacks continue to avoid the
allocation.

This changes only the Wi-Fi 7 command sender; the Wi-Fi 8 ring path
already allocates callback state before submission. Found during code
review.

Fixes: 52c555680bae ("wifi: ath12k: Move arch specific rx tid and related functions to wifi7 directory")
Tested-on: Compilation only, M=drivers/net/wireless/ath/ath12k
Signed-off-by: Pradeep Kumar Chitrapu <pradeep.chitrapu@xxxxxxxxxxxxxxxx>
---
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 35 +++++++++++++++++----------
1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index a41049e7b425..d3ed2134818a 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -148,30 +148,39 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab,
struct hal_srng *cmd_ring;
int cmd_num;

+ if (!cb) {
+ dp_cmd = NULL;
+ } else {
+ /* Can this be optimized so that we keep the pending command list only
+ * for tid delete command to free up the resource on the command status
+ * indication?
+ */
+ dp_cmd = kzalloc_obj(*dp_cmd, GFP_ATOMIC);
+ if (!dp_cmd)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&dp_cmd->list);
+ memcpy(&dp_cmd->data, rx_tid, sizeof(*rx_tid));
+ }
+
cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id];
cmd_num = ath12k_wifi7_hal_reo_cmd_send(ab, cmd_ring, type, cmd);

/* cmd_num should start from 1, during failure return the error code */
- if (cmd_num < 0)
+ if (cmd_num < 0) {
+ kfree(dp_cmd);
return cmd_num;
+ }

/* reo cmd ring descriptors has cmd_num starting from 1 */
- if (cmd_num == 0)
+ if (cmd_num == 0) {
+ kfree(dp_cmd);
return -EINVAL;
-
- if (!cb)
- return 0;
-
- /* Can this be optimized so that we keep the pending command list only
- * for tid delete command to free up the resource on the command status
- * indication?
- */
- dp_cmd = kzalloc_obj(*dp_cmd, GFP_ATOMIC);
+ }

if (!dp_cmd)
- return -ENOMEM;
+ return 0;

- memcpy(&dp_cmd->data, rx_tid, sizeof(*rx_tid));
dp_cmd->cmd_num = cmd_num;
dp_cmd->handler = cb;


--
2.43.0