Loading dp/inc/cdp_txrx_cmn_struct.h +1 −0 Original line number Diff line number Diff line Loading @@ -293,6 +293,7 @@ enum cdp_host_txrx_stats { TXRX_SOC_INTERRUPT_STATS = 12, TXRX_SOC_FSE_STATS = 13, TXRX_HAL_REG_WRITE_STATS = 14, TXRX_SOC_REO_HW_DESC_DUMP = 15, TXRX_HOST_STATS_MAX, }; Loading dp/wifi3.0/dp_ipa.c +88 −60 Original line number Diff line number Diff line /* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -100,6 +100,7 @@ static QDF_STATUS __dp_ipa_handle_buf_smmu_mapping(struct dp_soc *soc, bool create) { qdf_mem_info_t mem_map_table = {0}; QDF_STATUS ret = QDF_STATUS_SUCCESS; if (!qdf_ipa_is_ready()) return QDF_STATUS_SUCCESS; Loading @@ -108,10 +109,27 @@ static QDF_STATUS __dp_ipa_handle_buf_smmu_mapping(struct dp_soc *soc, qdf_nbuf_get_frag_paddr(nbuf, 0), size); if (create) { /* Assert if PA is zero */ qdf_assert_always(mem_map_table.pa); ret = qdf_ipa_wdi_create_smmu_mapping(1, &mem_map_table); } else { ret = qdf_ipa_wdi_release_smmu_mapping(1, &mem_map_table); } qdf_assert_always(!ret); /* Return status of mapping/unmapping is stored in * mem_map_table.result field, assert if the result * is failure */ if (create) return qdf_ipa_wdi_create_smmu_mapping(1, &mem_map_table); qdf_assert_always(!mem_map_table.result); else return qdf_ipa_wdi_release_smmu_mapping(1, &mem_map_table); qdf_assert_always(mem_map_table.result >= mem_map_table.size); return ret; } QDF_STATUS dp_ipa_handle_rx_buf_smmu_mapping(struct dp_soc *soc, Loading Loading @@ -582,6 +600,9 @@ int dp_ipa_ring_resource_setup(struct dp_soc *soc, srng_params.ring_base_vaddr; soc->ipa_uc_tx_rsc.ipa_wbm_ring_size = (srng_params.num_entries * srng_params.entry_size) << 2; soc->ipa_uc_tx_rsc.ipa_wbm_hp_shadow_paddr = hal_srng_get_hp_addr(hal_soc_to_hal_soc_handle(hal_soc), hal_srng_to_hal_ring_handle(hal_srng)); addr_offset = (unsigned long)(hal_srng->u.dst_ring.tp_addr) - (unsigned long)(hal_soc->dev_base_addr); soc->ipa_uc_tx_rsc.ipa_wbm_tp_paddr = Loading Loading @@ -743,14 +764,33 @@ QDF_STATUS dp_ipa_get_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_SUCCESS; } static void dp_ipa_set_tx_doorbell_paddr(struct dp_soc *soc, struct dp_ipa_resources *ipa_res) { struct hal_srng *wbm_srng = (struct hal_srng *) soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; hal_srng_dst_set_hp_paddr_confirm(wbm_srng, ipa_res->tx_comp_doorbell_paddr); dp_info("paddr %pK vaddr %pK", (void *)ipa_res->tx_comp_doorbell_paddr, (void *)ipa_res->tx_comp_doorbell_vaddr); } #ifdef IPA_SET_RESET_TX_DB_PA #define DP_IPA_SET_TX_DB_PADDR(soc, ipa_res) #else #define DP_IPA_SET_TX_DB_PADDR(soc, ipa_res) \ dp_ipa_set_tx_doorbell_paddr(soc, ipa_res) #endif QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); struct dp_ipa_resources *ipa_res; struct hal_srng *wbm_srng = (struct hal_srng *) soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; struct hal_srng *reo_srng = (struct hal_srng *) soc->reo_dest_ring[IPA_REO_DEST_RING_IDX].hal_srng; uint32_t tx_comp_doorbell_dmaaddr; Loading Loading @@ -789,11 +829,7 @@ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) qdf_assert_always(!ret); } hal_srng_dst_set_hp_paddr(wbm_srng, ipa_res->tx_comp_doorbell_paddr); dp_info("paddr %pK vaddr %pK", (void *)ipa_res->tx_comp_doorbell_paddr, (void *)ipa_res->tx_comp_doorbell_vaddr); DP_IPA_SET_TX_DB_PADDR(soc, ipa_res); /* * For RX, REO module on Napier/Hastings does reordering on incoming Loading @@ -802,7 +838,8 @@ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) * to IPA. * Set the doorbell addr for the REO ring. */ hal_srng_dst_set_hp_paddr(reo_srng, ipa_res->rx_ready_doorbell_paddr); hal_srng_dst_set_hp_paddr_confirm(reo_srng, ipa_res->rx_ready_doorbell_paddr); return QDF_STATUS_SUCCESS; } Loading Loading @@ -1743,6 +1780,36 @@ QDF_STATUS dp_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled) return QDF_STATUS_SUCCESS; } #ifdef IPA_SET_RESET_TX_DB_PA static QDF_STATUS dp_ipa_reset_tx_doorbell_pa(struct dp_soc *soc, struct dp_ipa_resources *ipa_res) { hal_ring_handle_t wbm_srng = soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; qdf_dma_addr_t hp_addr; if (!wbm_srng) return QDF_STATUS_E_FAILURE; hp_addr = soc->ipa_uc_tx_rsc.ipa_wbm_hp_shadow_paddr; hal_srng_dst_set_hp_paddr_confirm((struct hal_srng *)wbm_srng, hp_addr); dp_info("Reset WBM HP addr paddr: %pK", (void *)hp_addr); return QDF_STATUS_SUCCESS; } #define DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res) \ dp_ipa_set_tx_doorbell_paddr((soc), (ipa_res)) #define DP_IPA_RESET_TX_DB_PA(soc, ipa_res) \ dp_ipa_reset_tx_doorbell_pa((soc), (ipa_res)) #else #define DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res) #define DP_IPA_RESET_TX_DB_PA(soc, ipa_res) #endif QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); Loading @@ -1761,6 +1828,7 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) ipa_res = &pdev->ipa_resource; qdf_atomic_set(&soc->ipa_pipes_enabled, 1); DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res); dp_ipa_handle_rx_buf_pool_smmu_mapping(soc, pdev, true); result = qdf_ipa_wdi_enable_pipes(); Loading @@ -1769,6 +1837,7 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) "%s: Enable WDI PIPE fail, code %d", __func__, result); qdf_atomic_set(&soc->ipa_pipes_enabled, 0); DP_IPA_RESET_TX_DB_PA(soc, ipa_res); dp_ipa_handle_rx_buf_pool_smmu_mapping(soc, pdev, false); return QDF_STATUS_E_FAILURE; } Loading @@ -1783,69 +1852,28 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_SUCCESS; } #ifdef DEVICE_FORCE_WAKE_ENABLED /* * dp_ipa_get_tx_comp_pending_check() - Check if tx completions are pending. * @soc: DP pdev Context * * Ring full condition is checked to find if buffers are left for * processing as host only allocates buffers in this ring and IPA HW processes * the buffer. * * Return: True if tx completions are pending */ static bool dp_ipa_get_tx_comp_pending_check(struct dp_soc *soc) { struct dp_srng *tx_comp_ring = &soc->tx_comp_ring[IPA_TX_COMP_RING_IDX]; uint32_t hp, tp, entry_size, buf_cnt; hal_get_hw_hptp(soc->hal_soc, tx_comp_ring->hal_srng, &hp, &tp, WBM2SW_RELEASE); entry_size = hal_srng_get_entrysize(soc->hal_soc, WBM2SW_RELEASE) >> 2; if (hp > tp) buf_cnt = (hp - tp) / entry_size; else buf_cnt = (tx_comp_ring->num_entries - tp + hp) / entry_size; return (soc->ipa_uc_tx_rsc.alloc_tx_buf_cnt != buf_cnt); } #endif QDF_STATUS dp_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); int timeout = TX_COMP_DRAIN_WAIT_TIMEOUT_MS; QDF_STATUS result; struct dp_ipa_resources *ipa_res; if (!pdev) { dp_err("Invalid instance"); return QDF_STATUS_E_FAILURE; } ipa_res = &pdev->ipa_resource; qdf_sleep(TX_COMP_DRAIN_WAIT_TIMEOUT_MS); /* * The tx completions pending check will trigger register read * for HP and TP of wbm2sw2 ring. There is a possibility for * these reg read to cause a NOC error if UMAC is in low power * state. The WAR is to sleep for the drain timeout without checking * for the pending tx completions. This WAR can be replaced with * poll logic for HP/TP difference once force wake is in place. * Reset the tx completion doorbell address before invoking IPA disable * pipes API to ensure that there is no access to IPA tx doorbell * address post disable pipes. */ #ifdef DEVICE_FORCE_WAKE_ENABLED while (dp_ipa_get_tx_comp_pending_check(soc)) { qdf_sleep(TX_COMP_DRAIN_WAIT_MS); timeout -= TX_COMP_DRAIN_WAIT_MS; if (timeout <= 0) { dp_err("Tx completions pending. Force Disabling pipes"); break; } } #else qdf_sleep(timeout); #endif DP_IPA_RESET_TX_DB_PA(soc, ipa_res); result = qdf_ipa_wdi_disable_pipes(); if (result) { Loading dp/wifi3.0/dp_main.c +12 −0 Original line number Diff line number Diff line Loading @@ -396,6 +396,7 @@ const int dp_stats_mapping_table[][STATS_TYPE_MAX] = { {TXRX_FW_STATS_INVALID, TXRX_SOC_INTERRUPT_STATS}, {TXRX_FW_STATS_INVALID, TXRX_SOC_FSE_STATS}, {TXRX_FW_STATS_INVALID, TXRX_HAL_REG_WRITE_STATS}, {TXRX_FW_STATS_INVALID, TXRX_SOC_REO_HW_DESC_DUMP}, {HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT, TXRX_HOST_STATS_INVALID} }; Loading Loading @@ -8243,6 +8244,10 @@ dp_print_host_stats(struct dp_vdev *vdev, hal_dump_reg_write_stats(pdev->soc->hal_soc); hal_dump_reg_write_srng_stats(pdev->soc->hal_soc); break; case TXRX_SOC_REO_HW_DESC_DUMP: dp_get_rx_reo_queue_info((struct cdp_soc_t *)pdev->soc, vdev->vdev_id); break; default: dp_info("Wrong Input For TxRx Host Stats"); dp_txrx_stats_help(); Loading Loading @@ -11041,6 +11046,7 @@ static void dp_drain_txrx(struct cdp_soc_t *soc_handle) struct dp_soc *soc = (struct dp_soc *)soc_handle; uint32_t cur_tx_limit, cur_rx_limit; uint32_t budget = 0xffff; uint32_t val; int i; cur_tx_limit = soc->wlan_cfg_ctx->tx_comp_loop_pkt_limit; Loading @@ -11058,6 +11064,12 @@ static void dp_drain_txrx(struct cdp_soc_t *soc_handle) dp_service_srngs(&soc->intr_ctx[i], budget); dp_update_soft_irq_limits(soc, cur_tx_limit, cur_rx_limit); /* Do a dummy read at offset 0; this will ensure all * pendings writes(HP/TP) are flushed before read returns. */ val = HAL_REG_READ((struct hal_soc *)soc->hal_soc, 0); dp_debug("Register value at offset 0: %u\n", val); } #endif Loading dp/wifi3.0/dp_peer.c +138 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,12 @@ #include "dp_hist.h" #endif #ifdef REO_QDESC_HISTORY #define REO_QDESC_HISTORY_SIZE 512 uint64_t reo_qdesc_history_idx; struct reo_qdesc_event reo_qdesc_history[REO_QDESC_HISTORY_SIZE]; #endif #ifdef FEATURE_WDS static inline bool dp_peer_ast_free_in_unmap_supported(struct dp_soc *soc, Loading Loading @@ -69,6 +75,42 @@ dp_peer_ast_free_in_unmap_supported(struct dp_soc *soc, } #endif #ifdef REO_QDESC_HISTORY static inline void dp_rx_reo_qdesc_history_add(struct reo_desc_list_node *free_desc, enum reo_qdesc_event_type type) { struct reo_qdesc_event *evt; struct dp_rx_tid *rx_tid = &free_desc->rx_tid; uint32_t idx; reo_qdesc_history_idx++; idx = (reo_qdesc_history_idx & (REO_QDESC_HISTORY_SIZE - 1)); evt = &reo_qdesc_history[idx]; qdf_mem_copy(evt->peer_mac, free_desc->peer_mac, QDF_MAC_ADDR_SIZE); evt->qdesc_addr = rx_tid->hw_qdesc_paddr; evt->ts = qdf_get_log_timestamp(); evt->type = type; } #define DP_RX_REO_QDESC_GET_MAC(freedesc, peer) \ qdf_mem_copy(freedesc->peer_mac, peer->mac_addr.raw, QDF_MAC_ADDR_SIZE) #define DP_RX_REO_QDESC_UPDATE_EVT(free_desc) \ dp_rx_reo_qdesc_history_add((free_desc), REO_QDESC_UPDATE_CB) #define DP_RX_REO_QDESC_FREE_EVT(free_desc) \ dp_rx_reo_qdesc_history_add((free_desc), REO_QDESC_FREE) #else #define DP_RX_REO_QDESC_GET_MAC(freedesc, peer) #define DP_RX_REO_QDESC_UPDATE_EVT(free_desc) #define DP_RX_REO_QDESC_FREE_EVT(free_desc) #endif static inline void dp_set_ssn_valid_flag(struct hal_reo_cmd_params *params, uint8_t valid) Loading Loading @@ -2307,6 +2349,9 @@ static void dp_reo_desc_free(struct dp_soc *soc, void *cb_ctxt, "%s:%lu hw_qdesc_paddr: %pK, tid:%d", __func__, curr_ts, (void *)(rx_tid->hw_qdesc_paddr), rx_tid->tid); DP_RX_REO_QDESC_FREE_EVT(freedesc); qdf_mem_unmap_nbytes_single(soc->osdev, rx_tid->hw_qdesc_paddr, QDF_DMA_BIDIRECTIONAL, Loading Loading @@ -2433,6 +2478,7 @@ QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid, } else { hw_qdesc_vaddr = rx_tid->hw_qdesc_vaddr_unaligned; } rx_tid->hw_qdesc_vaddr_aligned = hw_qdesc_vaddr; /* TODO: Ensure that sec_type is set before ADDBA is received. * Currently this is set based on htt indication Loading Loading @@ -2650,6 +2696,8 @@ void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, struct hal_reo_cmd_params params; bool flush_failure = false; DP_RX_REO_QDESC_UPDATE_EVT(freedesc); if (reo_status->rx_queue_status.header.status == HAL_REO_CMD_DRAIN) { qdf_mem_zero(reo_status, sizeof(*reo_status)); reo_status->fl_cache_status.header.status = HAL_REO_CMD_DRAIN; Loading Loading @@ -2803,6 +2851,8 @@ static int dp_rx_tid_delete_wifi3(struct dp_peer *peer, int tid) qdf_mem_zero(¶ms, sizeof(params)); DP_RX_REO_QDESC_GET_MAC(freedesc, peer); params.std.need_status = 1; params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff; params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32; Loading Loading @@ -4365,3 +4415,91 @@ struct dp_peer *dp_sta_vdev_self_peer_ref_n_get(struct dp_soc *soc, qdf_spin_unlock_bh(&vdev->peer_list_lock); return peer; } #ifdef DUMP_REO_QUEUE_INFO_IN_DDR void dp_dump_rx_reo_queue_info( struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status) { struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt; if (!rx_tid) return; if (reo_status->fl_cache_status.header.status != HAL_REO_CMD_SUCCESS) { dp_err_rl("Rx tid REO HW desc flush failed(%d)", reo_status->rx_queue_status.header.status); return; } qdf_spin_lock_bh(&rx_tid->tid_lock); hal_dump_rx_reo_queue_desc(rx_tid->hw_qdesc_vaddr_aligned); qdf_spin_unlock_bh(&rx_tid->tid_lock); } void dp_send_cache_flush_for_rx_tid( struct dp_soc *soc, struct dp_peer *peer) { int i; struct dp_rx_tid *rx_tid; struct hal_reo_cmd_params params; if (!peer) { dp_err_rl("Peer is NULL"); return; } for (i = 0; i < DP_MAX_TIDS; i++) { rx_tid = &peer->rx_tid[i]; if (!rx_tid) continue; qdf_spin_lock_bh(&rx_tid->tid_lock); if (rx_tid->hw_qdesc_vaddr_aligned) { qdf_mem_zero(¶ms, sizeof(params)); params.std.need_status = 1; params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff; params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32; params.u.fl_cache_params.flush_no_inval = 0; if (QDF_STATUS_SUCCESS != dp_reo_send_cmd( soc, CMD_FLUSH_CACHE, ¶ms, dp_dump_rx_reo_queue_info, (void *)rx_tid)) { dp_err_rl("cache flush send failed tid %d", rx_tid->tid); qdf_spin_unlock_bh(&rx_tid->tid_lock); break; } } qdf_spin_unlock_bh(&rx_tid->tid_lock); } } void dp_get_rx_reo_queue_info( struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { struct dp_soc *soc = (struct dp_soc *)soc_hdl; struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_GENERIC_STATS); struct dp_peer *peer = NULL; if (!vdev) { dp_err_rl("vdev is null for vdev_id: %u", vdev_id); goto failed; } peer = dp_vdev_bss_peer_ref_n_get(soc, vdev, DP_MOD_ID_GENERIC_STATS); if (!peer) { dp_err_rl("Peer is NULL"); goto failed; } dp_send_cache_flush_for_rx_tid(soc, peer); failed: if (peer) dp_peer_unref_delete(peer, DP_MOD_ID_GENERIC_STATS); if (vdev) dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_GENERIC_STATS); } #endif /* DUMP_REO_QUEUE_INFO_IN_DDR */ dp/wifi3.0/dp_peer.h +107 −0 Original line number Diff line number Diff line Loading @@ -22,10 +22,28 @@ #include <qdf_lock.h> #include "dp_types.h" #ifdef DUMP_REO_QUEUE_INFO_IN_DDR #include "hal_reo.h" #endif #define DP_INVALID_PEER_ID 0xffff #define DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC 5000 #ifdef REO_QDESC_HISTORY enum reo_qdesc_event_type { REO_QDESC_UPDATE_CB = 0, REO_QDESC_FREE, }; struct reo_qdesc_event { qdf_dma_addr_t qdesc_addr; uint64_t ts; enum reo_qdesc_event_type type; uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; }; #endif typedef void dp_peer_iter_func(struct dp_soc *soc, struct dp_peer *peer, void *arg); void dp_peer_unref_delete(struct dp_peer *peer, enum dp_mod_id id); Loading Loading @@ -843,4 +861,93 @@ static inline void dp_peer_delete_ast_entries(struct dp_soc *soc, { } #endif #ifdef FEATURE_MEC /** * dp_peer_mec_spinlock_create() - Create the MEC spinlock * @soc: SoC handle * * Return: none */ void dp_peer_mec_spinlock_create(struct dp_soc *soc); /** * dp_peer_mec_spinlock_destroy() - Destroy the MEC spinlock * @soc: SoC handle * * Return: none */ void dp_peer_mec_spinlock_destroy(struct dp_soc *soc); /** * dp_peer_mec_flush_entries() - Delete all mec entries in table * @soc: Datapath SOC * * Return: None */ void dp_peer_mec_flush_entries(struct dp_soc *soc); #else static inline void dp_peer_mec_spinlock_create(struct dp_soc *soc) { } static inline void dp_peer_mec_spinlock_destroy(struct dp_soc *soc) { } static inline void dp_peer_mec_flush_entries(struct dp_soc *soc) { } #endif #ifdef DUMP_REO_QUEUE_INFO_IN_DDR /** * dp_send_cache_flush_for_rx_tid() - Send cache flush cmd to REO per tid * @soc : dp_soc handle * @peer: peer * * This function is used to send cache flush cmd to reo and * to register the callback to handle the dumping of the reo * queue stas from DDR * * Return: none */ void dp_send_cache_flush_for_rx_tid( struct dp_soc *soc, struct dp_peer *peer); /** * dp_get_rx_reo_queue_info() - Handler to get rx tid info * @soc : cdp_soc_t handle * @vdev_id: vdev id * * Handler to get rx tid info from DDR after h/w cache is * invalidated first using the cache flush cmd. * * Return: none */ void dp_get_rx_reo_queue_info( struct cdp_soc_t *soc_hdl, uint8_t vdev_id); /** * dp_dump_rx_reo_queue_info() - Callback function to dump reo queue stats * @soc : dp_soc handle * @cb_ctxt - callback context * @reo_status: vdev id * * This is the callback function registered after sending the reo cmd * to flush the h/w cache and invalidate it. In the callback the reo * queue desc info is dumped from DDR. * * Return: none */ void dp_dump_rx_reo_queue_info( struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status); #else /* DUMP_REO_QUEUE_INFO_IN_DDR */ static inline void dp_get_rx_reo_queue_info( struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { } #endif /* DUMP_REO_QUEUE_INFO_IN_DDR */ #endif /* _DP_PEER_H_ */ Loading
dp/inc/cdp_txrx_cmn_struct.h +1 −0 Original line number Diff line number Diff line Loading @@ -293,6 +293,7 @@ enum cdp_host_txrx_stats { TXRX_SOC_INTERRUPT_STATS = 12, TXRX_SOC_FSE_STATS = 13, TXRX_HAL_REG_WRITE_STATS = 14, TXRX_SOC_REO_HW_DESC_DUMP = 15, TXRX_HOST_STATS_MAX, }; Loading
dp/wifi3.0/dp_ipa.c +88 −60 Original line number Diff line number Diff line /* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -100,6 +100,7 @@ static QDF_STATUS __dp_ipa_handle_buf_smmu_mapping(struct dp_soc *soc, bool create) { qdf_mem_info_t mem_map_table = {0}; QDF_STATUS ret = QDF_STATUS_SUCCESS; if (!qdf_ipa_is_ready()) return QDF_STATUS_SUCCESS; Loading @@ -108,10 +109,27 @@ static QDF_STATUS __dp_ipa_handle_buf_smmu_mapping(struct dp_soc *soc, qdf_nbuf_get_frag_paddr(nbuf, 0), size); if (create) { /* Assert if PA is zero */ qdf_assert_always(mem_map_table.pa); ret = qdf_ipa_wdi_create_smmu_mapping(1, &mem_map_table); } else { ret = qdf_ipa_wdi_release_smmu_mapping(1, &mem_map_table); } qdf_assert_always(!ret); /* Return status of mapping/unmapping is stored in * mem_map_table.result field, assert if the result * is failure */ if (create) return qdf_ipa_wdi_create_smmu_mapping(1, &mem_map_table); qdf_assert_always(!mem_map_table.result); else return qdf_ipa_wdi_release_smmu_mapping(1, &mem_map_table); qdf_assert_always(mem_map_table.result >= mem_map_table.size); return ret; } QDF_STATUS dp_ipa_handle_rx_buf_smmu_mapping(struct dp_soc *soc, Loading Loading @@ -582,6 +600,9 @@ int dp_ipa_ring_resource_setup(struct dp_soc *soc, srng_params.ring_base_vaddr; soc->ipa_uc_tx_rsc.ipa_wbm_ring_size = (srng_params.num_entries * srng_params.entry_size) << 2; soc->ipa_uc_tx_rsc.ipa_wbm_hp_shadow_paddr = hal_srng_get_hp_addr(hal_soc_to_hal_soc_handle(hal_soc), hal_srng_to_hal_ring_handle(hal_srng)); addr_offset = (unsigned long)(hal_srng->u.dst_ring.tp_addr) - (unsigned long)(hal_soc->dev_base_addr); soc->ipa_uc_tx_rsc.ipa_wbm_tp_paddr = Loading Loading @@ -743,14 +764,33 @@ QDF_STATUS dp_ipa_get_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_SUCCESS; } static void dp_ipa_set_tx_doorbell_paddr(struct dp_soc *soc, struct dp_ipa_resources *ipa_res) { struct hal_srng *wbm_srng = (struct hal_srng *) soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; hal_srng_dst_set_hp_paddr_confirm(wbm_srng, ipa_res->tx_comp_doorbell_paddr); dp_info("paddr %pK vaddr %pK", (void *)ipa_res->tx_comp_doorbell_paddr, (void *)ipa_res->tx_comp_doorbell_vaddr); } #ifdef IPA_SET_RESET_TX_DB_PA #define DP_IPA_SET_TX_DB_PADDR(soc, ipa_res) #else #define DP_IPA_SET_TX_DB_PADDR(soc, ipa_res) \ dp_ipa_set_tx_doorbell_paddr(soc, ipa_res) #endif QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); struct dp_ipa_resources *ipa_res; struct hal_srng *wbm_srng = (struct hal_srng *) soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; struct hal_srng *reo_srng = (struct hal_srng *) soc->reo_dest_ring[IPA_REO_DEST_RING_IDX].hal_srng; uint32_t tx_comp_doorbell_dmaaddr; Loading Loading @@ -789,11 +829,7 @@ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) qdf_assert_always(!ret); } hal_srng_dst_set_hp_paddr(wbm_srng, ipa_res->tx_comp_doorbell_paddr); dp_info("paddr %pK vaddr %pK", (void *)ipa_res->tx_comp_doorbell_paddr, (void *)ipa_res->tx_comp_doorbell_vaddr); DP_IPA_SET_TX_DB_PADDR(soc, ipa_res); /* * For RX, REO module on Napier/Hastings does reordering on incoming Loading @@ -802,7 +838,8 @@ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) * to IPA. * Set the doorbell addr for the REO ring. */ hal_srng_dst_set_hp_paddr(reo_srng, ipa_res->rx_ready_doorbell_paddr); hal_srng_dst_set_hp_paddr_confirm(reo_srng, ipa_res->rx_ready_doorbell_paddr); return QDF_STATUS_SUCCESS; } Loading Loading @@ -1743,6 +1780,36 @@ QDF_STATUS dp_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled) return QDF_STATUS_SUCCESS; } #ifdef IPA_SET_RESET_TX_DB_PA static QDF_STATUS dp_ipa_reset_tx_doorbell_pa(struct dp_soc *soc, struct dp_ipa_resources *ipa_res) { hal_ring_handle_t wbm_srng = soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; qdf_dma_addr_t hp_addr; if (!wbm_srng) return QDF_STATUS_E_FAILURE; hp_addr = soc->ipa_uc_tx_rsc.ipa_wbm_hp_shadow_paddr; hal_srng_dst_set_hp_paddr_confirm((struct hal_srng *)wbm_srng, hp_addr); dp_info("Reset WBM HP addr paddr: %pK", (void *)hp_addr); return QDF_STATUS_SUCCESS; } #define DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res) \ dp_ipa_set_tx_doorbell_paddr((soc), (ipa_res)) #define DP_IPA_RESET_TX_DB_PA(soc, ipa_res) \ dp_ipa_reset_tx_doorbell_pa((soc), (ipa_res)) #else #define DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res) #define DP_IPA_RESET_TX_DB_PA(soc, ipa_res) #endif QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); Loading @@ -1761,6 +1828,7 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) ipa_res = &pdev->ipa_resource; qdf_atomic_set(&soc->ipa_pipes_enabled, 1); DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res); dp_ipa_handle_rx_buf_pool_smmu_mapping(soc, pdev, true); result = qdf_ipa_wdi_enable_pipes(); Loading @@ -1769,6 +1837,7 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) "%s: Enable WDI PIPE fail, code %d", __func__, result); qdf_atomic_set(&soc->ipa_pipes_enabled, 0); DP_IPA_RESET_TX_DB_PA(soc, ipa_res); dp_ipa_handle_rx_buf_pool_smmu_mapping(soc, pdev, false); return QDF_STATUS_E_FAILURE; } Loading @@ -1783,69 +1852,28 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_SUCCESS; } #ifdef DEVICE_FORCE_WAKE_ENABLED /* * dp_ipa_get_tx_comp_pending_check() - Check if tx completions are pending. * @soc: DP pdev Context * * Ring full condition is checked to find if buffers are left for * processing as host only allocates buffers in this ring and IPA HW processes * the buffer. * * Return: True if tx completions are pending */ static bool dp_ipa_get_tx_comp_pending_check(struct dp_soc *soc) { struct dp_srng *tx_comp_ring = &soc->tx_comp_ring[IPA_TX_COMP_RING_IDX]; uint32_t hp, tp, entry_size, buf_cnt; hal_get_hw_hptp(soc->hal_soc, tx_comp_ring->hal_srng, &hp, &tp, WBM2SW_RELEASE); entry_size = hal_srng_get_entrysize(soc->hal_soc, WBM2SW_RELEASE) >> 2; if (hp > tp) buf_cnt = (hp - tp) / entry_size; else buf_cnt = (tx_comp_ring->num_entries - tp + hp) / entry_size; return (soc->ipa_uc_tx_rsc.alloc_tx_buf_cnt != buf_cnt); } #endif QDF_STATUS dp_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); int timeout = TX_COMP_DRAIN_WAIT_TIMEOUT_MS; QDF_STATUS result; struct dp_ipa_resources *ipa_res; if (!pdev) { dp_err("Invalid instance"); return QDF_STATUS_E_FAILURE; } ipa_res = &pdev->ipa_resource; qdf_sleep(TX_COMP_DRAIN_WAIT_TIMEOUT_MS); /* * The tx completions pending check will trigger register read * for HP and TP of wbm2sw2 ring. There is a possibility for * these reg read to cause a NOC error if UMAC is in low power * state. The WAR is to sleep for the drain timeout without checking * for the pending tx completions. This WAR can be replaced with * poll logic for HP/TP difference once force wake is in place. * Reset the tx completion doorbell address before invoking IPA disable * pipes API to ensure that there is no access to IPA tx doorbell * address post disable pipes. */ #ifdef DEVICE_FORCE_WAKE_ENABLED while (dp_ipa_get_tx_comp_pending_check(soc)) { qdf_sleep(TX_COMP_DRAIN_WAIT_MS); timeout -= TX_COMP_DRAIN_WAIT_MS; if (timeout <= 0) { dp_err("Tx completions pending. Force Disabling pipes"); break; } } #else qdf_sleep(timeout); #endif DP_IPA_RESET_TX_DB_PA(soc, ipa_res); result = qdf_ipa_wdi_disable_pipes(); if (result) { Loading
dp/wifi3.0/dp_main.c +12 −0 Original line number Diff line number Diff line Loading @@ -396,6 +396,7 @@ const int dp_stats_mapping_table[][STATS_TYPE_MAX] = { {TXRX_FW_STATS_INVALID, TXRX_SOC_INTERRUPT_STATS}, {TXRX_FW_STATS_INVALID, TXRX_SOC_FSE_STATS}, {TXRX_FW_STATS_INVALID, TXRX_HAL_REG_WRITE_STATS}, {TXRX_FW_STATS_INVALID, TXRX_SOC_REO_HW_DESC_DUMP}, {HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT, TXRX_HOST_STATS_INVALID} }; Loading Loading @@ -8243,6 +8244,10 @@ dp_print_host_stats(struct dp_vdev *vdev, hal_dump_reg_write_stats(pdev->soc->hal_soc); hal_dump_reg_write_srng_stats(pdev->soc->hal_soc); break; case TXRX_SOC_REO_HW_DESC_DUMP: dp_get_rx_reo_queue_info((struct cdp_soc_t *)pdev->soc, vdev->vdev_id); break; default: dp_info("Wrong Input For TxRx Host Stats"); dp_txrx_stats_help(); Loading Loading @@ -11041,6 +11046,7 @@ static void dp_drain_txrx(struct cdp_soc_t *soc_handle) struct dp_soc *soc = (struct dp_soc *)soc_handle; uint32_t cur_tx_limit, cur_rx_limit; uint32_t budget = 0xffff; uint32_t val; int i; cur_tx_limit = soc->wlan_cfg_ctx->tx_comp_loop_pkt_limit; Loading @@ -11058,6 +11064,12 @@ static void dp_drain_txrx(struct cdp_soc_t *soc_handle) dp_service_srngs(&soc->intr_ctx[i], budget); dp_update_soft_irq_limits(soc, cur_tx_limit, cur_rx_limit); /* Do a dummy read at offset 0; this will ensure all * pendings writes(HP/TP) are flushed before read returns. */ val = HAL_REG_READ((struct hal_soc *)soc->hal_soc, 0); dp_debug("Register value at offset 0: %u\n", val); } #endif Loading
dp/wifi3.0/dp_peer.c +138 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,12 @@ #include "dp_hist.h" #endif #ifdef REO_QDESC_HISTORY #define REO_QDESC_HISTORY_SIZE 512 uint64_t reo_qdesc_history_idx; struct reo_qdesc_event reo_qdesc_history[REO_QDESC_HISTORY_SIZE]; #endif #ifdef FEATURE_WDS static inline bool dp_peer_ast_free_in_unmap_supported(struct dp_soc *soc, Loading Loading @@ -69,6 +75,42 @@ dp_peer_ast_free_in_unmap_supported(struct dp_soc *soc, } #endif #ifdef REO_QDESC_HISTORY static inline void dp_rx_reo_qdesc_history_add(struct reo_desc_list_node *free_desc, enum reo_qdesc_event_type type) { struct reo_qdesc_event *evt; struct dp_rx_tid *rx_tid = &free_desc->rx_tid; uint32_t idx; reo_qdesc_history_idx++; idx = (reo_qdesc_history_idx & (REO_QDESC_HISTORY_SIZE - 1)); evt = &reo_qdesc_history[idx]; qdf_mem_copy(evt->peer_mac, free_desc->peer_mac, QDF_MAC_ADDR_SIZE); evt->qdesc_addr = rx_tid->hw_qdesc_paddr; evt->ts = qdf_get_log_timestamp(); evt->type = type; } #define DP_RX_REO_QDESC_GET_MAC(freedesc, peer) \ qdf_mem_copy(freedesc->peer_mac, peer->mac_addr.raw, QDF_MAC_ADDR_SIZE) #define DP_RX_REO_QDESC_UPDATE_EVT(free_desc) \ dp_rx_reo_qdesc_history_add((free_desc), REO_QDESC_UPDATE_CB) #define DP_RX_REO_QDESC_FREE_EVT(free_desc) \ dp_rx_reo_qdesc_history_add((free_desc), REO_QDESC_FREE) #else #define DP_RX_REO_QDESC_GET_MAC(freedesc, peer) #define DP_RX_REO_QDESC_UPDATE_EVT(free_desc) #define DP_RX_REO_QDESC_FREE_EVT(free_desc) #endif static inline void dp_set_ssn_valid_flag(struct hal_reo_cmd_params *params, uint8_t valid) Loading Loading @@ -2307,6 +2349,9 @@ static void dp_reo_desc_free(struct dp_soc *soc, void *cb_ctxt, "%s:%lu hw_qdesc_paddr: %pK, tid:%d", __func__, curr_ts, (void *)(rx_tid->hw_qdesc_paddr), rx_tid->tid); DP_RX_REO_QDESC_FREE_EVT(freedesc); qdf_mem_unmap_nbytes_single(soc->osdev, rx_tid->hw_qdesc_paddr, QDF_DMA_BIDIRECTIONAL, Loading Loading @@ -2433,6 +2478,7 @@ QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid, } else { hw_qdesc_vaddr = rx_tid->hw_qdesc_vaddr_unaligned; } rx_tid->hw_qdesc_vaddr_aligned = hw_qdesc_vaddr; /* TODO: Ensure that sec_type is set before ADDBA is received. * Currently this is set based on htt indication Loading Loading @@ -2650,6 +2696,8 @@ void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, struct hal_reo_cmd_params params; bool flush_failure = false; DP_RX_REO_QDESC_UPDATE_EVT(freedesc); if (reo_status->rx_queue_status.header.status == HAL_REO_CMD_DRAIN) { qdf_mem_zero(reo_status, sizeof(*reo_status)); reo_status->fl_cache_status.header.status = HAL_REO_CMD_DRAIN; Loading Loading @@ -2803,6 +2851,8 @@ static int dp_rx_tid_delete_wifi3(struct dp_peer *peer, int tid) qdf_mem_zero(¶ms, sizeof(params)); DP_RX_REO_QDESC_GET_MAC(freedesc, peer); params.std.need_status = 1; params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff; params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32; Loading Loading @@ -4365,3 +4415,91 @@ struct dp_peer *dp_sta_vdev_self_peer_ref_n_get(struct dp_soc *soc, qdf_spin_unlock_bh(&vdev->peer_list_lock); return peer; } #ifdef DUMP_REO_QUEUE_INFO_IN_DDR void dp_dump_rx_reo_queue_info( struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status) { struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt; if (!rx_tid) return; if (reo_status->fl_cache_status.header.status != HAL_REO_CMD_SUCCESS) { dp_err_rl("Rx tid REO HW desc flush failed(%d)", reo_status->rx_queue_status.header.status); return; } qdf_spin_lock_bh(&rx_tid->tid_lock); hal_dump_rx_reo_queue_desc(rx_tid->hw_qdesc_vaddr_aligned); qdf_spin_unlock_bh(&rx_tid->tid_lock); } void dp_send_cache_flush_for_rx_tid( struct dp_soc *soc, struct dp_peer *peer) { int i; struct dp_rx_tid *rx_tid; struct hal_reo_cmd_params params; if (!peer) { dp_err_rl("Peer is NULL"); return; } for (i = 0; i < DP_MAX_TIDS; i++) { rx_tid = &peer->rx_tid[i]; if (!rx_tid) continue; qdf_spin_lock_bh(&rx_tid->tid_lock); if (rx_tid->hw_qdesc_vaddr_aligned) { qdf_mem_zero(¶ms, sizeof(params)); params.std.need_status = 1; params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff; params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32; params.u.fl_cache_params.flush_no_inval = 0; if (QDF_STATUS_SUCCESS != dp_reo_send_cmd( soc, CMD_FLUSH_CACHE, ¶ms, dp_dump_rx_reo_queue_info, (void *)rx_tid)) { dp_err_rl("cache flush send failed tid %d", rx_tid->tid); qdf_spin_unlock_bh(&rx_tid->tid_lock); break; } } qdf_spin_unlock_bh(&rx_tid->tid_lock); } } void dp_get_rx_reo_queue_info( struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { struct dp_soc *soc = (struct dp_soc *)soc_hdl; struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_GENERIC_STATS); struct dp_peer *peer = NULL; if (!vdev) { dp_err_rl("vdev is null for vdev_id: %u", vdev_id); goto failed; } peer = dp_vdev_bss_peer_ref_n_get(soc, vdev, DP_MOD_ID_GENERIC_STATS); if (!peer) { dp_err_rl("Peer is NULL"); goto failed; } dp_send_cache_flush_for_rx_tid(soc, peer); failed: if (peer) dp_peer_unref_delete(peer, DP_MOD_ID_GENERIC_STATS); if (vdev) dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_GENERIC_STATS); } #endif /* DUMP_REO_QUEUE_INFO_IN_DDR */
dp/wifi3.0/dp_peer.h +107 −0 Original line number Diff line number Diff line Loading @@ -22,10 +22,28 @@ #include <qdf_lock.h> #include "dp_types.h" #ifdef DUMP_REO_QUEUE_INFO_IN_DDR #include "hal_reo.h" #endif #define DP_INVALID_PEER_ID 0xffff #define DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC 5000 #ifdef REO_QDESC_HISTORY enum reo_qdesc_event_type { REO_QDESC_UPDATE_CB = 0, REO_QDESC_FREE, }; struct reo_qdesc_event { qdf_dma_addr_t qdesc_addr; uint64_t ts; enum reo_qdesc_event_type type; uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; }; #endif typedef void dp_peer_iter_func(struct dp_soc *soc, struct dp_peer *peer, void *arg); void dp_peer_unref_delete(struct dp_peer *peer, enum dp_mod_id id); Loading Loading @@ -843,4 +861,93 @@ static inline void dp_peer_delete_ast_entries(struct dp_soc *soc, { } #endif #ifdef FEATURE_MEC /** * dp_peer_mec_spinlock_create() - Create the MEC spinlock * @soc: SoC handle * * Return: none */ void dp_peer_mec_spinlock_create(struct dp_soc *soc); /** * dp_peer_mec_spinlock_destroy() - Destroy the MEC spinlock * @soc: SoC handle * * Return: none */ void dp_peer_mec_spinlock_destroy(struct dp_soc *soc); /** * dp_peer_mec_flush_entries() - Delete all mec entries in table * @soc: Datapath SOC * * Return: None */ void dp_peer_mec_flush_entries(struct dp_soc *soc); #else static inline void dp_peer_mec_spinlock_create(struct dp_soc *soc) { } static inline void dp_peer_mec_spinlock_destroy(struct dp_soc *soc) { } static inline void dp_peer_mec_flush_entries(struct dp_soc *soc) { } #endif #ifdef DUMP_REO_QUEUE_INFO_IN_DDR /** * dp_send_cache_flush_for_rx_tid() - Send cache flush cmd to REO per tid * @soc : dp_soc handle * @peer: peer * * This function is used to send cache flush cmd to reo and * to register the callback to handle the dumping of the reo * queue stas from DDR * * Return: none */ void dp_send_cache_flush_for_rx_tid( struct dp_soc *soc, struct dp_peer *peer); /** * dp_get_rx_reo_queue_info() - Handler to get rx tid info * @soc : cdp_soc_t handle * @vdev_id: vdev id * * Handler to get rx tid info from DDR after h/w cache is * invalidated first using the cache flush cmd. * * Return: none */ void dp_get_rx_reo_queue_info( struct cdp_soc_t *soc_hdl, uint8_t vdev_id); /** * dp_dump_rx_reo_queue_info() - Callback function to dump reo queue stats * @soc : dp_soc handle * @cb_ctxt - callback context * @reo_status: vdev id * * This is the callback function registered after sending the reo cmd * to flush the h/w cache and invalidate it. In the callback the reo * queue desc info is dumped from DDR. * * Return: none */ void dp_dump_rx_reo_queue_info( struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status); #else /* DUMP_REO_QUEUE_INFO_IN_DDR */ static inline void dp_get_rx_reo_queue_info( struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { } #endif /* DUMP_REO_QUEUE_INFO_IN_DDR */ #endif /* _DP_PEER_H_ */