lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 27 Oct 2022 10:50:07 +0530
From:   Sireesh Kodali <sireeshkodali1@...il.com>
To:     andersson@...nel.org, agross@...nel.org,
        ~postmarketos/upstreaming@...ts.sr.ht, linux-kernel@...r.kernel.org
Cc:     dmaengine@...r.kernel.org,
        Vladimir Lypak <vladimir.lypak@...il.com>,
        Sireesh Kodali <sireeshkodali1@...il.com>,
        Konrad Dybcio <konrad.dybcio@...ainline.org>,
        Vinod Koul <vkoul@...nel.org>,
        linux-arm-msm@...r.kernel.org (open list:ARM/QUALCOMM SUPPORT)
Subject: [PATCH v2 1/1] dmaengine: qcom: bam_dma: Add support for metadata

From: Vladimir Lypak <vladimir.lypak@...il.com>

Add client metadata support for receiving information about transfers.
Only type of metadata implemented is amount of transferred bytes. This
can be used to know how much data is actually received if information
transferred doesn't contain header with size or is aggregated.

Signed-off-by: Vladimir Lypak <vladimir.lypak@...il.com>
Signed-off-by: Sireesh Kodali <sireeshkodali1@...il.com>
---
 drivers/dma/qcom/bam_dma.c       | 57 ++++++++++++++++++++++++++++++++
 include/linux/dma/qcom_bam_dma.h |  8 +++++
 2 files changed, 65 insertions(+)

diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 3135a3e4a167..264a9a2e199f 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/dma/qcom_bam_dma.h>
 #include <linux/scatterlist.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
@@ -70,6 +71,7 @@ struct bam_async_desc {
 	u16 flags;
 
 	struct bam_desc_hw *curr_desc;
+	struct bam_dma_metadata *metadata;
 
 	/* list node for the desc in the bam_chan list of descriptors */
 	struct list_head desc_node;
@@ -418,6 +420,52 @@ static inline void __iomem *bam_addr(struct bam_device *bdev, u32 pipe,
 		r.ee_mult * bdev->ee;
 }
 
+/**
+ * bam_update_metadata - update metadata buffer
+ * @bchan: BAM channel to read metadata from
+ * @async_desc: BAM async descriptior
+ *
+ * Updates metadata buffer (transfer size) based on values
+ * read from FIFO descriptors at bchan->head
+ */
+
+static inline void bam_update_metadata(struct bam_chan *bchan,
+				       struct bam_async_desc *async_desc)
+{
+	unsigned int i, e, len = 0;
+	struct bam_desc_hw *fifo;
+
+	if (!async_desc->metadata)
+		return;
+
+	fifo = PTR_ALIGN(bchan->fifo_virt, sizeof(struct bam_desc_hw));
+	for (i = bchan->head, e = i + async_desc->xfer_len; i < e; i++)
+		len += fifo[i % MAX_DESCRIPTORS].size;
+
+	async_desc->metadata->xfer_len_bytes += len;
+}
+
+/**
+ * bam_attach_metadata - attach metadata buffer to the async descriptor
+ * @desc: async descriptor
+ * @data: buffer pointer
+ * @len: length of passed buffer
+ */
+static int bam_attach_metadata(struct dma_async_tx_descriptor *desc, void *data,
+			       size_t len)
+{
+	struct bam_async_desc *async_desc;
+
+	if (!data || len != sizeof(struct bam_dma_metadata))
+		return -EINVAL;
+
+	async_desc = container_of(desc, struct bam_async_desc, vd.tx);
+	async_desc->metadata = data;
+	async_desc->metadata->xfer_len_bytes = 0;
+
+	return 0;
+}
+
 /**
  * bam_reset() - reset and initialize BAM registers
  * @bdev: bam device
@@ -456,6 +504,10 @@ static void bam_reset(struct bam_device *bdev)
 	writel_relaxed(BAM_IRQ_MSK, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE));
 }
 
+static struct dma_descriptor_metadata_ops metadata_ops = {
+	.attach = bam_attach_metadata,
+};
+
 /**
  * bam_reset_channel - Reset individual BAM DMA channel
  * @bchan: bam channel
@@ -714,6 +766,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);
 }
 
@@ -867,6 +921,8 @@ static u32 process_channel_irqs(struct bam_device *bdev)
 			if (avail < async_desc->xfer_len)
 				break;
 
+			bam_update_metadata(bchan, async_desc);
+
 			/* manage FIFO */
 			bchan->head += async_desc->xfer_len;
 			bchan->head %= MAX_DESCRIPTORS;
@@ -1347,6 +1403,7 @@ static int bam_dma_probe(struct platform_device *pdev)
 	bdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
 	bdev->common.src_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES;
 	bdev->common.dst_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	bdev->common.desc_metadata_modes = DESC_METADATA_CLIENT;
 	bdev->common.device_alloc_chan_resources = bam_alloc_chan;
 	bdev->common.device_free_chan_resources = bam_free_chan;
 	bdev->common.device_prep_slave_sg = bam_prep_slave_sg;
diff --git a/include/linux/dma/qcom_bam_dma.h b/include/linux/dma/qcom_bam_dma.h
index 68fc0e643b1b..8168b0573f45 100644
--- a/include/linux/dma/qcom_bam_dma.h
+++ b/include/linux/dma/qcom_bam_dma.h
@@ -8,6 +8,14 @@
 
 #include <asm/byteorder.h>
 
+/*
+ * This data type is used as client metadata buffer in bam driver.
+ */
+struct bam_dma_metadata {
+	/* Actual number of bytes transferred by hardware */
+	size_t xfer_len_bytes;
+};
+
 /*
  * This data type corresponds to the native Command Element
  * supported by BAM DMA Engine.
-- 
2.38.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ