From 34d893df39e2bafd8c8f196d5ea6bb2e6f8f1a9b Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 8 Dec 2022 15:53:42 +0530 Subject: [PATCH] qcacmn: IOMMU map and unmap RX buffers to LPASS SMMU CB IOMMU map and unmap RX buffers into LPASS SMMU context bank for LPASS to access RX buffers in direct link usecases. Change-Id: Ie72a008309e3abdf3fbc7198bb5d3af5e9497180 CRs-Fixed: 3356568 --- dp/wifi3.0/dp_rx.c | 8 ++- dp/wifi3.0/dp_rx.h | 56 ++++++++++++++++++- dp/wifi3.0/dp_rx_buffer_pool.c | 25 ++++++++- dp/wifi3.0/dp_rx_buffer_pool.h | 21 +++++-- dp/wifi3.0/dp_rx_defrag.c | 5 ++ dp/wifi3.0/dp_rx_desc.c | 18 ++++-- dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c | 2 +- dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c | 2 +- 8 files changed, 123 insertions(+), 14 deletions(-) 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); } /*