mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
PCI: Add data integrity check for PCIe DMA
Add CRC check after PCIe DMA to verify data integrity. Bug 3636902 Bug 3868928 Change-Id: If497ce769571c6c837acbfbbb64b2242dfabef26 Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2718787 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2720336 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2815927 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Tested-by: Nagarjuna Kristam <nkristam@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
b26885400f
commit
319fa69bd5
@@ -14,6 +14,7 @@
|
||||
|
||||
#define EDMA_ABORT_TEST_EN (edma->edma_ch & 0x40000000)
|
||||
#define EDMA_STOP_TEST_EN (edma->edma_ch & 0x20000000)
|
||||
#define EDMA_CRC_TEST_EN (edma->edma_ch & 0x10000000)
|
||||
#define IS_EDMA_CH_ENABLED(i) (edma->edma_ch & ((BIT(i) << 4)))
|
||||
#define IS_EDMA_CH_ASYNC(i) (edma->edma_ch & BIT(i))
|
||||
#define REMOTE_EDMA_TEST_EN (edma->edma_ch & 0x80000000)
|
||||
@@ -26,7 +27,9 @@
|
||||
|
||||
struct edmalib_common {
|
||||
struct device *fdev;
|
||||
void *bar0_virt;
|
||||
void (*raise_irq)(void *p);
|
||||
void *priv;
|
||||
struct pcie_epf_bar0 *epf_bar0;
|
||||
void *src_virt;
|
||||
void __iomem *dma_base;
|
||||
u32 dma_size;
|
||||
@@ -114,6 +117,7 @@ static int edmalib_common_test(struct edmalib_common *edma)
|
||||
char *xfer_str[2] = {"WR", "RD"};
|
||||
u32 l_r;
|
||||
char *l_r_str[2] = {"local", "remote"};
|
||||
struct pcie_epf_bar0 *epf_bar0 = edma->epf_bar0;
|
||||
|
||||
if (!edma->stress_count) {
|
||||
tegra_pcie_edma_deinit(edma->cookie);
|
||||
@@ -129,6 +133,16 @@ static int edmalib_common_test(struct edmalib_common *edma)
|
||||
edma->edma_ch |= 0xF5;
|
||||
}
|
||||
|
||||
if (EDMA_CRC_TEST_EN) {
|
||||
/* 4 channels in sync mode */
|
||||
edma->edma_ch = (EDMA_CRC_TEST_EN | 0xF0);
|
||||
/* Single SZ_4K packet on each channel, so total SZ_16K of data */
|
||||
edma->stress_count = 1;
|
||||
edma->dma_size = SZ_4K;
|
||||
edma->nents = nents = 4;
|
||||
epf_bar0->wr_data[0].size = edma->dma_size * edma->nents;
|
||||
}
|
||||
|
||||
if (edma->cookie && edma->prev_edma_ch != edma->edma_ch) {
|
||||
edma->st_as_ch = -1;
|
||||
dev_info(edma->fdev, "edma_ch changed from 0x%x != 0x%x, deinit\n",
|
||||
@@ -291,6 +305,19 @@ static int edmalib_common_test(struct edmalib_common *edma)
|
||||
edma->tsz, diff, EDMA_PERF);
|
||||
}
|
||||
}
|
||||
|
||||
if (EDMA_CRC_TEST_EN && !REMOTE_EDMA_TEST_EN) {
|
||||
u32 crc;
|
||||
|
||||
edma->raise_irq(edma->priv);
|
||||
crc = crc32_le(~0, edma->src_virt, epf_bar0->wr_data[0].size);
|
||||
msleep(100);
|
||||
if (crc != epf_bar0->wr_data[0].crc)
|
||||
dev_err(edma->fdev, "CRC check failed, LCRC: 0x%x RCRC: 0x%x\n",
|
||||
crc, epf_bar0->wr_data[0].crc);
|
||||
else
|
||||
dev_err(edma->fdev, "CRC check pass\n");
|
||||
}
|
||||
dev_info(edma->fdev, "%s: EDMA LIB submit done\n", __func__);
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user