Netdev List
 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; 3+ 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] 3+ 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; 3+ 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] 3+ 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; 3+ 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] 3+ messages in thread

end of thread, other threads:[~2026-08-17 23:17 UTC | newest]

Thread overview: 3+ 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

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