From 3acc5c6d5e770b220bea7a9033b35732bfb6fbc3 Mon Sep 17 00:00:00 2001 From: stsp Date: Fri, 9 Feb 2024 14:07:27 +0000 Subject: [PATCH] implement qwx_dp_process_reo_status() --- sys/dev/ic/qwx.c | 295 +++++++++++++++++++++++++++++++++++++++++++- sys/dev/ic/qwxvar.h | 96 +++++++++++++- 2 files changed, 388 insertions(+), 3 deletions(-) diff --git a/sys/dev/ic/qwx.c b/sys/dev/ic/qwx.c index a8249b47048..8e9bcf1553b 100644 --- a/sys/dev/ic/qwx.c +++ b/sys/dev/ic/qwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: qwx.c,v 1.33 2024/02/09 14:05:48 stsp Exp $ */ +/* $OpenBSD: qwx.c,v 1.34 2024/02/09 14:07:27 stsp Exp $ */ /* * Copyright 2023 Stefan Sperling @@ -16209,10 +16209,301 @@ qwx_dp_process_rxdma_err(struct qwx_softc *sc) return 0; } +void +qwx_hal_reo_status_queue_stats(struct qwx_softc *sc, uint32_t *reo_desc, + struct hal_reo_status *status) +{ + struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; + struct hal_reo_get_queue_stats_status *desc = + (struct hal_reo_get_queue_stats_status *)tlv->value; + + status->uniform_hdr.cmd_num = + FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, desc->hdr.info0); + status->uniform_hdr.cmd_status = + FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, desc->hdr.info0); +#if 0 + ath11k_dbg(ab, ATH11K_DBG_HAL, "Queue stats status:\n"); + ath11k_dbg(ab, ATH11K_DBG_HAL, "header: cmd_num %d status %d\n", + status->uniform_hdr.cmd_num, + status->uniform_hdr.cmd_status); + ath11k_dbg(ab, ATH11K_DBG_HAL, "ssn %ld cur_idx %ld\n", + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_SSN, + desc->info0), + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_CUR_IDX, + desc->info0)); + ath11k_dbg(ab, ATH11K_DBG_HAL, "pn = [%08x, %08x, %08x, %08x]\n", + desc->pn[0], desc->pn[1], desc->pn[2], desc->pn[3]); + ath11k_dbg(ab, ATH11K_DBG_HAL, + "last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n", + desc->last_rx_enqueue_timestamp, + desc->last_rx_dequeue_timestamp); + ath11k_dbg(ab, ATH11K_DBG_HAL, + "rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n", + desc->rx_bitmap[0], desc->rx_bitmap[1], desc->rx_bitmap[2], + desc->rx_bitmap[3], desc->rx_bitmap[4], desc->rx_bitmap[5], + desc->rx_bitmap[6], desc->rx_bitmap[7]); + ath11k_dbg(ab, ATH11K_DBG_HAL, "count: cur_mpdu %ld cur_msdu %ld\n", + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MPDU_COUNT, + desc->info1), + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MSDU_COUNT, + desc->info1)); + ath11k_dbg(ab, ATH11K_DBG_HAL, "fwd_timeout %ld fwd_bar %ld dup_count %ld\n", + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_TIMEOUT_COUNT, + desc->info2), + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_FDTB_COUNT, + desc->info2), + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_DUPLICATE_COUNT, + desc->info2)); + ath11k_dbg(ab, ATH11K_DBG_HAL, "frames_in_order %ld bar_rcvd %ld\n", + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_FIO_COUNT, + desc->info3), + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_BAR_RCVD_CNT, + desc->info3)); + ath11k_dbg(ab, ATH11K_DBG_HAL, "num_mpdus %d num_msdus %d total_bytes %d\n", + desc->num_mpdu_frames, desc->num_msdu_frames, + desc->total_bytes); + ath11k_dbg(ab, ATH11K_DBG_HAL, "late_rcvd %ld win_jump_2k %ld hole_cnt %ld\n", + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_LATE_RX_MPDU, + desc->info4), + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_WINDOW_JMP2K, + desc->info4), + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_HOLE_COUNT, + desc->info4)); + ath11k_dbg(ab, ATH11K_DBG_HAL, "looping count %ld\n", + FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO5_LOOPING_CNT, + desc->info5)); +#endif +} + +void +qwx_hal_reo_flush_queue_status(struct qwx_softc *sc, uint32_t *reo_desc, + struct hal_reo_status *status) +{ + struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; + struct hal_reo_flush_queue_status *desc = + (struct hal_reo_flush_queue_status *)tlv->value; + + status->uniform_hdr.cmd_num = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, desc->hdr.info0); + status->uniform_hdr.cmd_status = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, desc->hdr.info0); + status->u.flush_queue.err_detected = FIELD_GET( + HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED, desc->info0); +} + +void +qwx_hal_reo_flush_cache_status(struct qwx_softc *sc, uint32_t *reo_desc, + struct hal_reo_status *status) +{ + struct ath11k_hal *hal = &sc->hal; + struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; + struct hal_reo_flush_cache_status *desc = + (struct hal_reo_flush_cache_status *)tlv->value; + + status->uniform_hdr.cmd_num = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, desc->hdr.info0); + status->uniform_hdr.cmd_status = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, desc->hdr.info0); + + status->u.flush_cache.err_detected = FIELD_GET( + HAL_REO_FLUSH_CACHE_STATUS_INFO0_IS_ERR, desc->info0); + status->u.flush_cache.err_code = FIELD_GET( + HAL_REO_FLUSH_CACHE_STATUS_INFO0_BLOCK_ERR_CODE, desc->info0); + if (!status->u.flush_cache.err_code) + hal->avail_blk_resource |= BIT(hal->current_blk_index); + + status->u.flush_cache.cache_controller_flush_status_hit = FIELD_GET( + HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_STATUS_HIT, desc->info0); + + status->u.flush_cache.cache_controller_flush_status_desc_type = + FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_DESC_TYPE, + desc->info0); + status->u.flush_cache.cache_controller_flush_status_client_id = + FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_CLIENT_ID, + desc->info0); + status->u.flush_cache.cache_controller_flush_status_err = + FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_ERR, + desc->info0); + status->u.flush_cache.cache_controller_flush_status_cnt = + FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_COUNT, + desc->info0); +} + +void +qwx_hal_reo_unblk_cache_status(struct qwx_softc *sc, uint32_t *reo_desc, + struct hal_reo_status *status) +{ + struct ath11k_hal *hal = &sc->hal; + struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; + struct hal_reo_unblock_cache_status *desc = + (struct hal_reo_unblock_cache_status *)tlv->value; + + status->uniform_hdr.cmd_num = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, desc->hdr.info0); + status->uniform_hdr.cmd_status = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, desc->hdr.info0); + + status->u.unblock_cache.err_detected = FIELD_GET( + HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_IS_ERR, desc->info0); + status->u.unblock_cache.unblock_type = FIELD_GET( + HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_TYPE, desc->info0); + + if (!status->u.unblock_cache.err_detected && + status->u.unblock_cache.unblock_type == + HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE) + hal->avail_blk_resource &= ~BIT(hal->current_blk_index); +} + +void +qwx_hal_reo_flush_timeout_list_status(struct qwx_softc *ab, uint32_t *reo_desc, + struct hal_reo_status *status) +{ + struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; + struct hal_reo_flush_timeout_list_status *desc = + (struct hal_reo_flush_timeout_list_status *)tlv->value; + + status->uniform_hdr.cmd_num = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, desc->hdr.info0); + status->uniform_hdr.cmd_status = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, desc->hdr.info0); + + status->u.timeout_list.err_detected = FIELD_GET( + HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_IS_ERR, desc->info0); + status->u.timeout_list.list_empty = FIELD_GET( + HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_LIST_EMPTY, desc->info0); + + status->u.timeout_list.release_desc_cnt = FIELD_GET( + HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_REL_DESC_COUNT, desc->info1); + status->u.timeout_list.fwd_buf_cnt = FIELD_GET( + HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_FWD_BUF_COUNT, desc->info1); +} + +void +qwx_hal_reo_desc_thresh_reached_status(struct qwx_softc *sc, uint32_t *reo_desc, + struct hal_reo_status *status) +{ + struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; + struct hal_reo_desc_thresh_reached_status *desc = + (struct hal_reo_desc_thresh_reached_status *)tlv->value; + + status->uniform_hdr.cmd_num = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, desc->hdr.info0); + status->uniform_hdr.cmd_status = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, desc->hdr.info0); + + status->u.desc_thresh_reached.threshold_idx = FIELD_GET( + HAL_REO_DESC_THRESH_STATUS_INFO0_THRESH_INDEX, desc->info0); + + status->u.desc_thresh_reached.link_desc_counter0 = FIELD_GET( + HAL_REO_DESC_THRESH_STATUS_INFO1_LINK_DESC_COUNTER0, desc->info1); + + status->u.desc_thresh_reached.link_desc_counter1 = FIELD_GET( + HAL_REO_DESC_THRESH_STATUS_INFO2_LINK_DESC_COUNTER1, desc->info2); + + status->u.desc_thresh_reached.link_desc_counter2 = FIELD_GET( + HAL_REO_DESC_THRESH_STATUS_INFO3_LINK_DESC_COUNTER2, desc->info3); + + status->u.desc_thresh_reached.link_desc_counter_sum = FIELD_GET( + HAL_REO_DESC_THRESH_STATUS_INFO4_LINK_DESC_COUNTER_SUM, + desc->info4); +} + +void +qwx_hal_reo_update_rx_reo_queue_status(struct qwx_softc *ab, uint32_t *reo_desc, + struct hal_reo_status *status) +{ + struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; + struct hal_reo_status_hdr *desc = + (struct hal_reo_status_hdr *)tlv->value; + + status->uniform_hdr.cmd_num = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, desc->info0); + status->uniform_hdr.cmd_status = FIELD_GET( + HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, desc->info0); +} + int qwx_dp_process_reo_status(struct qwx_softc *sc) { - return 0; + struct qwx_dp *dp = &sc->dp; + struct hal_srng *srng; + struct dp_reo_cmd *cmd, *tmp; + int found = 0, ret = 0; + uint32_t *reo_desc; + uint16_t tag; + 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 + qwx_hal_srng_access_begin(sc, srng); + + while ((reo_desc = qwx_hal_srng_dst_get_next_entry(sc, srng))) { + ret = 1; + + tag = FIELD_GET(HAL_SRNG_TLV_HDR_TAG, *reo_desc); + switch (tag) { + case HAL_REO_GET_QUEUE_STATS_STATUS: + qwx_hal_reo_status_queue_stats(sc, reo_desc, + &reo_status); + break; + case HAL_REO_FLUSH_QUEUE_STATUS: + qwx_hal_reo_flush_queue_status(sc, reo_desc, + &reo_status); + break; + case HAL_REO_FLUSH_CACHE_STATUS: + qwx_hal_reo_flush_cache_status(sc, reo_desc, + &reo_status); + break; + case HAL_REO_UNBLOCK_CACHE_STATUS: + qwx_hal_reo_unblk_cache_status(sc, reo_desc, + &reo_status); + break; + case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS: + qwx_hal_reo_flush_timeout_list_status(sc, reo_desc, + &reo_status); + break; + case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS: + qwx_hal_reo_desc_thresh_reached_status(sc, reo_desc, + &reo_status); + break; + case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS: + qwx_hal_reo_update_rx_reo_queue_status(sc, reo_desc, + &reo_status); + break; + default: + printf("%s: Unknown reo status type %d\n", + sc->sc_dev.dv_xname, tag); + continue; + } +#ifdef notyet + spin_lock_bh(&dp->reo_cmd_lock); +#endif + TAILQ_FOREACH_SAFE(cmd, &dp->reo_cmd_list, entry, tmp) { + if (reo_status.uniform_hdr.cmd_num == cmd->cmd_num) { + found = 1; + TAILQ_REMOVE(&dp->reo_cmd_list, cmd, entry); + break; + } + } +#ifdef notyet + spin_unlock_bh(&dp->reo_cmd_lock); +#endif + if (found) { + cmd->handler(dp, (void *)&cmd->data, + reo_status.uniform_hdr.cmd_status); + free(cmd, M_DEVBUF, sizeof(*cmd)); + } + found = 0; + } + + qwx_hal_srng_access_end(sc, srng); +#ifdef notyet + spin_unlock_bh(&srng->lock); +#endif + return ret; } int diff --git a/sys/dev/ic/qwxvar.h b/sys/dev/ic/qwxvar.h index bd98ff7c044..0f91f7bb8eb 100644 --- a/sys/dev/ic/qwxvar.h +++ b/sys/dev/ic/qwxvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: qwxvar.h,v 1.16 2024/02/09 12:50:10 bluhm Exp $ */ +/* $OpenBSD: qwxvar.h,v 1.17 2024/02/09 14:07:27 stsp Exp $ */ /* * Copyright (c) 2018-2019 The Linux Foundation. @@ -662,6 +662,100 @@ struct hal_srng_config { #define QWX_NUM_SRNG_CFG 21 +struct hal_reo_status_header { + uint16_t cmd_num; + enum hal_reo_cmd_status cmd_status; + uint16_t cmd_exe_time; + uint32_t timestamp; +}; + +struct hal_reo_status_queue_stats { + uint16_t ssn; + uint16_t curr_idx; + uint32_t pn[4]; + uint32_t last_rx_queue_ts; + uint32_t last_rx_dequeue_ts; + uint32_t rx_bitmap[8]; /* Bitmap from 0-255 */ + uint32_t curr_mpdu_cnt; + uint32_t curr_msdu_cnt; + uint16_t fwd_due_to_bar_cnt; + uint16_t dup_cnt; + uint32_t frames_in_order_cnt; + uint32_t num_mpdu_processed_cnt; + uint32_t num_msdu_processed_cnt; + uint32_t total_num_processed_byte_cnt; + uint32_t late_rx_mpdu_cnt; + uint32_t reorder_hole_cnt; + uint8_t timeout_cnt; + uint8_t bar_rx_cnt; + uint8_t num_window_2k_jump_cnt; +}; + +struct hal_reo_status_flush_queue { + bool err_detected; +}; + +enum hal_reo_status_flush_cache_err_code { + HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_SUCCESS, + HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_IN_USE, + HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_NOT_FOUND, +}; + +struct hal_reo_status_flush_cache { + bool err_detected; + enum hal_reo_status_flush_cache_err_code err_code; + bool cache_controller_flush_status_hit; + uint8_t cache_controller_flush_status_desc_type; + uint8_t cache_controller_flush_status_client_id; + uint8_t cache_controller_flush_status_err; + uint8_t cache_controller_flush_status_cnt; +}; + +enum hal_reo_status_unblock_cache_type { + HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE, + HAL_REO_STATUS_UNBLOCK_ENTIRE_CACHE_USAGE, +}; + +struct hal_reo_status_unblock_cache { + bool err_detected; + enum hal_reo_status_unblock_cache_type unblock_type; +}; + +struct hal_reo_status_flush_timeout_list { + bool err_detected; + bool list_empty; + uint16_t release_desc_cnt; + uint16_t fwd_buf_cnt; +}; + +enum hal_reo_threshold_idx { + HAL_REO_THRESHOLD_IDX_DESC_COUNTER0, + HAL_REO_THRESHOLD_IDX_DESC_COUNTER1, + HAL_REO_THRESHOLD_IDX_DESC_COUNTER2, + HAL_REO_THRESHOLD_IDX_DESC_COUNTER_SUM, +}; + +struct hal_reo_status_desc_thresh_reached { + enum hal_reo_threshold_idx threshold_idx; + uint32_t link_desc_counter0; + uint32_t link_desc_counter1; + uint32_t link_desc_counter2; + uint32_t link_desc_counter_sum; +}; + +struct hal_reo_status { + struct hal_reo_status_header uniform_hdr; + uint8_t loop_cnt; + union { + struct hal_reo_status_queue_stats queue_stats; + struct hal_reo_status_flush_queue flush_queue; + struct hal_reo_status_flush_cache flush_cache; + struct hal_reo_status_unblock_cache unblock_cache; + struct hal_reo_status_flush_timeout_list timeout_list; + struct hal_reo_status_desc_thresh_reached desc_thresh_reached; + } u; +}; + /* HAL context to be used to access SRNG APIs (currently used by data path * and transport (CE) modules) */ -- 2.20.1