From patchwork Thu Feb 15 09:04:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Govind Singh X-Patchwork-Id: 10220719 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E647D60467 for ; Thu, 15 Feb 2018 09:04:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D88FD2909F for ; Thu, 15 Feb 2018 09:04:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CAAF2290C8; Thu, 15 Feb 2018 09:04:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3BBFB2909F for ; Thu, 15 Feb 2018 09:04:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755123AbeBOJET (ORCPT ); Thu, 15 Feb 2018 04:04:19 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:37374 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755101AbeBOJEO (ORCPT ); Thu, 15 Feb 2018 04:04:14 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 76A6E609FD; Thu, 15 Feb 2018 09:04:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1518685454; bh=Eb8O4WIp2YxmVBHLcGcMMSyjJasM/ITJH2VwW1/LHOg=; h=From:To:Cc:Subject:Date:From; b=hWLdENo7hM/SI+46yD5ULuty3kbHn4PFx5D2I/OU2vQzmsKuFbGfnEHxIn5wUK1xB rrofR3/qMSqk7iK6AcP7L206zDzO3oUk/ZY7025PzvX6pG9il7gcQH4YxUEdR6dK8r hjd+wulHRwVHlC60I8H6pZ21YWlZXjHrs8F51t6A= Received: from govinds-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.1 with cipher ECDHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) (Authenticated sender: govinds@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 53D7260385; Thu, 15 Feb 2018 09:04:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1518685453; bh=Eb8O4WIp2YxmVBHLcGcMMSyjJasM/ITJH2VwW1/LHOg=; h=From:To:Cc:Subject:Date:From; b=CGUl562u51+FQENRxSZ3L9aFJjiTKjiCsgGTTRdVe/o0mVMhkoeBH/HtF0z3jUSKo Zhca+NIaaMd4ZhAFqaoQP2nbRmHMaVR4T1unoz8+iXPQ02uAnD/mw7hW0oywLqBaV2 /2Wa7jlGCVvtPWjjcIzGiyV4SkYJ01dOPDMbRZAE= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 53D7260385 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=govinds@codeaurora.org From: Govind Singh To: ath10k@lists.infradead.org Cc: linux-wireless@vger.kernel.org, Govind Singh Subject: [PATCH] ath10k: Enable IOMMU support for WCN3990 target Date: Thu, 15 Feb 2018 14:34:08 +0530 Message-Id: <1518685448-15317-1-git-send-email-govinds@codeaurora.org> X-Mailer: git-send-email 1.9.1 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When an IOMMU device is available on the platform bus, allocate an IOMMU domain and attach the wlan target to it. WCN3990 target can then attach an DMA I/O virtual address space to scan out of bound transactions. Signed-off-by: Govind Singh --- drivers/net/wireless/ath/ath10k/snoc.c | 100 ++++++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath10k/snoc.h | 3 + 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index cd21b25..502263d 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -26,6 +26,10 @@ #include #include #include +#include +#include +#include + #define WCN3990_CE_ATTR_FLAGS 0 #define ATH10K_SNOC_RX_POST_RETRY_MS 50 #define CE_POLL_PIPE 4 @@ -1292,6 +1296,88 @@ static int ath10k_hw_power_off(struct ath10k *ar) return ret; } +static int ath10k_smmu_attach(struct ath10k *ar) +{ + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + struct dma_iommu_mapping *mapping; + struct platform_device *pdev; + int ret = 0; + + ath10k_dbg(ar, ATH10K_DBG_SNOC, "Initializing SMMU\n"); + + pdev = ar_snoc->dev; + mapping = arm_iommu_create_mapping(&platform_bus_type, + ar_snoc->smmu_iova_start, + ar_snoc->smmu_iova_len); + if (IS_ERR(mapping)) { + ath10k_err(ar, "create mapping failed, err = %d\n", ret); + ret = PTR_ERR(mapping); + goto map_fail; + } + + ret = arm_iommu_attach_device(&pdev->dev, mapping); + if (ret < 0 && ret != -EEXIST) { + ath10k_err(ar, "iommu attach device failed, err = %d\n", ret); + goto attach_fail; + } else if (ret == -EEXIST) { + ret = 0; + } + + ar_snoc->smmu_mapping = mapping; + + return ret; + +attach_fail: + arm_iommu_release_mapping(mapping); +map_fail: + return ret; +} + +static void ath10k_smmu_deinit(struct ath10k *ar) +{ + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + struct platform_device *pdev; + + pdev = ar_snoc->dev; + + if (!ar_snoc->smmu_mapping) + return; + + arm_iommu_detach_device(&pdev->dev); + arm_iommu_release_mapping(ar_snoc->smmu_mapping); + + ar_snoc->smmu_mapping = NULL; +} + +static int ath10k_smmu_init(struct ath10k *ar) +{ + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + struct platform_device *pdev; + struct resource *res; + int ret = 0; + + pdev = ar_snoc->dev; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "smmu_iova_base"); + if (!res) { + ath10k_err(ar, "SMMU iova base not found\n"); + } else { + ar_snoc->smmu_iova_start = res->start; + ar_snoc->smmu_iova_len = resource_size(res); + ath10k_dbg(ar, ATH10K_DBG_SNOC, "SMMU iova start: %pa, len: %zu\n", + &ar_snoc->smmu_iova_start, ar_snoc->smmu_iova_len); + + ret = ath10k_smmu_attach(ar); + if (ret < 0) { + ath10k_err(ar, "SMMU init failed, err = %d, start: %pad, len: %zx\n", + ret, &ar_snoc->smmu_iova_start, + ar_snoc->smmu_iova_len); + } + } + + return ret; +} + static const struct of_device_id ath10k_snoc_dt_match[] = { { .compatible = "qcom,wcn3990-wifi", .data = &drv_priv, @@ -1339,16 +1425,22 @@ static int ath10k_snoc_probe(struct platform_device *pdev) ar_snoc->ce.bus_ops = &ath10k_snoc_bus_ops; ar->ce_priv = &ar_snoc->ce; + ret = ath10k_smmu_init(ar); + if (ret) { + ath10k_warn(ar, "failed to int SMMU: %d\n", ret); + goto err_core_destroy; + } + ath10k_snoc_resource_init(ar); if (ret) { ath10k_warn(ar, "failed to initialize resource: %d\n", ret); - goto err_core_destroy; + goto err_smmu_deinit; } ath10k_snoc_setup_resource(ar); if (ret) { ath10k_warn(ar, "failed to setup resource: %d\n", ret); - goto err_core_destroy; + goto err_smmu_deinit; } ret = ath10k_snoc_request_irq(ar); if (ret) { @@ -1396,6 +1488,9 @@ static int ath10k_snoc_probe(struct platform_device *pdev) err_release_resource: ath10k_snoc_release_resource(ar); +err_smmu_deinit: + ath10k_smmu_deinit(ar); + err_core_destroy: ath10k_core_destroy(ar); @@ -1409,6 +1504,7 @@ static int ath10k_snoc_remove(struct platform_device *pdev) ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc remove\n"); ath10k_core_unregister(ar); ath10k_hw_power_off(ar); + ath10k_smmu_deinit(ar); ath10k_snoc_free_irq(ar); ath10k_snoc_release_resource(ar); ath10k_core_destroy(ar); diff --git a/drivers/net/wireless/ath/ath10k/snoc.h b/drivers/net/wireless/ath/ath10k/snoc.h index 05dc98f..a9bca2e 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.h +++ b/drivers/net/wireless/ath/ath10k/snoc.h @@ -82,6 +82,9 @@ struct ath10k_snoc { struct timer_list rx_post_retry; struct ath10k_wcn3990_vreg_info *vreg; struct ath10k_wcn3990_clk_info *clk; + struct dma_iommu_mapping *smmu_mapping; + dma_addr_t smmu_iova_start; + size_t smmu_iova_len; }; static inline struct ath10k_snoc *ath10k_snoc_priv(struct ath10k *ar)