From: Kirill A. Korinsky Subject: Re: The 6th batch of qwz commits To: OpenBSD tech Cc: Stefan Sperling , Mark Kettenis Date: Thu, 01 Oct 2026 14:31:55 +0200 On Thu, 01 Oct 2026 13:47:12 +0200, Mark Kettenis wrote: > > > Date: Thu, 1 Oct 2026 13:43:35 +0200 > > From: Stefan Sperling > > > > (moved to tech@ from ports@) > > > > On Thu, Oct 01, 2026 at 01:29:40PM +0200, Kirill A. Korinsky wrote: > > > Stefan, > > > > > > here the 6th batch of qwz commits. > > > > > > It is quite mechanical with exception of one commit where I fix REO layout > > > to that I had discovered in ath12k, and the next one fixes its lifetime. > > > > > > It was tested on my device and makes it works better, but I may make typos. > > > > > > Ok? > > > > All OK by me, expect the last one of them: > > > > > Subject: [PATCH 7/7] sys/qwz: fix REO queue lifetime > > > > > > Track REO completions before publication and wait for peer unmap, > > > deletion, and cache flushes before reusing queue DMA. Submission errors > > > and timeouts retain ownership; hardware failures block reuse until cold > > > cleanup. HAL error conventions and flush semantics follow ath12k; > > > tracking and the reuse barrier adapt qwz's retained pool. > > > > This diff is too complicated for me to properly review right now. > > Since you have tested it and it seems to be a needed improvement to get > > this driver to work properly, I won't object to it going in without my OK. > > But I cannot fully endorse this diff. > > > > I don't like the conversion of some "return errno" to "return -errno". > > The Linux project uses this negative error code convention, but we do not. > > Yeah, please don't do that (outside of drm). > Sorry, here a correct diff. Diff juggling isn't my best skill and that series is huge, driver is huge and I try to did my best to keep things clean. But, In think, I saw -errno a few tiems in that code outside commented code. Anyway, here the correct diff which I plan to go in in a few hours, after git mirrors synced with alredy commited into cvs commits, and I prepare clean export. commit 222571b1a8c86759327a776273caaa1fe74adea1 Author: Kirill A. Korinsky Date: Mon Sep 28 01:09:56 2026 +0200 sys/qwz: fix REO queue lifetime Track REO completions before publication and wait for peer unmap, deletion, and cache flushes before reusing queue DMA. Submission errors and timeouts retain ownership; hardware failures block reuse until cold cleanup. HAL error conventions and flush semantics follow ath12k; tracking and the reuse barrier adapt qwz's retained pool. diff --git a/sys/dev/ic/qwz.c b/sys/dev/ic/qwz.c index 56da04766dc..59c4021e3e9 100644 --- a/sys/dev/ic/qwz.c +++ b/sys/dev/ic/qwz.c @@ -169,6 +169,7 @@ int qwz_dp_rx_h_null_q_desc(struct qwz_softc *, struct qwz_rx_msdu *, struct qwz_rx_msdu_list *); void qwz_dp_service_mon_ring(void *); void qwz_peer_frags_flush(struct qwz_softc *, struct ath12k_peer *); +int qwz_peer_rx_tid_cleanup(struct qwz_softc *, struct ath12k_peer *); int qwz_wmi_vdev_install_key(struct qwz_softc *, struct wmi_vdev_install_key_arg *, uint8_t); int qwz_dp_peer_rx_pn_replay_config(struct qwz_softc *, struct qwz_vif *, @@ -8235,14 +8236,19 @@ qwz_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv, int qwz_hal_reo_cmd_send(struct qwz_softc *sc, struct hal_srng *srng, - enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd) + enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd, + struct dp_reo_cmd *dp_cmd) { struct hal_tlv_64_hdr *reo_desc; + struct dp_reo_cmd *pending; + uint32_t hp, reap_hp; int ret; #ifdef notyet spin_lock_bh(&srng->lock); #endif qwz_hal_srng_access_begin(sc, srng); + hp = srng->u.src_ring.hp; + reap_hp = srng->u.src_ring.reap_hp; reo_desc = (struct hal_tlv_64_hdr *) qwz_hal_srng_src_get_next_entry(sc, srng); if (!reo_desc) { @@ -8274,6 +8280,26 @@ qwz_hal_reo_cmd_send(struct qwz_softc *sc, struct hal_srng *srng, break; } + if (ret <= 0) { + if (ret == 0) + ret = EINVAL; + goto rollback; + } + TAILQ_FOREACH(pending, &sc->dp.reo_cmd_list, entry) { + if (pending->cmd_num == ret) { + ret = EBUSY; + goto rollback; + } + } + if (dp_cmd != NULL) { + dp_cmd->cmd_num = ret; + TAILQ_INSERT_TAIL(&sc->dp.reo_cmd_list, dp_cmd, entry); + } + goto out; + +rollback: + srng->u.src_ring.hp = hp; + srng->u.src_ring.reap_hp = reap_hp; out: qwz_hal_srng_access_end(sc, srng); #ifdef notyet @@ -8994,13 +9020,11 @@ qwz_dp_alloc(struct qwz_softc *sc) dp->sc = sc; TAILQ_INIT(&dp->reo_cmd_list); - TAILQ_INIT(&dp->reo_cmd_cache_flush_list); #if 0 INIT_LIST_HEAD(&dp->dp_full_mon_mpdu_list); spin_lock_init(&dp->reo_cmd_lock); #endif - dp->reo_cmd_cache_flush_count = 0; dp->idle_link_rbm = qwz_dp_get_idle_link_rbm(sc); ret = qwz_wbm_idle_ring_setup(sc, &n_link_desc); @@ -9108,7 +9132,6 @@ qwz_dp_reo_cmd_list_cleanup(struct qwz_softc *sc) { struct qwz_dp *dp = &sc->dp; struct dp_reo_cmd *cmd, *tmp; - struct dp_reo_cache_flush_elem *cmd_cache, *tmp_cache; struct dp_rx_tid *rx_tid; #ifdef notyet spin_lock_bh(&dp->reo_cmd_lock); @@ -9119,15 +9142,6 @@ qwz_dp_reo_cmd_list_cleanup(struct qwz_softc *sc) qwz_dp_rx_tid_clear(sc, rx_tid); free(cmd, M_DEVBUF, sizeof(*cmd)); } - - TAILQ_FOREACH_SAFE(cmd_cache, &dp->reo_cmd_cache_flush_list, - entry, tmp_cache) { - TAILQ_REMOVE(&dp->reo_cmd_cache_flush_list, cmd_cache, entry); - dp->reo_cmd_cache_flush_count--; - rx_tid = &cmd_cache->data; - qwz_dp_rx_tid_clear(sc, rx_tid); - free(cmd_cache, M_DEVBUF, sizeof(*cmd_cache)); - } #ifdef notyet spin_unlock_bh(&dp->reo_cmd_lock); #endif @@ -9169,6 +9183,8 @@ qwz_dp_free(struct qwz_softc *sc) } } + memset(dp->rx_tid_retire, 0, sizeof(dp->rx_tid_retire)); + /* Deinit any SOC level resource */ } @@ -16573,7 +16589,6 @@ qwz_dp_process_reo_status(struct qwz_softc *sc) struct hal_reo_status reo_status; srng = &sc->hal.srng_list[dp->reo_status_ring.ring_id]; - memset(&reo_status, 0, sizeof(reo_status)); #ifdef notyet spin_lock_bh(&srng->lock); #endif @@ -16581,6 +16596,7 @@ qwz_dp_process_reo_status(struct qwz_softc *sc) while ((reo_desc = qwz_hal_srng_dst_get_next_entry(sc, srng))) { ret = 1; + memset(&reo_status, 0, sizeof(reo_status)); tlv = (struct hal_tlv_64_hdr *)reo_desc; tag = FIELD_GET(HAL_SRNG_TLV_HDR_TAG, le64toh(tlv->tl)); @@ -16596,6 +16612,10 @@ qwz_dp_process_reo_status(struct qwz_softc *sc) case HAL_REO_FLUSH_CACHE_STATUS: qwz_hal_reo_flush_cache_status(sc, reo_desc, &reo_status); + if (reo_status.u.flush_cache.err_detected || + reo_status.u.flush_cache.err_code || + reo_status.u.flush_cache.cache_controller_flush_status_err) + reo_status.uniform_hdr.cmd_status = HAL_REO_CMD_FAILED; break; case HAL_REO_UNBLOCK_CACHE_STATUS: qwz_hal_reo_unblk_cache_status(sc, reo_desc, @@ -16632,8 +16652,9 @@ qwz_dp_process_reo_status(struct qwz_softc *sc) spin_unlock_bh(&dp->reo_cmd_lock); #endif if (found) { - cmd->handler(dp, (void *)&cmd->data, - reo_status.uniform_hdr.cmd_status); + if (cmd->handler != NULL) + cmd->handler(dp, (void *)&cmd->data, + reo_status.uniform_hdr.cmd_status); free(cmd, M_DEVBUF, sizeof(*cmd)); } found = 0; @@ -22609,6 +22630,13 @@ qwz_peer_delete(struct qwz_softc *sc, uint32_t vdev_id, uint8_t pdev_id, } } + ret = qwz_peer_rx_tid_cleanup(sc, peer); + if (ret) { + printf("%s: failed to retire peer RX queues: %d\n", + sc->sc_dev.dv_xname, ret); + return ret; + } + TAILQ_REMOVE(&sc->peers, peer, entry); qwz_node_clear_peer_id(sc, peer); free(peer, M_DEVBUF, sizeof(*peer)); @@ -22673,44 +22701,27 @@ qwz_dp_tx_send_reo_cmd(struct qwz_softc *sc, struct dp_rx_tid *rx_tid, void (*cb)(struct qwz_dp *, void *, enum hal_reo_cmd_status)) { struct qwz_dp *dp = &sc->dp; - struct dp_reo_cmd *dp_cmd; + struct dp_reo_cmd *dp_cmd = NULL; struct hal_srng *cmd_ring; int cmd_num; if (test_bit(ATH12K_FLAG_CRASH_FLUSH, sc->sc_flags)) return ESHUTDOWN; + if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) { + dp_cmd = malloc(sizeof(*dp_cmd), M_DEVBUF, M_ZERO | M_NOWAIT); + if (dp_cmd == NULL) + return ENOMEM; + memcpy(&dp_cmd->data, rx_tid, sizeof(*rx_tid)); + dp_cmd->handler = cb; + } + cmd_ring = &sc->hal.srng_list[dp->reo_cmd_ring.ring_id]; - cmd_num = qwz_hal_reo_cmd_send(sc, cmd_ring, type, cmd); - /* cmd_num should start from 1, during failure return the error code */ - if (cmd_num < 0) + cmd_num = qwz_hal_reo_cmd_send(sc, cmd_ring, type, cmd, dp_cmd); + if (cmd_num < 0) { + free(dp_cmd, M_DEVBUF, sizeof(*dp_cmd)); return cmd_num; - - /* reo cmd ring descriptors has cmd_num starting from 1 */ - if (cmd_num == 0) - 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 = malloc(sizeof(*dp_cmd), M_DEVBUF, M_ZERO | M_NOWAIT); - if (!dp_cmd) - return ENOMEM; - - memcpy(&dp_cmd->data, rx_tid, sizeof(struct dp_rx_tid)); - dp_cmd->cmd_num = cmd_num; - dp_cmd->handler = cb; -#ifdef notyet - spin_lock_bh(&dp->reo_cmd_lock); -#endif - TAILQ_INSERT_TAIL(&dp->reo_cmd_list, dp_cmd, entry); -#ifdef notyet - spin_unlock_bh(&dp->reo_cmd_lock); -#endif + } return 0; } @@ -22825,141 +22836,131 @@ qwz_hal_reo_qdesc_setup(void *vaddr, int tid, uint32_t ba_window_size, } void -qwz_dp_reo_cmd_free(struct qwz_dp *dp, void *ctx, +qwz_dp_rx_tid_retire_done(struct qwz_dp *dp, void *ctx, enum hal_reo_cmd_status status) { - struct qwz_softc *sc = dp->sc; struct dp_rx_tid *rx_tid = ctx; - - if (status != HAL_REO_CMD_SUCCESS) - printf("%s: failed to flush rx tid hw desc, tid %d status %d\n", - sc->sc_dev.dv_xname, rx_tid->tid, status); - - qwz_dp_rx_tid_clear(sc, rx_tid); + struct qwz_rx_tid_retire *retire = &dp->rx_tid_retire[rx_tid->tid]; + + KASSERT(retire->data.mem == rx_tid->mem); + KASSERT(retire->state == QWZ_RX_TID_DELETE_PENDING || + retire->state == QWZ_RX_TID_FLUSH_PENDING); + + if (status != HAL_REO_CMD_SUCCESS) { + retire->state = QWZ_RX_TID_RETIRE_FAILED; + printf("%s: RX queue retirement failed, tid %u status %d\n", + dp->sc->sc_dev.dv_xname, rx_tid->tid, status); + } else if (retire->state == QWZ_RX_TID_DELETE_PENDING) { + retire->flush_offset = retire->data.size; + retire->state = QWZ_RX_TID_FLUSH_READY; + } else if (retire->flush_offset != 0) { + retire->state = QWZ_RX_TID_FLUSH_READY; + } else { + memset(retire, 0, sizeof(*retire)); + } + wakeup(dp->rx_tid_retire); } -void -qwz_dp_reo_cache_flush(struct qwz_softc *sc, struct dp_rx_tid *rx_tid) +int +qwz_dp_rx_tid_retire_submit(struct qwz_softc *sc, + struct qwz_rx_tid_retire *retire) { struct ath12k_hal_reo_cmd cmd = {0}; - unsigned long tot_desc_sz, desc_sz; + enum qwz_rx_tid_retire_state state = retire->state; + enum hal_reo_cmd_type type; + uint32_t offset = retire->flush_offset; + uint64_t paddr = retire->data.paddr; int ret; - tot_desc_sz = rx_tid->size; - desc_sz = qwz_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID); - - while (tot_desc_sz > desc_sz) { - tot_desc_sz -= desc_sz; - cmd.addr_lo = (rx_tid->paddr + tot_desc_sz) & 0xffffffff; - cmd.addr_hi = rx_tid->paddr >> 32; - ret = qwz_dp_tx_send_reo_cmd(sc, rx_tid, - HAL_REO_CMD_FLUSH_CACHE, &cmd, NULL); - if (ret) { - printf("%s: failed to send HAL_REO_CMD_FLUSH_CACHE, " - "tid %d (%d)\n", sc->sc_dev.dv_xname, rx_tid->tid, - ret); - } - } - - memset(&cmd, 0, sizeof(cmd)); - cmd.addr_lo = rx_tid->paddr & 0xffffffff; - cmd.addr_hi = rx_tid->paddr >> 32; - cmd.flag |= HAL_REO_CMD_FLG_NEED_STATUS; - ret = qwz_dp_tx_send_reo_cmd(sc, rx_tid, HAL_REO_CMD_FLUSH_CACHE, - &cmd, qwz_dp_reo_cmd_free); + cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; + if (state == QWZ_RX_TID_DELETE_READY) { + /* WCN7850 requires VLD to remain set until the cache flush. */ + cmd.upd0 = HAL_REO_CMD_UPD0_VLD; + cmd.upd1 = HAL_REO_CMD_UPD1_VLD; + type = HAL_REO_CMD_UPDATE_RX_QUEUE; + retire->state = QWZ_RX_TID_DELETE_PENDING; + } else { + KASSERT(state == QWZ_RX_TID_FLUSH_READY); + KASSERT(offset >= sizeof(struct hal_rx_reo_queue)); + retire->flush_offset -= sizeof(struct hal_rx_reo_queue); + paddr += retire->flush_offset; + if (retire->flush_offset == 0) + cmd.flag |= HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS; + type = HAL_REO_CMD_FLUSH_CACHE; + retire->state = QWZ_RX_TID_FLUSH_PENDING; + } + cmd.addr_lo = paddr & 0xffffffff; + cmd.addr_hi = paddr >> 32; + ret = qwz_dp_tx_send_reo_cmd(sc, &retire->data, type, &cmd, + qwz_dp_rx_tid_retire_done); if (ret) { - printf("%s: failed to send HAL_REO_CMD_FLUSH_CACHE cmd, " - "tid %d (%d)\n", sc->sc_dev.dv_xname, rx_tid->tid, ret); - qwz_dp_rx_tid_clear(sc, rx_tid); + retire->state = state; + retire->flush_offset = offset; } + return ret; } -void -qwz_dp_rx_tid_del_func(struct qwz_dp *dp, void *ctx, - enum hal_reo_cmd_status status) +int +qwz_dp_rx_tid_retire_wait(struct qwz_softc *sc) { - struct qwz_softc *sc = dp->sc; - struct dp_rx_tid *rx_tid = ctx; - struct dp_reo_cache_flush_elem *elem, *tmp; + struct qwz_dp *dp = &sc->dp; + struct qwz_rx_tid_retire *retire; + uint64_t deadline = getnsecuptime() + SEC_TO_NSEC(3); uint64_t now; + int i, pending, error, ret; - if (status == HAL_REO_CMD_DRAIN) { - qwz_dp_rx_tid_clear(sc, rx_tid); - return; - } else if (status != HAL_REO_CMD_SUCCESS) { - /* Shouldn't happen! Cleanup in case of other failure? */ - printf("%s: failed to delete rx tid %d hw descriptor %d\n", - sc->sc_dev.dv_xname, rx_tid->tid, status); - return; - } - - elem = malloc(sizeof(*elem), M_DEVBUF, M_ZERO | M_NOWAIT); - if (!elem) { - qwz_dp_rx_tid_clear(sc, rx_tid); - return; - } - - now = getnsecuptime(); - elem->ts = now; - memcpy(&elem->data, rx_tid, sizeof(*rx_tid)); - - qwz_dp_rx_tid_clear(sc, rx_tid); - -#ifdef notyet - spin_lock_bh(&dp->reo_cmd_lock); -#endif - TAILQ_INSERT_TAIL(&dp->reo_cmd_cache_flush_list, elem, entry); - dp->reo_cmd_cache_flush_count++; - - /* Flush and invalidate aged REO desc from HW cache */ - TAILQ_FOREACH_SAFE(elem, &dp->reo_cmd_cache_flush_list, entry, tmp) { - if (dp->reo_cmd_cache_flush_count > DP_REO_DESC_FREE_THRESHOLD || - now >= elem->ts + MSEC_TO_NSEC(DP_REO_DESC_FREE_TIMEOUT_MS)) { - TAILQ_REMOVE(&dp->reo_cmd_cache_flush_list, elem, entry); - dp->reo_cmd_cache_flush_count--; -#ifdef notyet - spin_unlock_bh(&dp->reo_cmd_lock); -#endif - qwz_dp_reo_cache_flush(sc, &elem->data); - free(elem, M_DEVBUF, sizeof(*elem)); -#ifdef notyet - spin_lock_bh(&dp->reo_cmd_lock); -#endif + for (;;) { + pending = 0; + error = 0; + for (i = 0; i < nitems(dp->rx_tid_retire); i++) { + retire = &dp->rx_tid_retire[i]; + switch (retire->state) { + case QWZ_RX_TID_REUSABLE: + break; + case QWZ_RX_TID_DELETE_READY: + case QWZ_RX_TID_FLUSH_READY: + ret = qwz_dp_rx_tid_retire_submit(sc, retire); + if (ret && !error) + error = ret; + pending = 1; + break; + case QWZ_RX_TID_DELETE_PENDING: + case QWZ_RX_TID_FLUSH_PENDING: + pending = 1; + break; + case QWZ_RX_TID_RETIRE_FAILED: + error = EIO; + break; + } } + if (error) + return error; + if (!pending) + return 0; + now = getnsecuptime(); + if (now >= deadline) + return ETIMEDOUT; + ret = tsleep_nsec(dp->rx_tid_retire, 0, "qwzreo", + deadline - now); + if (ret) + return ret; } -#ifdef notyet - spin_unlock_bh(&dp->reo_cmd_lock); -#endif } void qwz_peer_rx_tid_delete(struct qwz_softc *sc, struct ath12k_peer *peer, uint8_t tid) { - struct ath12k_hal_reo_cmd cmd = {0}; struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; - int ret; + struct qwz_rx_tid_retire *retire = &sc->dp.rx_tid_retire[tid]; if (!rx_tid->active) return; + KASSERT(retire->state == QWZ_RX_TID_REUSABLE); + retire->data = *rx_tid; + retire->state = QWZ_RX_TID_DELETE_READY; rx_tid->active = 0; - - cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; - cmd.addr_lo = rx_tid->paddr & 0xffffffff; - cmd.addr_hi = rx_tid->paddr >> 32; - cmd.upd0 |= HAL_REO_CMD_UPD0_VLD; - ret = qwz_dp_tx_send_reo_cmd(sc, rx_tid, HAL_REO_CMD_UPDATE_RX_QUEUE, - &cmd, qwz_dp_rx_tid_del_func); - if (ret) { - if (ret != ESHUTDOWN) { - printf("%s: failed to send " - "HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", - sc->sc_dev.dv_xname, tid, ret); - } - - qwz_dp_rx_tid_clear(sc, rx_tid); - } } void @@ -23006,11 +23007,11 @@ qwz_peer_frags_flush(struct qwz_softc *sc, struct ath12k_peer *peer) } } -void +int qwz_peer_rx_tid_cleanup(struct qwz_softc *sc, struct ath12k_peer *peer) { struct dp_rx_tid *rx_tid; - int i; + int i, ret; #ifdef notyet lockdep_assert_held(&ar->ab->base_lock); #endif @@ -23025,6 +23026,12 @@ qwz_peer_rx_tid_cleanup(struct qwz_softc *sc, struct ath12k_peer *peer) spin_lock_bh(&ar->ab->base_lock); #endif } + ret = qwz_dp_rx_tid_retire_wait(sc); + if (ret) + return ret; + for (i = 0; i <= HAL_DESC_REO_NON_QOS_TID; i++) + qwz_dp_rx_tid_clear(sc, &peer->rx_tid[i]); + return 0; } int @@ -23105,6 +23112,9 @@ qwz_peer_rx_tid_setup(struct qwz_softc *sc, struct ieee80211_node *ni, peer = qwz_peer_find_by_id(sc, nq->peer_id); if (peer == NULL) return ENOENT; + if (peer->delete_pending || peer->unmapped || + dp->rx_tid_retire[tid].state != QWZ_RX_TID_REUSABLE) + return EBUSY; #ifdef notyet spin_lock_bh(&ab->base_lock); @@ -23712,8 +23722,6 @@ qwz_mac_station_remove(struct qwz_softc *sc, struct qwz_vif *arvif, { int ret; - qwz_peer_rx_tid_cleanup(sc, peer); - ret = qwz_peer_delete(sc, arvif->vdev_id, pdev_id, peer); if (ret) { printf("%s: unable to delete BSS peer: %d\n", diff --git a/sys/dev/ic/qwzvar.h b/sys/dev/ic/qwzvar.h index d20b1a4b4f4..3f9bae208e1 100644 --- a/sys/dev/ic/qwzvar.h +++ b/sys/dev/ic/qwzvar.h @@ -1146,18 +1146,23 @@ struct dp_rx_tid { #endif }; -#define DP_REO_DESC_FREE_THRESHOLD 64 -#define DP_REO_DESC_FREE_TIMEOUT_MS 1000 #define DP_MON_PURGE_TIMEOUT_MS 100 #define DP_MON_SERVICE_BUDGET 128 -struct dp_reo_cache_flush_elem { - TAILQ_ENTRY(dp_reo_cache_flush_elem) entry; - struct dp_rx_tid data; - uint64_t ts; +enum qwz_rx_tid_retire_state { + QWZ_RX_TID_REUSABLE, + QWZ_RX_TID_DELETE_READY, + QWZ_RX_TID_DELETE_PENDING, + QWZ_RX_TID_FLUSH_READY, + QWZ_RX_TID_FLUSH_PENDING, + QWZ_RX_TID_RETIRE_FAILED, }; -TAILQ_HEAD(dp_reo_cmd_cache_flush_head, dp_reo_cache_flush_elem); +struct qwz_rx_tid_retire { + struct dp_rx_tid data; + enum qwz_rx_tid_retire_state state; + uint32_t flush_offset; +}; struct dp_reo_cmd { TAILQ_ENTRY(dp_reo_cmd) entry; @@ -1257,18 +1262,14 @@ struct qwz_dp { struct dp_tx_ring tx_ring[DP_TCL_NUM_RING_MAX]; struct hal_wbm_idle_scatter_list scatter_list[DP_IDLE_SCATTER_BUFS_MAX]; struct dp_reo_cmd_head reo_cmd_list; - struct dp_reo_cmd_cache_flush_head reo_cmd_cache_flush_list; #if 0 struct list_head dp_full_mon_mpdu_list; #endif - uint32_t reo_cmd_cache_flush_count; enum hal_rx_buf_return_buf_manager idle_link_rbm; #if 0 /** * protects access to below fields, * - reo_cmd_list - * - reo_cmd_cache_flush_list - * - reo_cmd_cache_flush_count */ spinlock_t reo_cmd_lock; #endif @@ -1302,6 +1303,7 @@ struct qwz_dp { * support for HostAP mode gets added to the driver. */ struct qwz_dmamem *rx_tid_mem[HAL_DESC_REO_NON_QOS_TID + 1]; + struct qwz_rx_tid_retire rx_tid_retire[HAL_DESC_REO_NON_QOS_TID + 1]; }; #define ATH12K_SHADOW_DP_TIMER_INTERVAL 20 -- wbr, Kirill