2018-02-15 09:04:14

by Govind Singh

[permalink] [raw]
Subject: [PATCH] ath10k: Enable IOMMU support for WCN3990 target

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 <[email protected]>
---
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 <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
+#include <asm/dma-iommu.h>
+#include <linux/iommu.h>
+#include <linux/dma-mapping.h>
+
#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)
--
1.9.1


2018-03-01 10:01:11

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH] ath10k: Enable IOMMU support for WCN3990 target

Govind Singh <[email protected]> writes:

> 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 <[email protected]>
> ---
> 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 <linux/platform_device.h>
> #include <linux/regulator/consumer.h>
> #include <linux/clk.h>
> +#include <asm/dma-iommu.h>
> +#include <linux/iommu.h>
> +#include <linux/dma-mapping.h>

Kbuild bot reported a problem with arm64 but strangely I cannot find the
full report. Anyway, this was the warning:

drivers/net/wireless/ath/ath10k/snoc.c:29:10: fatal error:
asm/dma-iommu.h: No such file or directory

Any ideas? Adding also Arnd, the grand master of compilation problems :)

Full patch here:

https://patchwork.kernel.org/patch/10220719/

--
Kalle Valo

2018-03-01 13:18:52

by Govind Singh

[permalink] [raw]
Subject: RE: [PATCH] ath10k: Enable IOMMU support for WCN3990 target

>> The asm/dma-iommu.h header file exsists only on arm32, no other architec=
ture.
>> I'm not sure about the purpose of the patch to start with:
>> it's normally up to the platform code to allocate IOMMU domains, device =
drivers should only need to manually interact with the IOMMU layer if they =
need more than one domain, but this ath10k patch appears to be using the de=
fault domain and should have no effect as long as the platform code works c=
orrectly.
Thanks Arnd, I have fixed this and migrated to 64bit API's(iommu_attach_de=
vice/iommu_detach_device/ iommu_get_domain_for_dev), will share the next re=
vision.
I tried using the default domain by adding the stream ID and mask in dt and=
no manual interaction, but it is resulting in TZ error and unhandled conte=
xt fault.
Seems I need to provide explicit mapping range(aperture_start/ aperture_end=
) as this is only working combination for me..

BR,
Govind

-----Original Message-----
From: ath10k [mailto:[email protected]] On Behalf Of Arnd =
Bergmann
Sent: Thursday, March 1, 2018 3:40 PM
To: Kalle Valo <[email protected]>
Cc: Govind Singh <[email protected]>; linux-wireless <linux-wireless@v=
ger.kernel.org>; [email protected]
Subject: Re: [PATCH] ath10k: Enable IOMMU support for WCN3990 target

On Thu, Mar 1, 2018 at 11:01 AM, Kalle Valo <[email protected]> wrote:
> Govind Singh <[email protected]> writes:
>
>> When an IOMMU device is available on the platform bus, allocate an=20
>> IOMMU domain and attach the wlan target to it.
>> WCN3990 target can then attach an DMA I/O virtual address space to=20
>> scan out of bound transactions.
>>
>> Signed-off-by: Govind Singh <[email protected]>
>> ---
>> 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=20
>> 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 <linux/platform_device.h>
>> #include <linux/regulator/consumer.h> #include <linux/clk.h>
>> +#include <asm/dma-iommu.h>
>> +#include <linux/iommu.h>
>> +#include <linux/dma-mapping.h>
>
> Kbuild bot reported a problem with arm64 but strangely I cannot find=20
> the full report. Anyway, this was the warning:
>
> drivers/net/wireless/ath/ath10k/snoc.c:29:10: fatal error:
> asm/dma-iommu.h: No such file or directory
>
> Any ideas? Adding also Arnd, the grand master of compilation problems=20
> :)
>
> Full patch here:
>
> https://patchwork.kernel.org/patch/10220719/
>

The asm/dma-iommu.h header file exsists only on arm32, no other architectur=
e.

I'm not sure about the purpose of the patch to start with:
it's normally up to the platform code to allocate IOMMU domains, device dri=
vers should only need to manually interact with the IOMMU layer if they nee=
d more than one domain, but this ath10k patch appears to be using the defau=
lt domain and should have no effect as long as the platform code works corr=
ectly.

Arnd

_______________________________________________
ath10k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath10k

2018-03-01 13:27:36

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH] ath10k: Enable IOMMU support for WCN3990 target

On Thu, Mar 1, 2018 at 2:18 PM, Govind Singh <[email protected]> wro=
te:
>>> The asm/dma-iommu.h header file exsists only on arm32, no other archite=
cture.
>>> I'm not sure about the purpose of the patch to start with:
>>> it's normally up to the platform code to allocate IOMMU domains, device=
drivers should only need to manually interact with the IOMMU layer if they=
need more than one domain, but this ath10k patch appears to be using the d=
efault domain and should have no effect as long as the platform code works =
correctly.
> Thanks Arnd, I have fixed this and migrated to 64bit API's(iommu_attach_=
device/iommu_detach_device/ iommu_get_domain_for_dev), will share the next =
revision.
> I tried using the default domain by adding the stream ID and mask in dt a=
nd no manual interaction, but it is resulting in TZ error and unhandled con=
text fault.
> Seems I need to provide explicit mapping range(aperture_start/ aperture_e=
nd) as this is only working combination for me..

I don't see why you need to do that at all, can you clarify?

The IOMMU should be set up implicitly for you here based on the iommus
property in DT,
with no driver changes at all. This should work on all architectures/

Arnd

2018-03-08 13:51:00

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH] ath10k: Enable IOMMU support for WCN3990 target

Arnd Bergmann <[email protected]> writes:

> On Thu, Mar 1, 2018 at 2:18 PM, Govind Singh <[email protected]> wrote:
>>>> The asm/dma-iommu.h header file exsists only on arm32, no other architecture.
>>>> I'm not sure about the purpose of the patch to start with:
>>>> it's normally up to the platform code to allocate IOMMU domains,
>>>> device drivers should only need to manually interact with the
>>>> IOMMU layer if they need more than one domain, but this ath10k
>>>> patch appears to be using the default domain and should have no
>>>> effect as long as the platform code works correctly.
>> Thanks Arnd, I have fixed this and migrated to 64bit
>> API's(iommu_attach_device/iommu_detach_device/
>> iommu_get_domain_for_dev), will share the next revision.
>> I tried using the default domain by adding the stream ID and mask in
>> dt and no manual interaction, but it is resulting in TZ error and
>> unhandled context fault.
>> Seems I need to provide explicit mapping range(aperture_start/
>> aperture_end) as this is only working combination for me..
>
> I don't see why you need to do that at all, can you clarify?
>
> The IOMMU should be set up implicitly for you here based on the iommus
> property in DT, with no driver changes at all. This should work on all
> architectures/

Maybe Govind is using some out-of-tree tree which is buggy in this
regard?

--
Kalle Valo

2018-03-08 13:59:33

by Govind Singh

[permalink] [raw]
Subject: Re: [PATCH] ath10k: Enable IOMMU support for WCN3990 target

On 2018-03-08 19:20, Kalle Valo wrote:
> Arnd Bergmann <[email protected]> writes:
>
>> On Thu, Mar 1, 2018 at 2:18 PM, Govind Singh
>> <[email protected]> wrote:
>>>>> The asm/dma-iommu.h header file exsists only on arm32, no other
>>>>> architecture.
>>>>> I'm not sure about the purpose of the patch to start with:
>>>>> it's normally up to the platform code to allocate IOMMU domains,
>>>>> device drivers should only need to manually interact with the
>>>>> IOMMU layer if they need more than one domain, but this ath10k
>>>>> patch appears to be using the default domain and should have no
>>>>> effect as long as the platform code works correctly.
>>> Thanks Arnd, I have fixed this and migrated to 64bit
>>> API's(iommu_attach_device/iommu_detach_device/
>>> iommu_get_domain_for_dev), will share the next revision.
>>> I tried using the default domain by adding the stream ID and mask in
>>> dt and no manual interaction, but it is resulting in TZ error and
>>> unhandled context fault.
>>> Seems I need to provide explicit mapping range(aperture_start/
>>> aperture_end) as this is only working combination for me..
>>
>> I don't see why you need to do that at all, can you clarify?
>>
>> The IOMMU should be set up implicitly for you here based on the iommus
>> property in DT, with no driver changes at all. This should work on all
>> architectures/
>
> Maybe Govind is using some out-of-tree tree which is buggy in this
> regard?

Actually there is limitations in using the iova address range for wlan
IP.
It can allow certain iova range and i was attaching the iommu to specify
the iova range.
I am exploring if i can use "dma-ranges" in dt to avoid the manual
interaction apart from
stream ID and mask.

BR,
Govind

2018-03-01 10:10:19

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH] ath10k: Enable IOMMU support for WCN3990 target

On Thu, Mar 1, 2018 at 11:01 AM, Kalle Valo <[email protected]> wrote:
> Govind Singh <[email protected]> writes:
>
>> 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 <[email protected]>
>> ---
>> 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 <linux/platform_device.h>
>> #include <linux/regulator/consumer.h>
>> #include <linux/clk.h>
>> +#include <asm/dma-iommu.h>
>> +#include <linux/iommu.h>
>> +#include <linux/dma-mapping.h>
>
> Kbuild bot reported a problem with arm64 but strangely I cannot find the
> full report. Anyway, this was the warning:
>
> drivers/net/wireless/ath/ath10k/snoc.c:29:10: fatal error:
> asm/dma-iommu.h: No such file or directory
>
> Any ideas? Adding also Arnd, the grand master of compilation problems :)
>
> Full patch here:
>
> https://patchwork.kernel.org/patch/10220719/
>

The asm/dma-iommu.h header file exsists only on arm32, no other architecture.

I'm not sure about the purpose of the patch to start with:
it's normally up to the platform code to allocate IOMMU domains,
device drivers should only need to manually interact with the
IOMMU layer if they need more than one domain, but this ath10k
patch appears to be using the default domain and should have
no effect as long as the platform code works correctly.

Arnd