diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 3875588aa1..c7036f6ed9 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -3128,6 +3128,12 @@ dp_pdev_rx_buffers_attach(struct dp_soc *dp_soc, uint32_t mac_id, rx_desc_pool->buf_size, true, __func__, __LINE__); + dp_audio_smmu_map(dp_soc->osdev, + qdf_mem_paddr_from_dmaaddr(dp_soc->osdev, + QDF_NBUF_CB_PADDR(nbuf)), + QDF_NBUF_CB_PADDR(nbuf), + rx_desc_pool->buf_size); + desc_list = next; } @@ -3366,7 +3372,7 @@ dp_rx_pdev_buffers_free(struct dp_pdev *pdev) rx_desc_pool = &soc->rx_desc_buf[mac_for_pdev]; - dp_rx_desc_nbuf_free(soc, rx_desc_pool); + dp_rx_desc_nbuf_free(soc, rx_desc_pool, false); dp_rx_buffer_pool_deinit(soc, mac_for_pdev); } diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 73962786b3..036a2c3d12 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -931,7 +931,8 @@ void dp_rx_desc_nbuf_and_pool_free(struct dp_soc *soc, uint32_t pool_id, * Return: None */ void dp_rx_desc_nbuf_free(struct dp_soc *soc, - struct rx_desc_pool *rx_desc_pool); + struct rx_desc_pool *rx_desc_pool, + bool is_mon_pool); #ifdef DP_RX_MON_MEM_FRAG /* @@ -2378,6 +2379,52 @@ bool dp_rx_pkt_tracepoints_enabled(void) qdf_trace_dp_rx_pkt_enabled()); } +#ifdef FEATURE_DIRECT_LINK +/** + * dp_audio_smmu_map()- Map memory region into Audio SMMU CB + * @qdf_dev: pointer to QDF device structure + * @paddr: physical address + * @iova: DMA address + * @size: memory region size + * + * Return: 0 on success else failure code + */ +static inline +int dp_audio_smmu_map(qdf_device_t qdf_dev, qdf_dma_addr_t paddr, + qdf_dma_addr_t iova, qdf_size_t size) +{ + return pld_audio_smmu_map(qdf_dev->dev, paddr, iova, size); +} + +/** + * dp_audio_smmu_unmap()- Remove memory region mapping from Audio SMMU CB + * @qdf_dev: pointer to QDF device structure + * @iova: DMA address + * @size: memory region size + * + * Return: None + */ +static inline +void dp_audio_smmu_unmap(qdf_device_t qdf_dev, qdf_dma_addr_t iova, + qdf_size_t size) +{ + pld_audio_smmu_unmap(qdf_dev->dev, iova, size); +} +#else +static inline +int dp_audio_smmu_map(qdf_device_t qdf_dev, qdf_dma_addr_t paddr, + qdf_dma_addr_t iova, qdf_size_t size) +{ + return 0; +} + +static inline +void dp_audio_smmu_unmap(qdf_device_t qdf_dev, qdf_dma_addr_t iova, + qdf_size_t size) +{ +} +#endif + #if defined(QCA_DP_RX_NBUF_NO_MAP_UNMAP) && !defined(BUILD_X86) static inline QDF_STATUS dp_pdev_rx_buffers_attach_simple(struct dp_soc *soc, uint32_t mac_id, @@ -2596,6 +2643,11 @@ void dp_rx_nbuf_unmap(struct dp_soc *soc, rx_desc_pool = &soc->rx_desc_buf[rx_desc->pool_id]; dp_ipa_reo_ctx_buf_mapping_lock(soc, reo_ring_num); + + dp_audio_smmu_unmap(soc->osdev, + QDF_NBUF_CB_PADDR(rx_desc->nbuf), + rx_desc_pool->buf_size); + dp_ipa_handle_rx_buf_smmu_mapping(soc, rx_desc->nbuf, rx_desc_pool->buf_size, false, __func__, __LINE__); @@ -2612,6 +2664,8 @@ void dp_rx_nbuf_unmap_pool(struct dp_soc *soc, struct rx_desc_pool *rx_desc_pool, qdf_nbuf_t nbuf) { + dp_audio_smmu_unmap(soc->osdev, QDF_NBUF_CB_PADDR(nbuf), + rx_desc_pool->buf_size); dp_ipa_handle_rx_buf_smmu_mapping(soc, nbuf, rx_desc_pool->buf_size, false, __func__, __LINE__); qdf_nbuf_unmap_nbytes_single(soc->osdev, nbuf, QDF_DMA_FROM_DEVICE, diff --git a/dp/wifi3.0/dp_rx_buffer_pool.c b/dp/wifi3.0/dp_rx_buffer_pool.c index c16b880114..569e385a6f 100644 --- a/dp/wifi3.0/dp_rx_buffer_pool.c +++ b/dp/wifi3.0/dp_rx_buffer_pool.c @@ -164,6 +164,12 @@ void dp_rx_refill_buff_pool_enqueue(struct dp_soc *soc) continue; } + dp_audio_smmu_map(dev, + qdf_mem_paddr_from_dmaaddr(dev, + QDF_NBUF_CB_PADDR(nbuf)), + QDF_NBUF_CB_PADDR(nbuf), + rx_desc_pool->buf_size); + buff_pool->buf_elem[head++] = nbuf; head &= (DP_RX_REFILL_BUFF_POOL_SIZE - 1); count++; @@ -257,11 +263,19 @@ dp_rx_buffer_pool_nbuf_map(struct dp_soc *soc, { QDF_STATUS ret = QDF_STATUS_SUCCESS; - if (!QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf)) + if (!QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf)) { ret = qdf_nbuf_map_nbytes_single(soc->osdev, (nbuf_frag_info_t->virt_addr).nbuf, QDF_DMA_FROM_DEVICE, rx_desc_pool->buf_size); + if (QDF_IS_STATUS_SUCCESS(ret)) + dp_audio_smmu_map(soc->osdev, + qdf_mem_paddr_from_dmaaddr(soc->osdev, + QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf)), + QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf), + rx_desc_pool->buf_size); + } + return ret; } @@ -300,6 +314,12 @@ static void dp_rx_refill_buff_pool_init(struct dp_soc *soc, u8 mac_id) continue; } + dp_audio_smmu_map(soc->osdev, + qdf_mem_paddr_from_dmaaddr(soc->osdev, + QDF_NBUF_CB_PADDR(nbuf)), + QDF_NBUF_CB_PADDR(nbuf), + rx_desc_pool->buf_size); + buff_pool->buf_elem[head] = nbuf; head++; } @@ -361,6 +381,9 @@ static void dp_rx_refill_buff_pool_deinit(struct dp_soc *soc, u8 mac_id) return; while ((nbuf = dp_rx_refill_buff_pool_dequeue_nbuf(soc))) { + dp_audio_smmu_unmap(soc->osdev, + QDF_NBUF_CB_PADDR(nbuf), + rx_desc_pool->buf_size); qdf_nbuf_unmap_nbytes_single(soc->osdev, nbuf, QDF_DMA_BIDIRECTIONAL, rx_desc_pool->buf_size); diff --git a/dp/wifi3.0/dp_rx_buffer_pool.h b/dp/wifi3.0/dp_rx_buffer_pool.h index 0c5212f99d..8a1f995437 100644 --- a/dp/wifi3.0/dp_rx_buffer_pool.h +++ b/dp/wifi3.0/dp_rx_buffer_pool.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -212,10 +213,22 @@ dp_rx_buffer_pool_nbuf_map(struct dp_soc *soc, struct rx_desc_pool *rx_desc_pool, struct dp_rx_nbuf_frag_info *nbuf_frag_info_t) { - return qdf_nbuf_map_nbytes_single(soc->osdev, - (nbuf_frag_info_t->virt_addr).nbuf, - QDF_DMA_FROM_DEVICE, - rx_desc_pool->buf_size); + QDF_STATUS status; + + status = qdf_nbuf_map_nbytes_single(soc->osdev, + (nbuf_frag_info_t->virt_addr).nbuf, + QDF_DMA_FROM_DEVICE, + rx_desc_pool->buf_size); + if (QDF_IS_STATUS_ERROR(status)) + return status; + + dp_audio_smmu_map(soc->osdev, + qdf_mem_paddr_from_dmaaddr(soc->osdev, + QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf)), + QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf), + rx_desc_pool->buf_size); + + return status; } static inline void dp_rx_schedule_refill_thread(struct dp_soc *soc) { } diff --git a/dp/wifi3.0/dp_rx_defrag.c b/dp/wifi3.0/dp_rx_defrag.c index 2650e2d5b9..b3257366cc 100644 --- a/dp/wifi3.0/dp_rx_defrag.c +++ b/dp/wifi3.0/dp_rx_defrag.c @@ -1343,6 +1343,11 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_txrx_peer *txrx_peer, dp_ipa_handle_rx_buf_smmu_mapping(soc, head, rx_desc_pool->buf_size, true, __func__, __LINE__); + dp_audio_smmu_map(soc->osdev, + qdf_mem_paddr_from_dmaaddr(soc->osdev, + QDF_NBUF_CB_PADDR(head)), + QDF_NBUF_CB_PADDR(head), rx_desc_pool->buf_size); + /* * As part of rx frag handler buffer was unmapped and rx desc * unmapped is set to 1. So again for defrag reinject frame reset diff --git a/dp/wifi3.0/dp_rx_desc.c b/dp/wifi3.0/dp_rx_desc.c index 96c59e44b4..1951ed937e 100644 --- a/dp/wifi3.0/dp_rx_desc.c +++ b/dp/wifi3.0/dp_rx_desc.c @@ -210,7 +210,8 @@ static QDF_STATUS dp_rx_desc_nbuf_collect(struct dp_soc *soc, static void dp_rx_desc_nbuf_cleanup(struct dp_soc *soc, qdf_nbuf_t nbuf_unmap_list, qdf_nbuf_t nbuf_free_list, - uint16_t buf_size) + uint16_t buf_size, + bool is_mon_pool) { qdf_nbuf_t nbuf = nbuf_unmap_list; qdf_nbuf_t next; @@ -218,6 +219,11 @@ static void dp_rx_desc_nbuf_cleanup(struct dp_soc *soc, while (nbuf) { next = nbuf->next; + if (!is_mon_pool) + dp_audio_smmu_unmap(soc->osdev, + QDF_NBUF_CB_PADDR(nbuf), + buf_size); + if (dp_ipa_handle_rx_buf_smmu_mapping(soc, nbuf, buf_size, false, __func__, __LINE__)) dp_info_rl("Unable to unmap nbuf: %pK", nbuf); @@ -246,12 +252,13 @@ void dp_rx_desc_nbuf_and_pool_free(struct dp_soc *soc, uint32_t pool_id, &nbuf_unmap_list, &nbuf_free_list); qdf_spin_unlock_bh(&rx_desc_pool->lock); dp_rx_desc_nbuf_cleanup(soc, nbuf_unmap_list, nbuf_free_list, - rx_desc_pool->buf_size); + rx_desc_pool->buf_size, false); qdf_spinlock_destroy(&rx_desc_pool->lock); } void dp_rx_desc_nbuf_free(struct dp_soc *soc, - struct rx_desc_pool *rx_desc_pool) + struct rx_desc_pool *rx_desc_pool, + bool is_mon_pool) { qdf_nbuf_t nbuf_unmap_list = NULL; qdf_nbuf_t nbuf_free_list = NULL; @@ -260,7 +267,7 @@ void dp_rx_desc_nbuf_free(struct dp_soc *soc, &nbuf_unmap_list, &nbuf_free_list); qdf_spin_unlock_bh(&rx_desc_pool->lock); dp_rx_desc_nbuf_cleanup(soc, nbuf_unmap_list, nbuf_free_list, - rx_desc_pool->buf_size); + rx_desc_pool->buf_size, is_mon_pool); } qdf_export_symbol(dp_rx_desc_nbuf_free); @@ -425,7 +432,8 @@ void dp_rx_desc_nbuf_and_pool_free(struct dp_soc *soc, uint32_t pool_id, } void dp_rx_desc_nbuf_free(struct dp_soc *soc, - struct rx_desc_pool *rx_desc_pool) + struct rx_desc_pool *rx_desc_pool, + bool is_mon_pool) { qdf_nbuf_t nbuf; int i; diff --git a/dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c b/dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c index e008740467..56a0ff08d5 100644 --- a/dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c +++ b/dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c @@ -915,7 +915,7 @@ void dp_rx_pdev_mon_buf_buffers_free(struct dp_pdev *pdev, uint32_t mac_id) if (rx_desc_pool->rx_mon_dest_frag_enable) dp_rx_desc_frag_free(soc, rx_desc_pool); else - dp_rx_desc_nbuf_free(soc, rx_desc_pool); + dp_rx_desc_nbuf_free(soc, rx_desc_pool, true); } QDF_STATUS diff --git a/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c b/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c index 41490082bf..c41b49389c 100644 --- a/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c +++ b/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c @@ -988,7 +988,7 @@ dp_rx_pdev_mon_status_buffers_free(struct dp_pdev *pdev, uint32_t mac_id) dp_debug("Mon RX Status Desc Pool Free pdev[%d]", pdev_id); - dp_rx_desc_nbuf_free(soc, rx_desc_pool); + dp_rx_desc_nbuf_free(soc, rx_desc_pool, true); } /*