mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
PCI: rockchip: add checksum for dma trx
Change-Id: Ib51edd5527976a4aa66893937918911d9d1d20c1 Signed-off-by: Simon Xue <xxm@rock-chips.com>
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user