Linux-mediatek Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v8] net: airoha: npu: use cacheline-sized buffers for mailbox DMA
@ 2026-08-17  9:06 Daniel Pawlik
  2026-08-17  9:52 ` Qingfang Deng
  2026-08-17 23:17 ` Jakub Kicinski
  0 siblings, 2 replies; 5+ messages in thread
From: Daniel Pawlik @ 2026-08-17  9:06 UTC (permalink / raw)
  To: netdev; +Cc: lorenzo, win847, linux-arm-kernel, linux-mediatek, Daniel Pawlik

On EN7581 + MT7996 (Gemtek W1700K), mapping small caller buffers with
DMA_BIDIRECTIONAL regresses NPU version probe: the mailbox completes
successfully but WLAN_FUNC_GET_WAIT_NPU_VERSION reads as 0.0 instead of
0.1111.

Allocate at least SMP_CACHE_BYTES for each mailbox payload and map
ALIGN(len, SMP_CACHE_BYTES) with DMA_BIDIRECTIONAL while programming
the original payload length into the mailbox length register.

Tested on Quantum Fiber / Gemtek W1700K (EN7581 + MT7996), kernel
6.18.44, including two cold reboots and sustained WiFi use.

Fixes: 6f884eb87a79 ("net: airoha: Fix DMA direction for NPU mailbox buffer")
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20260814110017.2795022-1-pawlik.dan@gmail.com/
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20260809152813.585797-1-pawlik.dan@gmail.com/
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20260805070851.2885888-1-pawlik.dan@gmail.com/
Assisted-by: Cursor:composer-2
Signed-off-by: Daniel Pawlik <pawlik.dan@gmail.com>
---
 drivers/net/ethernet/airoha/airoha_npu.c | 25 +++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c
index b679bed952de..d560b8763753 100644
--- a/drivers/net/ethernet/airoha/airoha_npu.c
+++ b/drivers/net/ethernet/airoha/airoha_npu.c
@@ -5,6 +5,7 @@
  */

 #include <linux/devcoredump.h>
+#include <linux/dma-mapping.h>
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
 #include <linux/of_net.h>
@@ -160,15 +161,21 @@ struct wlan_mbox_data {
 	DECLARE_FLEX_ARRAY(u8, d);
 };

+static size_t airoha_npu_mbox_size(size_t len)
+{
+	return ALIGN(max(len, SMP_CACHE_BYTES), SMP_CACHE_BYTES);
+}
+
 static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id,
 			       void *p, int size)
 {
 	u16 core = 0; /* FIXME */
 	u32 val, offset = core << 4;
 	dma_addr_t dma_addr;
+	size_t map_len = airoha_npu_mbox_size(size);
 	int ret;

-	dma_addr = dma_map_single(npu->dev, p, size, DMA_BIDIRECTIONAL);
+	dma_addr = dma_map_single(npu->dev, p, map_len, DMA_BIDIRECTIONAL);
 	ret = dma_mapping_error(npu->dev, dma_addr);
 	if (ret)
 		return ret;
@@ -191,7 +198,7 @@ static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id,

 	spin_unlock_bh(&npu->cores[core].lock);

-	dma_unmap_single(npu->dev, dma_addr, size, DMA_BIDIRECTIONAL);
+	dma_unmap_single(npu->dev, dma_addr, map_len, DMA_BIDIRECTIONAL);

 	return ret;
 }
@@ -333,7 +340,7 @@ static int airoha_npu_ppe_init(struct airoha_npu *npu)
 	struct ppe_mbox_data *ppe_data;
 	int err;

-	ppe_data = kzalloc_obj(*ppe_data);
+	ppe_data = kzalloc(airoha_npu_mbox_size(sizeof(*ppe_data)), GFP_KERNEL);
 	if (!ppe_data)
 		return -ENOMEM;

@@ -354,7 +361,7 @@ static int airoha_npu_ppe_deinit(struct airoha_npu *npu)
 	struct ppe_mbox_data *ppe_data;
 	int err;

-	ppe_data = kzalloc_obj(*ppe_data);
+	ppe_data = kzalloc(airoha_npu_mbox_size(sizeof(*ppe_data)), GFP_KERNEL);
 	if (!ppe_data)
 		return -ENOMEM;

@@ -375,7 +382,7 @@ static int airoha_npu_ppe_flush_sram_entries(struct airoha_npu *npu,
 	struct ppe_mbox_data *ppe_data;
 	int err;

-	ppe_data = kzalloc_obj(*ppe_data);
+	ppe_data = kzalloc(airoha_npu_mbox_size(sizeof(*ppe_data)), GFP_KERNEL);
 	if (!ppe_data)
 		return -ENOMEM;

@@ -399,7 +406,7 @@ static int airoha_npu_foe_commit_entry(struct airoha_npu *npu,
 	struct ppe_mbox_data *ppe_data;
 	int err;

-	ppe_data = kzalloc_obj(*ppe_data, GFP_ATOMIC);
+	ppe_data = kzalloc(airoha_npu_mbox_size(sizeof(*ppe_data)), GFP_ATOMIC);
 	if (!ppe_data)
 		return -ENOMEM;

@@ -434,7 +441,7 @@ static int airoha_npu_ppe_stats_setup(struct airoha_npu *npu,
 	int err, size = num_stats_entries * sizeof(*npu->stats);
 	struct ppe_mbox_data *ppe_data;

-	ppe_data = kzalloc_obj(*ppe_data, GFP_ATOMIC);
+	ppe_data = kzalloc(airoha_npu_mbox_size(sizeof(*ppe_data)), GFP_ATOMIC);
 	if (!ppe_data)
 		return -ENOMEM;

@@ -466,7 +473,7 @@ static int airoha_npu_wlan_msg_send(struct airoha_npu *npu, int ifindex,
 	int err, len;

 	len = sizeof(*wlan_data) + data_len;
-	wlan_data = kzalloc(len, gfp);
+	wlan_data = kzalloc(airoha_npu_mbox_size(len), gfp);
 	if (!wlan_data)
 		return -ENOMEM;

@@ -489,7 +496,7 @@ static int airoha_npu_wlan_msg_get(struct airoha_npu *npu, int ifindex,
 	int err, len;

 	len = sizeof(*wlan_data) + data_len;
-	wlan_data = kzalloc(len, gfp);
+	wlan_data = kzalloc(airoha_npu_mbox_size(len), gfp);
 	if (!wlan_data)
 		return -ENOMEM;

--
2.55.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v8] net: airoha: npu: use cacheline-sized buffers for mailbox DMA
  2026-08-17  9:06 [PATCH v8] net: airoha: npu: use cacheline-sized buffers for mailbox DMA Daniel Pawlik
@ 2026-08-17  9:52 ` Qingfang Deng
  2026-08-17 23:17 ` Jakub Kicinski
  1 sibling, 0 replies; 5+ messages in thread
From: Qingfang Deng @ 2026-08-17  9:52 UTC (permalink / raw)
  To: Daniel Pawlik, netdev; +Cc: lorenzo, win847, linux-arm-kernel, linux-mediatek

Hi,

On 2026/8/17 17:06, Daniel Pawlik wrote:
> On EN7581 + MT7996 (Gemtek W1700K), mapping small caller buffers with
> DMA_BIDIRECTIONAL regresses NPU version probe: the mailbox completes
> successfully but WLAN_FUNC_GET_WAIT_NPU_VERSION reads as 0.0 instead of
> 0.1111.
>
> Allocate at least SMP_CACHE_BYTES for each mailbox payload and map
> ALIGN(len, SMP_CACHE_BYTES) with DMA_BIDIRECTIONAL while programming
> the original payload length into the mailbox length register.
>
> Tested on Quantum Fiber / Gemtek W1700K (EN7581 + MT7996), kernel
> 6.18.44, including two cold reboots and sustained WiFi use.
>
> Fixes: 6f884eb87a79 ("net: airoha: Fix DMA direction for NPU mailbox buffer")
> Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20260814110017.2795022-1-pawlik.dan@gmail.com/
> Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20260809152813.585797-1-pawlik.dan@gmail.com/
> Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20260805070851.2885888-1-pawlik.dan@gmail.com/
> Assisted-by: Cursor:composer-2
> Signed-off-by: Daniel Pawlik <pawlik.dan@gmail.com>
> ---
>   drivers/net/ethernet/airoha/airoha_npu.c | 25 +++++++++++++++---------
>   1 file changed, 16 insertions(+), 9 deletions(-)
>
> --
> 2.55.0
>
> diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c
> index b679bed952de..d560b8763753 100644
> --- a/drivers/net/ethernet/airoha/airoha_npu.c
> +++ b/drivers/net/ethernet/airoha/airoha_npu.c
> @@ -5,6 +5,7 @@
>    */
>
>   #include <linux/devcoredump.h>
> +#include <linux/dma-mapping.h>
>   #include <linux/firmware.h>
>   #include <linux/platform_device.h>
>   #include <linux/of_net.h>
> @@ -160,15 +161,21 @@ struct wlan_mbox_data {
>   	DECLARE_FLEX_ARRAY(u8, d);
>   };
>
> +static size_t airoha_npu_mbox_size(size_t len)
> +{
> +	return ALIGN(max(len, SMP_CACHE_BYTES), SMP_CACHE_BYTES);

SMP_CACHE_BYTES defaults to L1_CACHE_BYTES on Aarch64. On Cortex-A53 
this is fine, but some CPU's L2 cache line size might differ. For 
portability, please use dma_get_cache_alignment() instead.

Also "max" is redundant.

> +}
> +
>   static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id,
>   			       void *p, int size)
>   {
>   	u16 core = 0; /* FIXME */
>   	u32 val, offset = core << 4;
>   	dma_addr_t dma_addr;
> +	size_t map_len = airoha_npu_mbox_size(size);
>   	int ret;
>
> -	dma_addr = dma_map_single(npu->dev, p, size, DMA_BIDIRECTIONAL);
> +	dma_addr = dma_map_single(npu->dev, p, map_len, DMA_BIDIRECTIONAL);
You don't have to align the size passed to DMA API. The underlying 
implementation already aligns it.
>   	ret = dma_mapping_error(npu->dev, dma_addr);
>   	if (ret)
>   		return ret;
> @@ -191,7 +198,7 @@ static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id,
>
>   	spin_unlock_bh(&npu->cores[core].lock);
>
> -	dma_unmap_single(npu->dev, dma_addr, size, DMA_BIDIRECTIONAL);
> +	dma_unmap_single(npu->dev, dma_addr, map_len, DMA_BIDIRECTIONAL);
>
>   	return ret;
>   }

Best regards,

Qingfang



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v8] net: airoha: npu: use cacheline-sized buffers for mailbox DMA
  2026-08-17  9:06 [PATCH v8] net: airoha: npu: use cacheline-sized buffers for mailbox DMA Daniel Pawlik
  2026-08-17  9:52 ` Qingfang Deng
@ 2026-08-17 23:17 ` Jakub Kicinski
  2026-08-18  6:23   ` Daniel Pawlik
  1 sibling, 1 reply; 5+ messages in thread
From: Jakub Kicinski @ 2026-08-17 23:17 UTC (permalink / raw)
  To: Daniel Pawlik; +Cc: netdev, lorenzo, win847, linux-arm-kernel, linux-mediatek

On Mon, 17 Aug 2026 11:06:01 +0200 Daniel Pawlik wrote:
> On EN7581 + MT7996 (Gemtek W1700K), mapping small caller buffers with
> DMA_BIDIRECTIONAL regresses NPU version probe: the mailbox completes
> successfully but WLAN_FUNC_GET_WAIT_NPU_VERSION reads as 0.0 instead of
> 0.1111.
> 
> Allocate at least SMP_CACHE_BYTES for each mailbox payload and map
> ALIGN(len, SMP_CACHE_BYTES) with DMA_BIDIRECTIONAL while programming
> the original payload length into the mailbox length register.
> 
> Tested on Quantum Fiber / Gemtek W1700K (EN7581 + MT7996), kernel
> 6.18.44, including two cold reboots and sustained WiFi use.

To me the fact that this patch helps only proves that the swiotlb
implementation on this platform is wonky, no?
IOW AFAIU we are avoiding the bounce buffer so things work, but
the bounce buffer is still broken?


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v8] net: airoha: npu: use cacheline-sized buffers for mailbox DMA
  2026-08-17 23:17 ` Jakub Kicinski
@ 2026-08-18  6:23   ` Daniel Pawlik
  2026-08-18 15:29     ` Jakub Kicinski
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel Pawlik @ 2026-08-18  6:23 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: netdev, lorenzo, win847, linux-arm-kernel, linux-mediatek

Hi Kuba,

You may be right that the underlying issue is the SWIOTLB/bounce path on
EN7581 rather than DMA_BIDIRECTIONAL being wrong in general. W1700K does
show SWIOTLB enabled at boot.

v8 does not switch to coherent DMA; it only rounds up mailbox payload
allocations (dma_get_cache_alignment() in v9) and maps the same rounded
length with DMA_BIDIRECTIONAL, while the mailbox length register still
uses the original payload size. On this board, mapping only the payload
size regresses probe back to 0.0 even with the larger allocation, so the
rounded map length seems required here.

I have not bisected whether that avoids SWIOTLB entirely or just makes
the bounce/sync path behave. I agree a platform fix would be better if
the bounce implementation is broken. For now this restores NPU probe on
W1700K after 6f884eb.

I'm happy to gather more data (dma mapping debug, swiotlb usage, etc.) if
that helps track the root cause.

Thanks,
Daniel

wt., 18 sie 2026 o 01:17 Jakub Kicinski <kuba@kernel.org> napisał(a):
>
> On Mon, 17 Aug 2026 11:06:01 +0200 Daniel Pawlik wrote:
> > On EN7581 + MT7996 (Gemtek W1700K), mapping small caller buffers with
> > DMA_BIDIRECTIONAL regresses NPU version probe: the mailbox completes
> > successfully but WLAN_FUNC_GET_WAIT_NPU_VERSION reads as 0.0 instead of
> > 0.1111.
> >
> > Allocate at least SMP_CACHE_BYTES for each mailbox payload and map
> > ALIGN(len, SMP_CACHE_BYTES) with DMA_BIDIRECTIONAL while programming
> > the original payload length into the mailbox length register.
> >
> > Tested on Quantum Fiber / Gemtek W1700K (EN7581 + MT7996), kernel
> > 6.18.44, including two cold reboots and sustained WiFi use.
>
> To me the fact that this patch helps only proves that the swiotlb
> implementation on this platform is wonky, no?
> IOW AFAIU we are avoiding the bounce buffer so things work, but
> the bounce buffer is still broken?



-- 
Z poważaniem,
Daniel Pawlik


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v8] net: airoha: npu: use cacheline-sized buffers for mailbox DMA
  2026-08-18  6:23   ` Daniel Pawlik
@ 2026-08-18 15:29     ` Jakub Kicinski
  0 siblings, 0 replies; 5+ messages in thread
From: Jakub Kicinski @ 2026-08-18 15:29 UTC (permalink / raw)
  To: Daniel Pawlik; +Cc: netdev, lorenzo, win847, linux-arm-kernel, linux-mediatek

On Tue, 18 Aug 2026 08:23:33 +0200 Daniel Pawlik wrote:
> v8 does not switch to coherent DMA; it only rounds up mailbox payload
> allocations (dma_get_cache_alignment() in v9) and maps the same rounded
> length with DMA_BIDIRECTIONAL, while the mailbox length register still
> uses the original payload size. On this board, mapping only the payload
> size regresses probe back to 0.0 even with the larger allocation, so the
> rounded map length seems required here.

Please trace into the dma API implementation on this platform where the
alignment makes a difference. The "unaligned length" path must be buggy.
We should fix it there, not in all the drivers (my concern being that
this is not the only driver that hits the issue).


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-08-18 15:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-17  9:06 [PATCH v8] net: airoha: npu: use cacheline-sized buffers for mailbox DMA Daniel Pawlik
2026-08-17  9:52 ` Qingfang Deng
2026-08-17 23:17 ` Jakub Kicinski
2026-08-18  6:23   ` Daniel Pawlik
2026-08-18 15:29     ` Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox