diff --git a/hif/inc/hif.h b/hif/inc/hif.h index dbaceda58f..4f6a5ef0f1 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -583,6 +583,8 @@ struct htc_callbacks { * @is_load_unload_in_progress: Query if driver state Load/Unload in Progress * @is_driver_unloading: Query if driver is unloading. * @get_bandwidth_level: Query current bandwidth level for the driver + * @prealloc_get_consistent_mem_unligned: get prealloc unaligned consistent mem + * @prealloc_put_consistent_mem_unligned: put unaligned consistent mem to pool * This Structure provides callback pointer for HIF to query hdd for driver * states. */ @@ -594,6 +596,10 @@ struct hif_driver_state_callbacks { bool (*is_driver_unloading)(void *context); bool (*is_target_ready)(void *context); int (*get_bandwidth_level)(void *context); + void *(*prealloc_get_consistent_mem_unaligned)(qdf_size_t size, + qdf_dma_addr_t *paddr, + uint32_t ring_type); + void (*prealloc_put_consistent_mem_unaligned)(void *vaddr); }; /* This API detaches the HTC layer from the HIF device */ diff --git a/hif/src/ce/ce_internal.h b/hif/src/ce/ce_internal.h index f659c86d62..94b148746e 100644 --- a/hif/src/ce/ce_internal.h +++ b/hif/src/ce/ce_internal.h @@ -89,6 +89,12 @@ struct CE_ring_state { unsigned int high_water_mark_nentries; void *srng_ctx; void **per_transfer_context; + + /* HAL CE ring type */ + uint32_t hal_ring_type; + /* ring memory prealloc */ + uint8_t is_ring_prealloc; + OS_DMA_MEM_CONTEXT(ce_dmacontext); /* OS Specific DMA context */ }; diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c index ed6d262748..b176b19393 100644 --- a/hif/src/ce/ce_main.c +++ b/hif/src/ce/ce_main.c @@ -58,6 +58,10 @@ #define QCA_WIFI_SUPPORT_SRNG #endif +#ifdef QCA_WIFI_SUPPORT_SRNG +#include +#endif + /* Forward references */ QDF_STATUS hif_post_recv_buffers_for_pipe(struct HIF_CE_pipe_info *pipe_info); @@ -1018,11 +1022,14 @@ static QDF_STATUS ce_alloc_desc_ring(struct hif_softc *scn, unsigned int CE_id, scn->ipa_ce_ring->vaddr; } else { ce_ring->base_addr_owner_space_unaligned = - qdf_mem_alloc_consistent(scn->qdf_dev, - scn->qdf_dev->dev, - (nentries * desc_size + - CE_DESC_RING_ALIGN), - base_addr); + hif_mem_alloc_consistent_unaligned + (scn, + (nentries * desc_size + + CE_DESC_RING_ALIGN), + base_addr, + ce_ring->hal_ring_type, + &ce_ring->is_ring_prealloc); + if (!ce_ring->base_addr_owner_space_unaligned) { HIF_ERROR("%s: Failed to allocate DMA memory for ce ring id : %u", __func__, CE_id); @@ -1053,10 +1060,12 @@ static void ce_free_desc_ring(struct hif_softc *scn, unsigned int CE_id, } ce_ring->base_addr_owner_space_unaligned = NULL; } else { - qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, - ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN, - ce_ring->base_addr_owner_space_unaligned, - ce_ring->base_addr_CE_space, 0); + hif_mem_free_consistent_unaligned + (scn, + ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN, + ce_ring->base_addr_owner_space_unaligned, + ce_ring->base_addr_CE_space, 0, + ce_ring->is_ring_prealloc); ce_ring->base_addr_owner_space_unaligned = NULL; } } @@ -1067,9 +1076,14 @@ static QDF_STATUS ce_alloc_desc_ring(struct hif_softc *scn, unsigned int CE_id, unsigned int nentries, uint32_t desc_size) { ce_ring->base_addr_owner_space_unaligned = - qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev, + hif_mem_alloc_consistent_unaligned + (scn, (nentries * desc_size + - CE_DESC_RING_ALIGN), base_addr); + CE_DESC_RING_ALIGN), + base_addr, + ce_ring->hal_ring_type, + &ce_ring->is_ring_prealloc); + if (!ce_ring->base_addr_owner_space_unaligned) { HIF_ERROR("%s: Failed to allocate DMA memory for ce ring id : %u", __func__, CE_id); @@ -1081,10 +1095,12 @@ static QDF_STATUS ce_alloc_desc_ring(struct hif_softc *scn, unsigned int CE_id, static void ce_free_desc_ring(struct hif_softc *scn, unsigned int CE_id, struct CE_ring_state *ce_ring, uint32_t desc_size) { - qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, - ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN, - ce_ring->base_addr_owner_space_unaligned, - ce_ring->base_addr_CE_space, 0); + hif_mem_free_consistent_unaligned + (scn, + ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN, + ce_ring->base_addr_owner_space_unaligned, + ce_ring->base_addr_CE_space, 0, + ce_ring->is_ring_prealloc); ce_ring->base_addr_owner_space_unaligned = NULL; } #endif /* IPA_OFFLOAD */ @@ -1184,7 +1200,26 @@ static inline uint32_t ce_get_desc_size(struct hif_softc *scn, return hif_state->ce_services->ce_get_desc_size(ring_type); } - +#ifdef QCA_WIFI_SUPPORT_SRNG +static inline int32_t ce_ring_type_to_hal_ring_type(uint32_t ce_ring_type) +{ + switch (ce_ring_type) { + case CE_RING_SRC: + return CE_SRC; + case CE_RING_DEST: + return CE_DST; + case CE_RING_STATUS: + return CE_DST_STATUS; + default: + return -EINVAL; + } +} +#else +static int32_t ce_ring_type_to_hal_ring_type(uint32_t ce_ring_type) +{ + return 0; +} +#endif static struct CE_ring_state *ce_alloc_ring_state(struct CE_state *CE_state, uint8_t ring_type, uint32_t nentries) { @@ -1209,6 +1244,7 @@ static struct CE_ring_state *ce_alloc_ring_state(struct CE_state *CE_state, ce_ring->low_water_mark_nentries = 0; ce_ring->high_water_mark_nentries = nentries; ce_ring->per_transfer_context = (void **)ptr; + ce_ring->hal_ring_type = ce_ring_type_to_hal_ring_type(ring_type); desc_size = ce_get_desc_size(scn, ring_type); diff --git a/hif/src/hif_main.c b/hif/src/hif_main.c index d185ad045d..1c6944f735 100644 --- a/hif/src/hif_main.c +++ b/hif/src/hif_main.c @@ -1525,6 +1525,64 @@ int hif_get_bandwidth_level(struct hif_opaque_softc *hif_handle) qdf_export_symbol(hif_get_bandwidth_level); +#ifdef DP_MEM_PRE_ALLOC +void *hif_mem_alloc_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + qdf_dma_addr_t *paddr, + uint32_t ring_type, + uint8_t *is_mem_prealloc) +{ + void *vaddr = NULL; + struct hif_driver_state_callbacks *cbk = + hif_get_callbacks_handle(scn); + + *is_mem_prealloc = false; + if (cbk && cbk->prealloc_get_consistent_mem_unaligned) { + vaddr = cbk->prealloc_get_consistent_mem_unaligned(size, + paddr, + ring_type); + if (vaddr) { + *is_mem_prealloc = true; + goto end; + } + } + + vaddr = qdf_mem_alloc_consistent(scn->qdf_dev, + scn->qdf_dev->dev, + size, + paddr); +end: + dp_info("%s va_unaligned %pK pa_unaligned %pK size %d ring_type %d", + *is_mem_prealloc ? "pre-alloc" : "dynamic-alloc", vaddr, + (void *)*paddr, (int)size, ring_type); + + return vaddr; +} + +void hif_mem_free_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + void *vaddr, + qdf_dma_addr_t paddr, + qdf_dma_context_t memctx, + uint8_t is_mem_prealloc) +{ + struct hif_driver_state_callbacks *cbk = + hif_get_callbacks_handle(scn); + + if (is_mem_prealloc) { + if (cbk && cbk->prealloc_put_consistent_mem_unaligned) { + cbk->prealloc_put_consistent_mem_unaligned(vaddr); + } else { + dp_warn("dp_prealloc_put_consistent_unligned NULL"); + QDF_BUG(0); + } + } else { + qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, + size, vaddr, paddr, memctx); + } +} +#endif + /** * hif_batch_send() - API to access hif specific function * ce_batch_send. diff --git a/hif/src/hif_main.h b/hif/src/hif_main.h index e062a3fb8a..94512a4dbb 100644 --- a/hif/src/hif_main.h +++ b/hif/src/hif_main.h @@ -381,6 +381,47 @@ void hif_wlan_disable(struct hif_softc *scn); int hif_target_sleep_state_adjust(struct hif_softc *scn, bool sleep_ok, bool wait_for_it); + +#ifdef DP_MEM_PRE_ALLOC +void *hif_mem_alloc_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + qdf_dma_addr_t *paddr, + uint32_t ring_type, + uint8_t *is_mem_prealloc); + +void hif_mem_free_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + void *vaddr, + qdf_dma_addr_t paddr, + qdf_dma_context_t memctx, + uint8_t is_mem_prealloc); +#else +static inline +void *hif_mem_alloc_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + qdf_dma_addr_t *paddr, + uint32_t ring_type, + uint8_t *is_mem_prealloc) +{ + return qdf_mem_alloc_consistent(scn->qdf_dev, + scn->qdf_dev->dev, + size, + paddr); +} + +static inline +void hif_mem_free_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + void *vaddr, + qdf_dma_addr_t paddr, + qdf_dma_context_t memctx, + uint8_t is_mem_prealloc) +{ + return qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, + size, vaddr, paddr, memctx); +} +#endif + /** * hif_get_rx_ctx_id() - Returns NAPI instance ID based on CE ID * @ctx_id: Rx CE context ID