[PATCH ath-next v3 07/13] wifi: ath12k: ng: process REO status ring
Pradeep Kumar Chitrapu
pradeep.chitrapu at oss.qualcomm.com
Tue Nov 3 17:10:50 PST 2026
Wi-Fi 8 can submit REO commands with completion callbacks, but its NAPI
service path does not drain the REO status ring. Commands that request a
status therefore cannot deliver their decoded response to the pending
command context.
Service the REO status ring from the Wi-Fi 8 datapath, decode each
supported status TLV, match it to the pending command number, and pass the
complete status payload to the registered callback. Keep a queue-stats
command pending when a 1K bitmap page follows, then release its context
after processing the second page.
This commit only connects the generic command and status framework. It
does not add a command client or change Wi-Fi 7 status processing.
Tested-on: Compilation only, M=drivers/net/wireless/ath/ath12k
Signed-off-by: Pradeep Kumar Chitrapu <pradeep.chitrapu at oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/wifi8/dp.c | 8 +++
drivers/net/wireless/ath/ath12k/wifi8/dp_rx.c | 93 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/wifi8/dp_rx.h | 1 +
3 files changed, 102 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/wifi8/dp.c b/drivers/net/wireless/ath/ath12k/wifi8/dp.c
index dee73473cea9..e89826f33206 100644
--- a/drivers/net/wireless/ath/ath12k/wifi8/dp.c
+++ b/drivers/net/wireless/ath/ath12k/wifi8/dp.c
@@ -498,6 +498,14 @@ static int ath12k_wifi8_dp_service_srng(struct ath12k_dp *dp,
goto done;
}
+ if (dp->hw_params->ring_mask->reo_status[grp_id]) {
+ work_done = ath12k_wifi8_dp_rx_process_reo_status(dp, budget);
+ budget -= work_done;
+ tot_work_done += work_done;
+ if (budget <= 0)
+ goto done;
+ }
+
done:
return tot_work_done;
}
diff --git a/drivers/net/wireless/ath/ath12k/wifi8/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi8/dp_rx.c
index b75e65091995..632ce30fe459 100644
--- a/drivers/net/wireless/ath/ath12k/wifi8/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi8/dp_rx.c
@@ -2210,3 +2210,96 @@ int ath12k_wifi8_dp_rx_process_err(struct ath12k_dp *dp,
return total_msdu_reaped;
}
+
+int ath12k_wifi8_dp_rx_process_reo_status(struct ath12k_dp *dp, int budget)
+{
+ struct ath12k_base *ab = dp->ab;
+ struct hal_tlv_64_hdr *hdr;
+ struct hal_srng *srng;
+ struct ath12k_dp_rx_reo_cmd *cmd, *tmp;
+ struct hal_reo_status reo_status;
+ int work_done = 0;
+ u16 tag;
+ bool found;
+ bool done;
+
+ srng = &ab->hal.srng_list[dp->reo_status_ring.ring_id];
+
+ spin_lock_bh(&srng->lock);
+ ath12k_hal_srng_access_begin(ab, srng);
+
+ while (work_done < budget &&
+ (hdr = ath12k_hal_srng_dst_get_next_entry(ab, srng))) {
+ work_done++;
+ tag = le64_get_bits(hdr->tl, HAL_SRNG_TLV_HDR_TAG);
+ memset(&reo_status, 0, sizeof(reo_status));
+
+ reo_status.tag = tag;
+ switch (tag) {
+ case HAL_REO_GET_QUEUE_STATS_STATUS:
+ ath12k_wifi8_hal_reo_status_queue_stats(ab, hdr, &reo_status);
+ break;
+ case HAL_REO_GET_QUEUE_1K_STATS_STATUS:
+ ath12k_wifi8_hal_reo_status_queue_1k_stats(ab, hdr,
+ &reo_status);
+ break;
+ case HAL_REO_FLUSH_QUEUE_STATUS:
+ ath12k_wifi8_hal_reo_flush_queue_status(ab, hdr, &reo_status);
+ break;
+ case HAL_REO_FLUSH_CACHE_STATUS:
+ ath12k_wifi8_hal_reo_flush_cache_status(ab, hdr, &reo_status);
+ break;
+ case HAL_REO_UNBLOCK_CACHE_STATUS:
+ ath12k_wifi8_hal_reo_unblk_cache_status(ab, hdr, &reo_status);
+ break;
+ case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS:
+ ath12k_wifi8_hal_reo_flush_timeout_list_status(ab, hdr,
+ &reo_status);
+ break;
+ case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS:
+ ath12k_wifi8_hal_reo_desc_thresh_reached_status(ab, hdr,
+ &reo_status);
+ break;
+ case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS:
+ ath12k_wifi8_hal_reo_update_rx_reo_queue_status(ab, hdr,
+ &reo_status);
+ break;
+ default:
+ ath12k_warn(ab, "Unknown reo status type %d\n", tag);
+ continue;
+ }
+
+ found = false;
+ done = true;
+
+ spin_lock_bh(&dp->reo_cmd_lock);
+ list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) {
+ if (reo_status.uniform_hdr.cmd_num != cmd->cmd_num)
+ continue;
+
+ found = true;
+ if (tag == HAL_REO_GET_QUEUE_STATS_STATUS &&
+ reo_status.u.queue_stats.to_follow_1k)
+ done = false;
+
+ if (done)
+ list_del(&cmd->list);
+
+ break;
+ }
+ spin_unlock_bh(&dp->reo_cmd_lock);
+
+ if (found) {
+ if (cmd->handler)
+ cmd->handler(dp, &cmd->u, &reo_status);
+
+ if (done)
+ kfree(cmd);
+ }
+ }
+
+ ath12k_hal_srng_access_end(ab, srng);
+ spin_unlock_bh(&srng->lock);
+
+ return work_done;
+}
diff --git a/drivers/net/wireless/ath/ath12k/wifi8/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi8/dp_rx.h
index a05ab2f4495c..10940dd92a62 100644
--- a/drivers/net/wireless/ath/ath12k/wifi8/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/wifi8/dp_rx.h
@@ -191,4 +191,5 @@ void ath12k_hal_extract_rx_spd_data_qcn9625(struct hal_rx_spd *rx_info,
struct hal_rx_desc *rx_desc);
int ath12k_wifi8_dp_rx_process_err(struct ath12k_dp *dp,
struct napi_struct *napi, int budget);
+int ath12k_wifi8_dp_rx_process_reo_status(struct ath12k_dp *dp, int budget);
#endif /* ATH12K_DP_RX_WIFI8_H */
--
2.43.0
More information about the ath12k
mailing list