realtek: add portmasks, vlan_profiles and vlans to debugfs

Prepare portmasks, vlan profiles and vlans for changes
in upcoming patches by exporting them to debugfs for easier
debugging and monitoring.

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
Link: https://github.com/openwrt/openwrt/pull/21872
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Linus Lüssing 2025-05-07 18:53:06 +02:00 committed by Robert Marko
parent 5435ed7acc
commit 19d849d900
8 changed files with 434 additions and 74 deletions

View file

@ -360,6 +360,229 @@ static const struct file_operations l2_table_fops = {
.release = single_release,
};
static int rtldsa_pmsks_table_raw_show(struct seq_file *m, void *v)
{
struct rtl838x_switch_priv *priv = m->private;
u64 all_ports;
mutex_lock(&priv->reg_mutex);
for (int i = 0; i < MAX_MC_PMASKS; i += 4) {
seq_printf(m, "%04i: ", i);
for (int j = 0; j < 4; j++) {
bool is_set = test_bit(i + j, priv->mc_group_bm);
seq_printf(m, " %c0x%016llx%c", is_set ? ' ' : '(',
priv->r->read_mcast_pmask(i + j),
is_set ? ' ' : ')');
}
seq_printf(m, "\n");
}
all_ports = priv->r->read_mcast_pmask(MC_PMASK_ALL_PORTS_IDX);
seq_printf(m, "MC_PMASK_ALL_PORTS (%i): 0x%016llx\n",
MC_PMASK_ALL_PORTS_IDX, all_ports);
mutex_unlock(&priv->reg_mutex);
return 0;
}
static int rtldsa_pmsks_table_raw_open(struct inode *inode, struct file *filp)
{
return single_open(filp, rtldsa_pmsks_table_raw_show, inode->i_private);
}
static const struct file_operations rtldsa_pmsks_table_raw_fops = {
.owner = THIS_MODULE,
.open = rtldsa_pmsks_table_raw_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int rtldsa_pmsks_table_show(struct seq_file *m, void *v)
{
struct rtl838x_switch_priv *priv = m->private;
u64 ports;
mutex_lock(&priv->reg_mutex);
for (int i = 0; i < MC_PMASK_ALL_PORTS_IDX; i++) {
if (!test_bit(i, priv->mc_group_bm))
continue;
ports = priv->r->read_mcast_pmask(i);
seq_printf(m, "%04i:", i);
for (int j = 0; j < sizeof(ports)*8; j++)
if (ports & BIT_ULL(j))
seq_printf(m, " %i", j);
seq_printf(m, "\n");
}
ports = priv->r->read_mcast_pmask(MC_PMASK_ALL_PORTS_IDX);
seq_printf(m, "MC_PMASK_ALL_PORTS (%i):", MC_PMASK_ALL_PORTS_IDX);
for (int i = 0; i < sizeof(ports)*8; i++)
if (ports & BIT_ULL(i))
seq_printf(m, " %i", i);
seq_printf(m, "\n");
mutex_unlock(&priv->reg_mutex);
return 0;
}
static int rtldsa_pmsks_table_open(struct inode *inode, struct file *filp)
{
return single_open(filp, rtldsa_pmsks_table_show, inode->i_private);
}
static const struct file_operations rtldsa_pmsks_table_fops = {
.owner = THIS_MODULE,
.open = rtldsa_pmsks_table_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int rtldsa_vlan_profiles_show(struct seq_file *m, void *v)
{
struct rtl838x_switch_priv *priv = m->private;
struct rtldsa_vlan_profile profile;
int ret, profiles_max;
if (!priv->r->vlan_profile_get)
return -ENOTSUPP;
profiles_max = max(RTL838X_VLAN_PROFILE_MAX, RTL839X_VLAN_PROFILE_MAX);
profiles_max = max(profiles_max, RTL930X_VLAN_PROFILE_MAX);
profiles_max = max(profiles_max, RTL931X_VLAN_PROFILE_MAX);
mutex_lock(&priv->reg_mutex);
seq_printf(m,
"prof-idx: L2 learn | UNKN L2MC FLD PMSK (IDX) | UNKN IPMC FLD PMSK (IDX) | UNKN IPv6MC FLD PMSK (IDX)\n");
for (int i = 0; i <= profiles_max; i++) {
ret = priv->r->vlan_profile_get(i, &profile);
if (ret < 0)
break;
if (profile.pmsk_is_idx)
seq_printf(m, "%i: %i %03i %03i %03i\n", i,
profile.l2_learn,
profile.unkn_mc_fld.pmsks_idx.l2,
profile.unkn_mc_fld.pmsks_idx.ip,
profile.unkn_mc_fld.pmsks_idx.ip6);
else
seq_printf(m, "%i: %i 0x%016llx 0x%016llx 0x%016llx\n", i,
profile.l2_learn,
profile.unkn_mc_fld.pmsks.l2,
profile.unkn_mc_fld.pmsks.ip,
profile.unkn_mc_fld.pmsks.ip6);
}
mutex_unlock(&priv->reg_mutex);
return 0;
}
static int rtldsa_vlan_profiles_open(struct inode *inode, struct file *filp)
{
return single_open(filp, rtldsa_vlan_profiles_show, inode->i_private);
}
static const struct file_operations rtldsa_vlan_profiles_fops = {
.owner = THIS_MODULE,
.open = rtldsa_vlan_profiles_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int rtldsa_vlan_table_raw_show(struct seq_file *m, void *v)
{
struct rtl838x_switch_priv *priv = m->private;
struct rtl838x_vlan_info info;
if (!priv->r->vlan_tables_read)
return -ENOTSUPP;
mutex_lock(&priv->reg_mutex);
seq_printf(m, "VID: profile-index untagged-ports member-ports\n");
for (int i = 0; i < MAX_VLANS; i++) {
priv->r->vlan_tables_read(i, &info);
if (!info.member_ports)
continue;
seq_printf(m, "%i: %2i 0x%016llx 0x%016llx\n", i,
info.profile_id,
info.untagged_ports,
info.member_ports);
}
mutex_unlock(&priv->reg_mutex);
return 0;
}
static int rtldsa_vlan_table_raw_open(struct inode *inode, struct file *filp)
{
return single_open(filp, rtldsa_vlan_table_raw_show, inode->i_private);
}
static const struct file_operations rtldsa_vlan_table_raw_fops = {
.owner = THIS_MODULE,
.open = rtldsa_vlan_table_raw_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int rtldsa_vlan_table_show(struct seq_file *m, void *v)
{
struct rtl838x_switch_priv *priv = m->private;
struct rtl838x_vlan_info info;
if (!priv->r->vlan_tables_read)
return -ENOTSUPP;
mutex_lock(&priv->reg_mutex);
for (int i = 0; i < MAX_VLANS; i++) {
priv->r->vlan_tables_read(i, &info);
if (!info.member_ports)
continue;
seq_printf(m, "%i: %i |", i, info.profile_id);
for (int j = 0; j < sizeof(info.member_ports)*8; j++)
if (info.member_ports & BIT_ULL(j))
seq_printf(m, " %i%s", j,
(info.untagged_ports & BIT_ULL(j)) ? "" : "t");
seq_printf(m, "\n");
}
mutex_unlock(&priv->reg_mutex);
return 0;
}
static int rtldsa_vlan_table_open(struct inode *inode, struct file *filp)
{
return single_open(filp, rtldsa_vlan_table_show, inode->i_private);
}
static const struct file_operations rtldsa_vlan_table_fops = {
.owner = THIS_MODULE,
.open = rtldsa_vlan_table_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static ssize_t age_out_read(struct file *filp, char __user *buffer, size_t count,
loff_t *ppos)
{
@ -695,6 +918,21 @@ void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv)
debugfs_create_file("l2_table", 0400, rtl838x_dir, priv, &l2_table_fops);
debugfs_create_file("port_masks_table_raw", 0400, rtl838x_dir, priv,
&rtldsa_pmsks_table_raw_fops);
debugfs_create_file("port_masks_table", 0400, rtl838x_dir, priv,
&rtldsa_pmsks_table_fops);
debugfs_create_file("vlan_profiles", 0400, rtl838x_dir, priv,
&rtldsa_vlan_profiles_fops);
debugfs_create_file("vlan_table_raw", 0400, rtl838x_dir, priv,
&rtldsa_vlan_table_raw_fops);
debugfs_create_file("vlan_table", 0400, rtl838x_dir, priv,
&rtldsa_vlan_table_fops);
return;
err:
rtl838x_dbgfs_cleanup(priv);
@ -714,4 +952,19 @@ void rtl930x_dbgfs_init(struct rtl838x_switch_priv *priv)
debugfs_create_file("drop_counters", 0400, dbg_dir, priv, &drop_counter_fops);
debugfs_create_file("l2_table", 0400, dbg_dir, priv, &l2_table_fops);
debugfs_create_file("port_masks_table_raw", 0400, dbg_dir, priv,
&rtldsa_pmsks_table_raw_fops);
debugfs_create_file("port_masks_table", 0400, dbg_dir, priv,
&rtldsa_pmsks_table_fops);
debugfs_create_file("vlan_profiles", 0400, dbg_dir, priv,
&rtldsa_vlan_profiles_fops);
debugfs_create_file("vlan_table_raw", 0400, dbg_dir, priv,
&rtldsa_vlan_table_raw_fops);
debugfs_create_file("vlan_table", 0400, dbg_dir, priv,
&rtldsa_vlan_table_fops);
}

View file

@ -454,8 +454,7 @@ static void rtldsa_vlan_setup(struct rtl838x_switch_priv *priv)
priv->r->vlan_profile_setup(0);
priv->r->vlan_profile_setup(1);
dev_info(priv->dev, "MC_PMASK_ALL_PORTS: %016llx\n", priv->r->read_mcast_pmask(MC_PMASK_ALL_PORTS_IDX));
priv->r->vlan_profile_dump(0);
priv->r->vlan_profile_dump(priv, 0);
info.fid = 0; /* Default Forwarding ID / MSTI */
info.hash_uc_fid = false; /* Do not build the L2 lookup hash with FID, but VID */

View file

@ -490,6 +490,29 @@ static void rtl838x_write_mcast_pmask(int idx, u64 portmask)
rtl_table_release(q);
}
static int
rtldsa_838x_vlan_profile_get(int idx, struct rtldsa_vlan_profile *profile)
{
u32 p;
if (idx < 0 || idx > RTL838X_VLAN_PROFILE_MAX)
return -EINVAL;
p = sw_r32(RTL838X_VLAN_PROFILE(idx));
*profile = (struct rtldsa_vlan_profile) {
.l2_learn = RTL838X_VLAN_L2_LEARN_EN_R(p),
.unkn_mc_fld.pmsks_idx = {
.l2 = RTL838X_VLAN_L2_UNKN_MC_FLD_PMSK(p),
.ip = RTL838X_VLAN_IP4_UNKN_MC_FLD_PMSK(p),
.ip6 = RTL838X_VLAN_IP6_UNKN_MC_FLD_PMSK(p),
},
.pmsk_is_idx = 1,
};
return 0;
}
static void rtl838x_vlan_profile_setup(int profile)
{
u32 p = RTL838X_VLAN_L2_LEARN_EN(1) |
@ -1683,6 +1706,20 @@ static void rtl838x_set_receive_management_action(int port, rma_ctrl_t type, act
}
}
static void
rtldsa_838x_vlan_profile_dump(struct rtl838x_switch_priv *priv, int idx)
{
struct rtldsa_vlan_profile p;
if (rtldsa_838x_vlan_profile_get(idx, &p) < 0)
return;
dev_dbg(priv->dev,
"VLAN profile %d: L2 learning: %d, UNKN L2MC FLD PMSK %d, UNKN IPMC FLD PMSK %d, UNKN IPv6MC FLD PMSK: %d\n", idx,
p.l2_learn, p.unkn_mc_fld.pmsks_idx.l2,
p.unkn_mc_fld.pmsks_idx.ip, p.unkn_mc_fld.pmsks_idx.ip6);
}
const struct rtldsa_config rtldsa_838x_cfg = {
.mask_port_reg_be = rtl838x_mask_port_reg,
.set_port_reg_be = rtl838x_set_port_reg,
@ -1721,7 +1758,8 @@ const struct rtldsa_config rtldsa_838x_cfg = {
.vlan_set_tagged = rtl838x_vlan_set_tagged,
.vlan_set_untagged = rtl838x_vlan_set_untagged,
.mac_force_mode_ctrl = rtl838x_mac_force_mode_ctrl,
.vlan_profile_dump = rtl838x_vlan_profile_dump,
.vlan_profile_get = rtldsa_838x_vlan_profile_get,
.vlan_profile_dump = rtldsa_838x_vlan_profile_dump,
.vlan_profile_setup = rtl838x_vlan_profile_setup,
.vlan_fwd_on_inner = rtl838x_vlan_fwd_on_inner,
.set_vlan_igr_filter = rtl838x_set_igr_filter,
@ -1794,20 +1832,3 @@ irqreturn_t rtl838x_switch_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
void rtl838x_vlan_profile_dump(int profile)
{
u32 p;
if (profile < 0 || profile > RTL838X_VLAN_PROFILE_MAX)
return;
p = sw_r32(RTL838X_VLAN_PROFILE(profile));
pr_debug("VLAN profile %d: L2 learning: %d, UNKN L2MC FLD PMSK %d, UNKN IPMC FLD PMSK %d, UNKN IPv6MC FLD PMSK: %d\n",
profile, RTL838X_VLAN_L2_LEARN_EN_R(p),
RTL838X_VLAN_L2_UNKN_MC_FLD_PMSK(p),
RTL838X_VLAN_IP4_UNKN_MC_FLD_PMSK(p),
RTL838X_VLAN_IP6_UNKN_MC_FLD_PMSK(p));
}

View file

@ -914,6 +914,26 @@ struct rtldsa_mst {
struct kref refcount;
};
struct rtldsa_vlan_profile {
union {
struct {
u64 l2;
u64 ip;
u64 ip6;
} pmsks;
struct {
u16 l2;
u16 ip;
u16 ip6;
} pmsks_idx;
} unkn_mc_fld;
int l2_learn;
u8 pmsk_is_idx:1, routing_ipuc:1, routing_ip6uc:1,
routing_ipmc:1, routing_ip6mc:1, bridge_ipmc:1, bridge_ip6mc:1;
};
enum l2_entry_type {
L2_INVALID = 0,
L2_UNICAST = 1,
@ -1279,7 +1299,8 @@ struct rtldsa_config {
void (*vlan_tables_read)(u32 vlan, struct rtl838x_vlan_info *info);
void (*vlan_set_tagged)(u32 vlan, struct rtl838x_vlan_info *info);
void (*vlan_set_untagged)(u32 vlan, u64 portmask);
void (*vlan_profile_dump)(int index);
int (*vlan_profile_get)(int index, struct rtldsa_vlan_profile *profile);
void (*vlan_profile_dump)(struct rtl838x_switch_priv *priv, int index);
void (*vlan_profile_setup)(int profile);
void (*vlan_port_pvidmode_set)(int port, enum pbvlan_type type, enum pbvlan_mode mode);
void (*vlan_port_pvid_set)(int port, enum pbvlan_type type, int pvid);

View file

@ -519,6 +519,30 @@ static void rtl839x_write_mcast_pmask(int idx, u64 portmask)
rtl_table_release(q);
}
static int
rtldsa_839x_vlan_profile_get(int idx, struct rtldsa_vlan_profile *profile)
{
u32 p[2];
if (idx < 0 || idx > RTL839X_VLAN_PROFILE_MAX)
return -EINVAL;
p[0] = sw_r32(RTL839X_VLAN_PROFILE(idx));
p[1] = sw_r32(RTL839X_VLAN_PROFILE(idx) + 4);
*profile = (struct rtldsa_vlan_profile) {
.l2_learn = RTL839X_VLAN_L2_LEARN_EN_R(p),
.unkn_mc_fld.pmsks_idx = {
.l2 = RTL839X_VLAN_L2_UNKN_MC_FLD_PMSK(p),
.ip = RTL839X_VLAN_IP4_UNKN_MC_FLD_PMSK(p),
.ip6 = RTL839X_VLAN_IP6_UNKN_MC_FLD_PMSK(p),
},
.pmsk_is_idx = 1,
};
return 0;
}
static void rtl839x_vlan_profile_setup(int profile)
{
u32 p[2] = { 0, 0 };
@ -626,22 +650,21 @@ irqreturn_t rtl839x_switch_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
void rtl839x_vlan_profile_dump(int profile)
static void
rtldsa_839x_vlan_profile_dump(struct rtl838x_switch_priv *priv, int idx)
{
u32 p[2];
struct rtldsa_vlan_profile p;
if (profile < 0 || profile > RTL839X_VLAN_PROFILE_MAX)
if (rtldsa_839x_vlan_profile_get(idx, &p) < 0)
return;
p[0] = sw_r32(RTL839X_VLAN_PROFILE(profile));
p[1] = sw_r32(RTL839X_VLAN_PROFILE(profile) + 4);
pr_debug("VLAN profile %d: L2 learning: %d, UNKN L2MC FLD PMSK %d, UNKN IPMC FLD PMSK %d, UNKN IPv6MC FLD PMSK: %d\n",
profile, RTL839X_VLAN_L2_LEARN_EN_R(p),
RTL839X_VLAN_L2_UNKN_MC_FLD_PMSK(p),
RTL839X_VLAN_IP4_UNKN_MC_FLD_PMSK(p),
RTL839X_VLAN_IP6_UNKN_MC_FLD_PMSK(p));
pr_debug("VLAN profile %d: raw %08x, %08x\n", profile, p[0], p[1]);
dev_dbg(priv->dev,
"VLAN profile %d: L2 learning: %d, UNKN L2MC FLD PMSK %d, UNKN IPMC FLD PMSK %d, UNKN IPv6MC FLD PMSK: %d\n"
"VLAN profile %d: raw %08x, %08x\n", idx,
p.l2_learn, p.unkn_mc_fld.pmsks_idx.l2,
p.unkn_mc_fld.pmsks_idx.ip, p.unkn_mc_fld.pmsks_idx.ip6, idx,
sw_r32(RTL839X_VLAN_PROFILE(idx)),
sw_r32(RTL839X_VLAN_PROFILE(idx) + 4));
}
static int rtldsa_839x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, int port, u32 port_state[])
@ -1660,7 +1683,8 @@ const struct rtldsa_config rtldsa_839x_cfg = {
.vlan_tables_read = rtl839x_vlan_tables_read,
.vlan_set_tagged = rtl839x_vlan_set_tagged,
.vlan_set_untagged = rtl839x_vlan_set_untagged,
.vlan_profile_dump = rtl839x_vlan_profile_dump,
.vlan_profile_get = rtldsa_839x_vlan_profile_get,
.vlan_profile_dump = rtldsa_839x_vlan_profile_dump,
.vlan_profile_setup = rtl839x_vlan_profile_setup,
.vlan_fwd_on_inner = rtl839x_vlan_fwd_on_inner,
.vlan_port_keep_tag_set = rtl839x_vlan_port_keep_tag_set,

View file

@ -157,13 +157,11 @@ int rtl838x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate
/* RTL838x-specific */
u32 rtl838x_hash(struct rtl838x_switch_priv *priv, u64 seed);
irqreturn_t rtl838x_switch_irq(int irq, void *dev_id);
void rtl838x_vlan_profile_dump(int index);
void rtldsa_838x_print_matrix(void);
/* RTL839x-specific */
u32 rtl839x_hash(struct rtl838x_switch_priv *priv, u64 seed);
irqreturn_t rtl839x_switch_irq(int irq, void *dev_id);
void rtl839x_vlan_profile_dump(int index);
void rtl839x_exec_tbl2_cmd(u32 cmd);
void rtldsa_839x_print_matrix(void);
@ -171,7 +169,6 @@ void rtldsa_839x_print_matrix(void);
u32 rtl930x_hash(struct rtl838x_switch_priv *priv, u64 seed);
irqreturn_t rtldsa_930x_switch_irq(int irq, void *dev_id);
irqreturn_t rtl839x_switch_irq(int irq, void *dev_id);
void rtl930x_vlan_profile_dump(int index);
void rtldsa_930x_print_matrix(void);
/* RTL931x-specific */

View file

@ -306,31 +306,59 @@ static void rtl930x_vlan_set_tagged(u32 vlan, struct rtl838x_vlan_info *info)
rtl_table_release(r);
}
void rtl930x_vlan_profile_dump(int profile)
static int
rtldsa_930x_vlan_profile_get(int idx, struct rtldsa_vlan_profile *profile)
{
u32 p[5];
if (profile < 0 || profile > RTL930X_VLAN_PROFILE_MAX)
if (idx < 0 || idx > RTL930X_VLAN_PROFILE_MAX)
return -EINVAL;
for (int i = 0; i < 5; i++)
p[i] = sw_r32(RTL930X_VLAN_PROFILE_SET(idx) + i * 4);
*profile = (struct rtldsa_vlan_profile) {
.l2_learn = RTL930X_VLAN_L2_LEARN_EN_R(p),
.unkn_mc_fld.pmsks = {
.l2 = RTL930X_VLAN_L2_UNKN_MC_FLD_PMSK(p),
.ip = RTL930X_VLAN_IP4_UNKN_MC_FLD_PMSK(p),
.ip6 = RTL930X_VLAN_IP6_UNKN_MC_FLD_PMSK(p),
},
.pmsk_is_idx = 0,
.routing_ipuc = p[0] & BIT(17),
.routing_ip6uc = p[0] & BIT(16),
.routing_ipmc = p[0] & BIT(13),
.routing_ip6mc = p[0] & BIT(12),
.bridge_ipmc = p[0] & BIT(15),
.bridge_ip6mc = p[0] & BIT(14),
};
return 0;
}
static void
rtldsa_930x_vlan_profile_dump(struct rtl838x_switch_priv *priv, int idx)
{
struct rtldsa_vlan_profile p;
if (rtldsa_930x_vlan_profile_get(idx, &p) < 0)
return;
p[0] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile));
p[1] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 4);
p[2] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 8);
p[3] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 12);
p[4] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 16);
pr_debug("VLAN %d: L2 learn: %d; Unknown MC PMasks: L2 %0lx, IPv4 %0lx, IPv6: %0lx",
profile, RTL930X_VLAN_L2_LEARN_EN_R(p),
RTL930X_VLAN_L2_UNKN_MC_FLD_PMSK(p),
RTL930X_VLAN_IP4_UNKN_MC_FLD_PMSK(p),
RTL930X_VLAN_IP6_UNKN_MC_FLD_PMSK(p));
pr_debug(" Routing enabled: IPv4 UC %c, IPv6 UC %c, IPv4 MC %c, IPv6 MC %c\n",
p[0] & BIT(17) ? 'y' : 'n', p[0] & BIT(16) ? 'y' : 'n',
p[0] & BIT(13) ? 'y' : 'n', p[0] & BIT(12) ? 'y' : 'n');
pr_debug(" Bridge enabled: IPv4 MC %c, IPv6 MC %c,\n",
p[0] & BIT(15) ? 'y' : 'n', p[0] & BIT(14) ? 'y' : 'n');
pr_debug("VLAN profile %d: raw %08x %08x %08x %08x %08x\n",
profile, p[0], p[1], p[2], p[3], p[4]);
dev_dbg(priv->dev,
"VLAN %d: L2 learn: %d; Unknown MC PMasks: L2 %llx, IPv4 %llx, IPv6: %llx\n"
" Routing enabled: IPv4 UC %c, IPv6 UC %c, IPv4 MC %c, IPv6 MC %c\n"
" Bridge enabled: IPv4 MC %c, IPv6 MC %c\n"
"VLAN profile %d: raw %08x %08x %08x %08x %08x\n",
idx, p.l2_learn, p.unkn_mc_fld.pmsks.l2,
p.unkn_mc_fld.pmsks.ip, p.unkn_mc_fld.pmsks.ip6,
p.routing_ipuc ? 'y' : 'n', p.routing_ip6uc ? 'y' : 'n',
p.routing_ipmc ? 'y' : 'n', p.routing_ip6mc ? 'y' : 'n',
p.bridge_ipmc ? 'y' : 'n', p.bridge_ip6mc ? 'y' : 'n', idx,
sw_r32(RTL930X_VLAN_PROFILE_SET(idx)),
sw_r32(RTL930X_VLAN_PROFILE_SET(idx) + 4),
sw_r32(RTL930X_VLAN_PROFILE_SET(idx) + 8) & 0x1FFFFFFF,
sw_r32(RTL930X_VLAN_PROFILE_SET(idx) + 12) & 0x1FFFFFFF,
sw_r32(RTL930X_VLAN_PROFILE_SET(idx) + 16) & 0x1FFFFFFF);
}
static void rtl930x_vlan_set_untagged(u32 vlan, u64 portmask)
@ -2654,7 +2682,8 @@ const struct rtldsa_config rtldsa_930x_cfg = {
.vlan_tables_read = rtl930x_vlan_tables_read,
.vlan_set_tagged = rtl930x_vlan_set_tagged,
.vlan_set_untagged = rtl930x_vlan_set_untagged,
.vlan_profile_dump = rtl930x_vlan_profile_dump,
.vlan_profile_get = rtldsa_930x_vlan_profile_get,
.vlan_profile_dump = rtldsa_930x_vlan_profile_dump,
.vlan_profile_setup = rtl930x_vlan_profile_setup,
.vlan_fwd_on_inner = rtl930x_vlan_fwd_on_inner,
.set_vlan_igr_filter = rtl930x_set_igr_filter,

View file

@ -132,26 +132,41 @@ inline int rtl931x_tbl_access_data_0(int i)
return RTL931X_TBL_ACCESS_DATA_0(i);
}
static void rtl931x_vlan_profile_dump(int index)
static int
rtldsa_931x_vlan_profile_get(int idx, struct rtldsa_vlan_profile *profile)
{
u32 p[7];
if (index < 0 || index > RTL931X_VLAN_PROFILE_MAX)
if (idx < 0 || idx > RTL931X_VLAN_PROFILE_MAX)
return -EINVAL;
for (int i = 0; i < 7; i++)
p[i] = sw_r32(RTL931X_VLAN_PROFILE_SET(idx) + i * 4);
*profile = (struct rtldsa_vlan_profile) {
.l2_learn = RTL931X_VLAN_L2_LEARN_EN_R(p),
.unkn_mc_fld.pmsks = {
.l2 = RTL931X_VLAN_L2_UNKN_MC_FLD_PMSK(p),
.ip = RTL931X_VLAN_IP4_UNKN_MC_FLD_PMSK(p),
.ip6 = RTL931X_VLAN_IP6_UNKN_MC_FLD_PMSK(p),
},
};
return 0;
}
static void
rtldsa_931x_vlan_profile_dump(struct rtl838x_switch_priv *priv, int idx)
{
struct rtldsa_vlan_profile p;
if (rtldsa_931x_vlan_profile_get(idx, &p) < 0)
return;
p[0] = sw_r32(RTL931X_VLAN_PROFILE_SET(index));
p[1] = sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 4);
p[2] = sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 8);
p[3] = sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 12);
p[4] = sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 16);
p[5] = sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 20);
p[6] = sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 24);
pr_debug("VLAN %d: L2 learning: %d, L2 Unknown MultiCast Field %llx, IPv4 Unknown MultiCast Field %llx, IPv6 Unknown MultiCast Field: %llx\n",
index, RTL931X_VLAN_L2_LEARN_EN_R(p),
RTL931X_VLAN_L2_UNKN_MC_FLD_PMSK(p),
RTL931X_VLAN_IP4_UNKN_MC_FLD_PMSK(p),
RTL931X_VLAN_IP6_UNKN_MC_FLD_PMSK(p));
dev_dbg(priv->dev,
"VLAN %d: L2 learning: %d, L2 Unknown MultiCast Field %llx, IPv4 Unknown MultiCast Field %llx, IPv6 Unknown MultiCast Field: %llx\n",
idx, p.l2_learn, p.unkn_mc_fld.pmsks.l2,
p.unkn_mc_fld.pmsks.ip, p.unkn_mc_fld.pmsks.ip6);
}
static int rtldsa_931x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, int port, u32 port_state[])
@ -1810,7 +1825,8 @@ const struct rtldsa_config rtldsa_931x_cfg = {
.vlan_tables_read = rtl931x_vlan_tables_read,
.vlan_set_tagged = rtl931x_vlan_set_tagged,
.vlan_set_untagged = rtl931x_vlan_set_untagged,
.vlan_profile_dump = rtl931x_vlan_profile_dump,
.vlan_profile_get = rtldsa_931x_vlan_profile_get,
.vlan_profile_dump = rtldsa_931x_vlan_profile_dump,
.vlan_profile_setup = rtl931x_vlan_profile_setup,
.vlan_fwd_on_inner = rtl931x_vlan_fwd_on_inner,
.stp_get = rtldsa_931x_stp_get,