.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)
{
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);
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);
}
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 */
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) |
}
}
+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,
.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,
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));
-}
-
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,
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);
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 };
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[])
.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,
/* 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);
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 */
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)
.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,
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)
- return;
+ 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;
+}
- 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);
+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;
- 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[])
.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,