From 15fb83796aefa5961661a7ac6c34ffafa31282ab Mon Sep 17 00:00:00 2001 From: jiad Date: Fri, 9 Nov 2018 16:16:29 +0800 Subject: [PATCH] qcacld-3.0: Fix WDI 1.0 MCC TX SMMU unmap For WDI 1.0 MCC TX, wlan driver is involved for TX and skb is provided from IPA driver. With SMMU enabled, dma_addr is of IPA domain. In such case, wlan driver needs to do DMA map itself. After doing DMA map, an offset of frag_header and ipa_header is added to the iova and skb->cb is updated with the new iova. After TX completion, skb DMA unmap is done but with the iova of the above offset included, which leads to unmapped iova error. Fix is to recalculate the iova and update skb->cb with new iova, which has frag_header and ipa_header length removed. Change-Id: I7d04e9b01fbd973601ee9e4e74c6bf4dd3d0f7bb CRs-Fixed: 2338049 --- components/ipa/core/src/wlan_ipa_core.c | 24 ++++++++++++++++++++++ core/dp/txrx/ol_tx_desc.c | 3 --- core/dp/txrx/ol_txrx_legacy_flow_control.c | 4 ---- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index 27f1152bde80..c44bc3e41238 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -285,6 +285,14 @@ static void wlan_ipa_send_pkt_to_tl( } else { ipa_ctx->stats.num_tx_desc_error++; qdf_spin_unlock_bh(&ipa_ctx->q_lock); + + if (qdf_mem_smmu_s1_enabled(osdev)) { + if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) + qdf_nbuf_mapped_paddr_set(skb, paddr); + + qdf_nbuf_unmap(osdev, skb, QDF_DMA_TO_DEVICE); + } + qdf_ipa_free_skb(ipa_tx_desc); wlan_ipa_wdi_rm_try_release(ipa_ctx); return; @@ -1203,12 +1211,28 @@ static void wlan_ipa_nbuf_cb(qdf_nbuf_t skb) qdf_ipa_rx_data_t *ipa_tx_desc; struct wlan_ipa_tx_desc *tx_desc; uint16_t id; + struct wlan_objmgr_pdev *pdev = ipa_ctx->pdev; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + qdf_device_t osdev = wlan_psoc_get_qdf_dev(psoc); if (!qdf_nbuf_ipa_owned_get(skb)) { dev_kfree_skb_any(skb); return; } + if (osdev && qdf_mem_smmu_s1_enabled(osdev)) { + if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { + qdf_dma_addr_t paddr = QDF_NBUF_CB_PADDR(skb); + + qdf_nbuf_mapped_paddr_set(skb, + paddr - + WLAN_IPA_WLAN_FRAG_HEADER - + WLAN_IPA_WLAN_IPA_HEADER); + } + + qdf_nbuf_unmap(osdev, skb, QDF_DMA_TO_DEVICE); + } + /* Get Tx desc pointer from SKB CB */ id = QDF_NBUF_CB_TX_IPA_PRIV(skb); tx_desc = &ipa_ctx->tx_desc_pool[id]; diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c index 102073a04ac5..3943abfa5d2c 100644 --- a/core/dp/txrx/ol_tx_desc.c +++ b/core/dp/txrx/ol_tx_desc.c @@ -800,9 +800,6 @@ void ol_tx_desc_frame_list_free(struct ol_txrx_pdev_t *pdev, if (!qdf_nbuf_ipa_owned_get(msdu)) qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_TO_DEVICE); - else if (qdf_mem_smmu_s1_enabled(pdev->osdev)) - qdf_nbuf_unmap(pdev->osdev, msdu, - QDF_DMA_TO_DEVICE); } /* free the tx desc */ diff --git a/core/dp/txrx/ol_txrx_legacy_flow_control.c b/core/dp/txrx/ol_txrx_legacy_flow_control.c index 2b72a5ad4c83..791df5e5c70c 100644 --- a/core/dp/txrx/ol_txrx_legacy_flow_control.c +++ b/core/dp/txrx/ol_txrx_legacy_flow_control.c @@ -134,10 +134,6 @@ void ol_txrx_vdev_flush(struct cdp_vdev *pvdev) qdf_nbuf_unmap(vdev->pdev->osdev, vdev->ll_pause.txq.head, QDF_DMA_TO_DEVICE); - else if (qdf_mem_smmu_s1_enabled(vdev->pdev->osdev)) - qdf_nbuf_unmap(vdev->pdev->osdev, - vdev->ll_pause.txq.head, - QDF_DMA_TO_DEVICE); } qdf_nbuf_tx_free(vdev->ll_pause.txq.head, QDF_NBUF_PKT_ERROR);