2026-01-29 22:25:33 +08:00

552 lines
11 KiB
C

// SPDX-License-Identifier: GPL-2.0
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <asm/sw64io.h>
#include <asm/debug.h>
#include <asm/csr.h>
char da_match_buf[1024], dv_match_buf[1024], dav_match_buf[1024];
char ia_match_buf[1024], iv_match_buf[1024], ida_match_buf[1024];
unsigned long da_match_cf1, da_match_cf2, da_match_cf3;
unsigned long dv_match_cf1, dv_match_cf2, dv_match_cf3;
unsigned long dav_match_cf1, dav_match_cf2, dav_match_cf3,
dav_match_cf4, dav_match_cf5;
unsigned long ia_match_cf1, ia_match_cf2, ia_match_cf3, ia_match_cf4;
unsigned long iv_match_cf1, iv_match_cf2;
unsigned long ida_match_cf1, ida_match_cf2;
static int da_match_show(struct seq_file *m, void *v)
{
seq_printf(m, "%s", da_match_buf);
return 0;
}
static int dv_match_show(struct seq_file *m, void *v)
{
seq_printf(m, "%s", dv_match_buf);
return 0;
}
static int dav_match_show(struct seq_file *m, void *v)
{
seq_printf(m, "%s", dav_match_buf);
return 0;
}
static int ia_match_show(struct seq_file *m, void *v)
{
seq_printf(m, "%s", ia_match_buf);
return 0;
}
static int iv_match_show(struct seq_file *m, void *v)
{
seq_printf(m, "%s", iv_match_buf);
return 0;
}
static int ida_match_show(struct seq_file *m, void *v)
{
seq_printf(m, "%s", ida_match_buf);
return 0;
}
static int da_match_open(struct inode *inode, struct file *file)
{
return single_open(file, da_match_show, NULL);
}
static int dv_match_open(struct inode *inode, struct file *file)
{
return single_open(file, dv_match_show, NULL);
}
static int dav_match_open(struct inode *inode, struct file *file)
{
return single_open(file, dav_match_show, NULL);
}
static int ia_match_open(struct inode *inode, struct file *file)
{
return single_open(file, ia_match_show, NULL);
}
static int iv_match_open(struct inode *inode, struct file *file)
{
return single_open(file, iv_match_show, NULL);
}
static int ida_match_open(struct inode *inode, struct file *file)
{
return single_open(file, ida_match_show, NULL);
}
static void
write_da_match(void *i)
{
unsigned long dc_ctl;
write_csr(da_match_cf1, CSR_DA_MATCH);
write_csr(da_match_cf2, CSR_DA_MASK);
dc_ctl = read_csr(CSR_DC_CTLP);
dc_ctl &= ~((0x1UL << 3) | (0x3UL << DA_MATCH_EN_S)
| (0x1UL << DAV_MATCH_EN_S) | (0x1UL << DPM_MATCH_EN_S)
| (0x3UL << DPM_MATCH));
dc_ctl |= da_match_cf3;
write_csr(dc_ctl, CSR_DC_CTLP);
}
static void
write_dv_match(void *i)
{
unsigned long dc_ctl;
write_csr(dv_match_cf1, CSR_DV_MATCH);
write_csr(dv_match_cf2, CSR_DV_MASK);
dc_ctl = read_csr(CSR_DC_CTLP);
dc_ctl &= ~((0x1UL << DAV_MATCH_EN_S) | (0x1UL << DPM_MATCH_EN_S)
| (0x3UL << DPM_MATCH));
dc_ctl |= ((0x1UL << DV_MATCH_EN_S) | dv_match_cf3);
write_csr(dc_ctl, CSR_DC_CTLP);
}
static void
write_dav_match(void *i)
{
unsigned long dc_ctl;
write_csr(dav_match_cf1, CSR_DA_MATCH);
write_csr(dav_match_cf2, CSR_DA_MASK);
write_csr(dav_match_cf3, CSR_DV_MATCH);
write_csr(dav_match_cf4, CSR_DV_MASK);
dc_ctl = read_csr(CSR_DC_CTLP);
dc_ctl &= ~((0x1UL << 3) | (0x3UL << DA_MATCH_EN_S)
| (0x1UL << DPM_MATCH_EN_S) | (0x3UL << DPM_MATCH));
dc_ctl |= ((0x1UL << DV_MATCH_EN_S) | (0x1UL << DAV_MATCH_EN_S)
| dav_match_cf5);
write_csr(dc_ctl, CSR_DC_CTLP);
}
static void
write_ia_match(void *i)
{
ia_match_cf1 |= (0x1UL << IA_MATCH_EN_S);
write_csr_imb(ia_match_cf1, CSR_IA_MATCH);
write_csr_imb(ia_match_cf2, CSR_IA_MASK);
write_csr(((0x3ffUL << 18) | ia_match_cf3), CSR_IA_VPNMATCH);
write_csr(((0x3ffUL << 18) | ia_match_cf4), CSR_IA_UPNMATCH);
}
static void
write_iv_match(void *i)
{
unsigned long ia_match_tmp;
ia_match_tmp = read_csr(CSR_IA_MATCH);
ia_match_tmp &= ~(0x1UL << IV_PM_EN_S);
ia_match_tmp |= ((((iv_match_cf2 >> IV_PM_EN_S) & 0x1) << IV_PM_EN_S)
| (iv_match_cf2 & 0x3) | (0x1UL << IV_MATCH_EN_S));
write_csr_imb(iv_match_cf1, CSR_IV_MATCH);
write_csr_imb(ia_match_tmp, CSR_IA_MATCH);
}
static void
write_ida_match(void *i)
{
ida_match_cf1 |= (0x1UL << IDA_MATCH_EN_S);
write_csr(ida_match_cf1, CSR_IDA_MATCH);
write_csr(ida_match_cf2, CSR_IDA_MASK);
}
static ssize_t da_match_set(struct file *file, const char __user *user_buf,
size_t len, loff_t *ppos)
{
size_t size;
char tmp[400];
char *p;
int i, m;
const char *sep = " ";
char tmp1[400];
int err;
char *ret = NULL;
size = min(sizeof(da_match_buf) - 1, len);
if (copy_from_user(da_match_buf, user_buf, size))
return -EFAULT;
da_match_buf[size] = '\0';
strcpy(tmp, da_match_buf);
p = tmp;
for (i = 0 ; i < 4; i++) {
m = i*100;
ret = strsep(&p, sep);
if (ret != NULL)
strcpy(&tmp1[m], ret);
}
tmp1[400] = '\0';
err = kstrtoul(&tmp1[0], 0, &da_match_cf1);
if (err)
return err;
err = kstrtoul(&tmp1[100], 0, &da_match_cf2);
if (err)
return err;
err = kstrtoul(&tmp1[200], 0, &da_match_cf3);
if (err)
return err;
if (on_each_cpu(write_da_match, NULL, 1))
pr_crit("%s: timed out\n", __func__);
return len;
}
static ssize_t dv_match_set(struct file *file, const char __user *user_buf,
size_t len, loff_t *ppos)
{
size_t size;
char tmp[400];
char *p;
int i, m;
const char *sep = " ";
char tmp1[400];
int err;
char *ret = NULL;
size = min(sizeof(dv_match_buf) - 1, len);
if (copy_from_user(dv_match_buf, user_buf, size))
return -EFAULT;
dv_match_buf[size] = '\0';
strcpy(tmp, dv_match_buf);
p = tmp;
for (i = 0 ; i < 4; i++) {
m = i*100;
ret = strsep(&p, sep);
if (ret != NULL)
strcpy(&tmp1[m], ret);
}
tmp1[400] = '\0';
err = kstrtoul(&tmp1[0], 0, &dv_match_cf1);
if (err)
return err;
err = kstrtoul(&tmp1[100], 0, &dv_match_cf2);
if (err)
return err;
err = kstrtoul(&tmp1[200], 0, &dv_match_cf3);
if (err)
return err;
if (on_each_cpu(write_dv_match, NULL, 1))
pr_crit("%s: timed out\n", __func__);
return len;
}
static ssize_t dav_match_set(struct file *file, const char __user *user_buf,
size_t len, loff_t *ppos)
{
size_t size;
char tmp[500];
char *p;
int i, m;
const char *sep = " ";
char tmp1[500];
int err;
char *ret = NULL;
size = min(sizeof(dav_match_buf) - 1, len);
if (copy_from_user(dav_match_buf, user_buf, size))
return -EFAULT;
dav_match_buf[size] = '\0';
strcpy(tmp, dav_match_buf);
p = tmp;
for (i = 0 ; i < 5; i++) {
m = i*100;
ret = strsep(&p, sep);
if (ret != NULL)
strcpy(&tmp1[m], ret);
}
tmp1[500] = '\0';
err = kstrtoul(&tmp1[0], 0, &dav_match_cf1);
if (err)
return err;
err = kstrtoul(&tmp1[100], 0, &dav_match_cf2);
if (err)
return err;
err = kstrtoul(&tmp1[200], 0, &dav_match_cf3);
if (err)
return err;
err = kstrtoul(&tmp1[300], 0, &dav_match_cf4);
if (err)
return err;
err = kstrtoul(&tmp1[400], 0, &dav_match_cf5);
if (err)
return err;
if (on_each_cpu(write_dav_match, NULL, 1))
pr_crit("%s: timed out\n", __func__);
return len;
}
static ssize_t ia_match_set(struct file *file, const char __user *user_buf,
size_t len, loff_t *ppos)
{
size_t size;
char tmp[400];
char *p;
int i, m;
const char *sep = " ";
char tmp1[400];
int err;
char *ret = NULL;
size = min(sizeof(ia_match_buf) - 1, len);
if (copy_from_user(ia_match_buf, user_buf, size))
return -EFAULT;
ia_match_buf[size] = '\0';
strcpy(tmp, ia_match_buf);
p = tmp;
for (i = 0 ; i < 4; i++) {
m = i*100;
ret = strsep(&p, sep);
if (ret != NULL)
strcpy(&tmp1[m], ret);
}
tmp1[400] = '\0';
err = kstrtoul(&tmp1[0], 0, &ia_match_cf1);
if (err)
return err;
err = kstrtoul(&tmp1[100], 0, &ia_match_cf2);
if (err)
return err;
err = kstrtoul(&tmp1[200], 0, &ia_match_cf3);
if (err)
return err;
err = kstrtoul(&tmp1[300], 0, &ia_match_cf4);
if (err)
return err;
if (on_each_cpu(write_ia_match, NULL, 1))
pr_crit("%s: timed out\n", __func__);
return len;
}
static ssize_t iv_match_set(struct file *file, const char __user *user_buf,
size_t len, loff_t *ppos)
{
size_t size;
char tmp[400];
char *p;
int i, m;
const char *sep = " ";
char tmp1[400];
int err;
char *ret = NULL;
size = min(sizeof(ia_match_buf) - 1, len);
if (copy_from_user(ia_match_buf, user_buf, size))
return -EFAULT;
ia_match_buf[size] = '\0';
strcpy(tmp, ia_match_buf);
p = tmp;
for (i = 0 ; i < 4; i++) {
m = i*100;
ret = strsep(&p, sep);
if (ret != NULL)
strcpy(&tmp1[m], ret);
}
tmp1[400] = '\0';
err = kstrtoul(&tmp1[0], 0, &iv_match_cf1);
if (err)
return err;
err = kstrtoul(&tmp1[100], 0, &iv_match_cf2);
if (err)
return err;
if (on_each_cpu(write_iv_match, NULL, 1))
pr_crit("%s: timed out\n", __func__);
return len;
}
static ssize_t ida_match_set(struct file *file, const char __user *user_buf,
size_t len, loff_t *ppos)
{
size_t size;
char tmp[400];
char *p;
int i, m;
const char *sep = " ";
char tmp1[400];
int err;
char *ret = NULL;
size = min(sizeof(ida_match_buf) - 1, len);
if (copy_from_user(ida_match_buf, user_buf, size))
return -EFAULT;
ida_match_buf[size] = '\0';
strcpy(tmp, ida_match_buf);
p = tmp;
for (i = 0 ; i < 4; i++) {
m = i*100;
ret = strsep(&p, sep);
if (ret != NULL)
strcpy(&tmp1[m], ret);
}
tmp1[400] = '\0';
err = kstrtoul(&tmp1[0], 0, &ida_match_cf1);
if (err)
return err;
err = kstrtoul(&tmp1[100], 0, &ida_match_cf2);
if (err)
return err;
if (on_each_cpu(write_ida_match, NULL, 1))
pr_crit("%s: timed out\n", __func__);
return len;
}
static const struct file_operations set_da_match_fops = {
.open = da_match_open,
.read = seq_read,
.write = da_match_set,
.llseek = seq_lseek,
.release = single_release,
};
static const struct file_operations set_dv_match_fops = {
.open = dv_match_open,
.read = seq_read,
.write = dv_match_set,
.llseek = seq_lseek,
.release = single_release,
};
static const struct file_operations set_dav_match_fops = {
.open = dav_match_open,
.read = seq_read,
.write = dav_match_set,
.llseek = seq_lseek,
.release = single_release,
};
static const struct file_operations set_ia_match_fops = {
.open = ia_match_open,
.read = seq_read,
.write = ia_match_set,
.llseek = seq_lseek,
.release = single_release,
};
static const struct file_operations set_iv_match_fops = {
.open = iv_match_open,
.read = seq_read,
.write = iv_match_set,
.llseek = seq_lseek,
.release = single_release,
};
static const struct file_operations set_ida_match_fops = {
.open = ida_match_open,
.read = seq_read,
.write = ida_match_set,
.llseek = seq_lseek,
.release = single_release,
};
static int __init match_debugfs_init(void)
{
struct dentry *match_entry;
if (!sw64_debugfs_dir)
return -ENODEV;
match_entry = debugfs_create_file("da_match", 0600,
sw64_debugfs_dir, NULL,
&set_da_match_fops);
if (!match_entry)
return -ENOMEM;
match_entry = debugfs_create_file("dv_match", 0600,
sw64_debugfs_dir, NULL,
&set_dv_match_fops);
if (!match_entry)
return -ENOMEM;
match_entry = debugfs_create_file("dav_match", 0600,
sw64_debugfs_dir, NULL,
&set_dav_match_fops);
if (!match_entry)
return -ENOMEM;
match_entry = debugfs_create_file("ia_match", 0600,
sw64_debugfs_dir, NULL,
&set_ia_match_fops);
if (!match_entry)
return -ENOMEM;
match_entry = debugfs_create_file("iv_match", 0600,
sw64_debugfs_dir, NULL,
&set_iv_match_fops);
if (!match_entry)
return -ENOMEM;
match_entry = debugfs_create_file("ida_match", 0600,
sw64_debugfs_dir, NULL,
&set_ida_match_fops);
if (!match_entry)
return -ENOMEM;
return 0;
}
late_initcall(match_debugfs_init);