DMA Engine development
 help / color / mirror / Atom feed
* [PATCH] dmaengine: qcom: bam_dma: Report the residue of packet
@ 2026-11-15 15:52 Nickolay Goppen
  2026-11-15 16:08 ` sashiko-bot
  0 siblings, 1 reply; 3+ messages in thread
From: Nickolay Goppen @ 2026-11-15 15:52 UTC (permalink / raw)
  To: Vinod Koul, Frank Li
  Cc: linux-arm-msm, dmaengine, linux-kernel, Nickolay Goppen

The BAM writes back the number of bytes actually received into the
descriptor that ended an RX transfer. Report this through the standard
dmaengine_result (residue = length - transferred) so clients get the
packet length from callback_result().

Assisted-by: LLM
Signed-off-by: Nickolay Goppen <setotau@mainlining.org>
---
IPA v2.x uses BAM to send and receive IP packets, to and from the AP.
However, unlike its predecessor BAM-DMUX, it doesn't send information
about the packet length, but ipa2 driver will need that. To find the 
length of the packet, one must instead read the difference between 
packet length and residue.
---
 drivers/dma/qcom/bam_dma.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index e62e411dc8f8..b5cfe3ce3406 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -65,6 +65,7 @@ struct bam_async_desc {
 
 	u32 num_desc;
 	u32 xfer_len;
+	size_t transferred;
 
 	/* transaction flags, EOT|EOB|NWD */
 	u16 flags;
@@ -447,6 +448,30 @@ static inline void __iomem *bam_addr(struct bam_device *bdev, u32 pipe,
 		r.ee_mult * bdev->ee;
 }
 
+/**
+ * bam_fifo_xfer_len - bytes transferred for a completed descriptor chunk
+ * @bchan: BAM channel the chunk was queued on
+ * @async_desc: BAM async descriptor owning the chunk
+ *
+ * For RX pipes the BAM overwrites the size field of the descriptor that
+ * ended the transfer with the number of bytes actually written to memory,
+ * which can be less than the buffer size (e.g. an IPA packet).  Those
+ * values live in the FIFO copy, not in async_desc->desc[].
+ */
+
+static u32 bam_fifo_xfer_len(struct bam_chan *bchan,
+			     const struct bam_async_desc *async_desc)
+	struct bam_desc_hw *fifo = PTR_ALIGN(bchan->fifo_virt,
+					     sizeof(struct bam_desc_hw));
+	u32 len = 0;
+	unsigned int i;
+
+	for (i = bchan->head; i < bchan->head + async_desc->xfer_len; i++)
+		len += le16_to_cpu(fifo[i % MAX_DESCRIPTORS].size);
+
+	return len;
+}
+
 /**
  * bam_reset() - reset and initialize BAM registers
  * @bdev: bam device
@@ -732,6 +757,8 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
 		} while (remainder > 0);
 	}
 
+	async_desc->vd.tx.metadata_ops = &metadata_ops;
+
 	return vchan_tx_prep(&bchan->vc, &async_desc->vd, flags);
 }
 
@@ -881,6 +908,11 @@ static u32 process_channel_irqs(struct bam_device *bdev)
 			if (avail < async_desc->xfer_len)
 				break;
 
+			async_desc->transferred +=
+				bam_fifo_xfer_len(bchan, async_desc);
+			async_desc->vd.tx_result.residue =
+				async_desc->length - async_desc->transferred;
+
 			/* manage FIFO */
 			bchan->head += async_desc->xfer_len;
 			bchan->head %= MAX_DESCRIPTORS;

---
base-commit: 2cc223d6ffadd48e25eff0c8a03108a5d7a61c41
change-id: 20261115-qcom-bam-dma-metadata-f34e592d400c

Best regards,
--  
Nickolay Goppen <setotau@mainlining.org>

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

end of thread, other threads:[~2026-11-15 16:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-15 15:52 [PATCH] dmaengine: qcom: bam_dma: Report the residue of packet Nickolay Goppen
2026-11-15 16:08 ` sashiko-bot
2026-11-15 16:14   ` Nickolay Goppen

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