PCI: rockchip: add checksum for dma trx

Change-Id: Ib51edd5527976a4aa66893937918911d9d1d20c1
Signed-off-by: Simon Xue <xxm@rock-chips.com>
This commit is contained in:
Simon Xue
2021-08-06 09:50:00 +08:00
committed by Tao Huang
parent cefaa94c1a
commit cdfa3fbd8a

View File

@@ -122,6 +122,7 @@
#define PCIE_DMA_SET_DATA_CHECK_POS (SZ_1M - 0x4)
#define PCIE_DMA_SET_LOCAL_IDX_POS (SZ_1M - 0x8)
#define PCIE_DMA_SET_BUF_SIZE_POS (SZ_1M - 0xc)
#define PCIE_DMA_SET_CHK_SUM_POS (SZ_1M - 0x10)
#define PCIE_DMA_DATA_CHECK 0x12345678
#define PCIE_DMA_DATA_ACK_CHECK 0xdeadbeef
@@ -130,6 +131,8 @@
#define PCIE_DMA_PARAM_SIZE 64
#define PCIE_DMA_CHN0 0x0
static int enable_check_sum;
struct pcie_misc_dev {
struct miscdevice dev;
struct dma_trx_obj *obj;
@@ -140,6 +143,18 @@ static inline bool is_rc(struct dma_trx_obj *obj)
return (obj->busno == 0);
}
static unsigned int rk_pcie_check_sum(unsigned int *src, int size)
{
unsigned int result = 0;
size /= sizeof(*src);
while (size-- > 0)
result ^= *src++;
return result;
}
static void rk_pcie_prepare_dma(struct dma_trx_obj *obj,
unsigned int idx, unsigned int bus_idx,
unsigned int local_idx, size_t buf_size,
@@ -150,6 +165,7 @@ static void rk_pcie_prepare_dma(struct dma_trx_obj *obj,
void *virt;
unsigned long flags;
struct dma_table *table = NULL;
unsigned int checksum;
switch (type) {
case PCIE_DMA_DATA_SND:
@@ -171,6 +187,11 @@ static void rk_pcie_prepare_dma(struct dma_trx_obj *obj,
writel(local_idx, virt + PCIE_DMA_SET_LOCAL_IDX_POS);
writel(buf_size, virt + PCIE_DMA_SET_BUF_SIZE_POS);
if (enable_check_sum) {
checksum = rk_pcie_check_sum(virt, SZ_1M - 0x10);
writel(checksum, virt + PCIE_DMA_SET_CHK_SUM_POS);
}
buf_size = SZ_1M;
break;
case PCIE_DMA_DATA_RCV_ACK:
@@ -275,6 +296,7 @@ static enum hrtimer_restart rk_pcie_scan_timer(struct hrtimer *timer)
bool need_ack = false;
struct dma_trx_obj *obj = container_of(timer,
struct dma_trx_obj, scan_timer);
unsigned int check_sum, check_sum_tmp;
for (i = 0; i < PCIE_DMA_BUF_CNT; i++) {
sda_base = obj->mem_base + PCIE_DMA_BUF_SIZE * i;
@@ -290,7 +312,19 @@ static enum hrtimer_restart rk_pcie_scan_timer(struct hrtimer *timer)
if (sdv == PCIE_DMA_DATA_CHECK) {
if (!need_ack)
need_ack = true;
if (enable_check_sum) {
check_sum = readl(scan_data_addr + PCIE_DMA_SET_CHK_SUM_POS);
check_sum_tmp = rk_pcie_check_sum(scan_data_addr, SZ_1M - 0x10);
if (check_sum != check_sum_tmp) {
pr_err("checksum[%d] failed, 0x%x, should be 0x%x\n",
idx, check_sum_tmp, check_sum);
print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET,
32, 4, scan_data_addr, SZ_1M, false);
}
writel(0x0, scan_data_addr + PCIE_DMA_SET_CHK_SUM_POS);
}
writel(0x0, scan_data_addr + PCIE_DMA_SET_DATA_CHECK_POS);
set_bit(i, &obj->local_read_available);
rk_pcie_prepare_dma(obj, idx, 0, 0, 0x4,
PCIE_DMA_DATA_RCV_ACK);
@@ -647,12 +681,25 @@ static int rk_pcie_debugfs_open(struct inode *inode, struct file *file)
return single_open(file, rk_pcie_debugfs_trx_show, inode->i_private);
}
static ssize_t rk_pcie_debugfs_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
int ret;
ret = kstrtoint_from_user(user_buf, count, 0, &enable_check_sum);
if (ret)
return ret;
return count;
}
static const struct file_operations rk_pcie_debugfs_fops = {
.owner = THIS_MODULE,
.open = rk_pcie_debugfs_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = rk_pcie_debugfs_write,
};
#endif