diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/debugfs.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/debugfs.c index 7e6918df20..00f2642624 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/debugfs.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/debugfs.c @@ -631,9 +631,9 @@ void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv) debugfs_create_x32("ctrl", 0644, mirror_dir, (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_CTRL + i * 4)); debugfs_create_x32("ingress_pm", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + priv->r->mir_spm + i * 4)); + (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_SPM_CTRL + i * 4)); debugfs_create_x32("egress_pm", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + priv->r->mir_dpm + i * 4)); + (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_DPM_CTRL + i * 4)); debugfs_create_x32("qid", 0644, mirror_dir, (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_QID_CTRL(i))); debugfs_create_x32("rspan_vlan", 0644, mirror_dir, @@ -650,9 +650,9 @@ void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv) debugfs_create_x32("ctrl", 0644, mirror_dir, (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_CTRL + i * 4)); debugfs_create_x64("ingress_pm", 0644, mirror_dir, - (u64 *)(RTL838X_SW_BASE + priv->r->mir_spm + i * 8)); + (u64 *)(RTL838X_SW_BASE + RTL839X_MIR_SPM_CTRL + i * 8)); debugfs_create_x64("egress_pm", 0644, mirror_dir, - (u64 *)(RTL838X_SW_BASE + priv->r->mir_dpm + i * 8)); + (u64 *)(RTL838X_SW_BASE + RTL839X_MIR_DPM_CTRL + i * 8)); debugfs_create_x32("rspan_vlan", 0644, mirror_dir, (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_RSPAN_VLAN_CTRL(i))); debugfs_create_x32("rspan_tx", 0644, mirror_dir, diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c index eee3479aea..288e5361e4 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/dsa.c @@ -2269,17 +2269,25 @@ out: return err; } -static int rtl83xx_port_mirror_add(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror, - bool ingress, struct netlink_ext_ack *extack) +static int rtldsa_port_mirror_add(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror, + bool ingress, struct netlink_ext_ack *extack) { /* We support 4 mirror groups, one destination port per group */ - int group; struct rtl838x_switch_priv *priv = ds->priv; - int ctrl_reg, dpm_reg, spm_reg; + struct rtldsa_mirror_config config; + int err = 0; + int pm_reg; + int group; + int r; + + if (!priv->r->get_mirror_config) + return -EOPNOTSUPP; pr_debug("In %s\n", __func__); + mutex_lock(&priv->reg_mutex); + for (group = 0; group < 4; group++) { if (priv->mirror_group_ports[group] == mirror->to_local_port) break; @@ -2291,77 +2299,80 @@ static int rtl83xx_port_mirror_add(struct dsa_switch *ds, int port, } } - if (group >= 4) - return -ENOSPC; - - ctrl_reg = priv->r->mir_ctrl + group * 4; - dpm_reg = priv->r->mir_dpm + group * 4 * priv->port_width; - spm_reg = priv->r->mir_spm + group * 4 * priv->port_width; + if (group >= 4) { + err = -ENOSPC; + goto out_unlock; + } pr_debug("Using group %d\n", group); - mutex_lock(&priv->reg_mutex); - if (priv->family_id == RTL8380_FAMILY_ID) { - /* Enable mirroring to port across VLANs (bit 11) */ - sw_w32(1 << 11 | (mirror->to_local_port << 4) | 1, ctrl_reg); - } else { - /* Enable mirroring to destination port */ - sw_w32((mirror->to_local_port << 4) | 1, ctrl_reg); - } - - if (ingress && (priv->r->get_port_reg_be(spm_reg) & (1ULL << port))) { - mutex_unlock(&priv->reg_mutex); - return -EEXIST; - } - if ((!ingress) && (priv->r->get_port_reg_be(dpm_reg) & (1ULL << port))) { - mutex_unlock(&priv->reg_mutex); - return -EEXIST; + r = priv->r->get_mirror_config(&config, group, mirror->to_local_port); + if (r < 0) { + err = r; + goto out_unlock; } if (ingress) - priv->r->mask_port_reg_be(0, 1ULL << port, spm_reg); + pm_reg = config.spm; else - priv->r->mask_port_reg_be(0, 1ULL << port, dpm_reg); + pm_reg = config.dpm; + sw_w32(config.val, config.ctrl); + + if (priv->r->get_port_reg_be(pm_reg) & (1ULL << port)) { + err = -EEXIST; + goto out_unlock; + } + + priv->r->mask_port_reg_be(0, 1ULL << port, pm_reg); priv->mirror_group_ports[group] = mirror->to_local_port; + +out_unlock: mutex_unlock(&priv->reg_mutex); - return 0; + return err; } -static void rtl83xx_port_mirror_del(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror) +static void rtldsa_port_mirror_del(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror) { - int group = 0; struct rtl838x_switch_priv *priv = ds->priv; - int ctrl_reg, dpm_reg, spm_reg; + struct rtldsa_mirror_config config; + int group = 0; + int r; + + if (!priv->r->get_mirror_config) + return; pr_debug("In %s\n", __func__); + + mutex_lock(&priv->reg_mutex); + for (group = 0; group < 4; group++) { if (priv->mirror_group_ports[group] == mirror->to_local_port) break; } if (group >= 4) - return; + goto out_unlock; - ctrl_reg = priv->r->mir_ctrl + group * 4; - dpm_reg = priv->r->mir_dpm + group * 4 * priv->port_width; - spm_reg = priv->r->mir_spm + group * 4 * priv->port_width; + r = priv->r->get_mirror_config(&config, group, mirror->to_local_port); + if (r < 0) + goto out_unlock; - mutex_lock(&priv->reg_mutex); if (mirror->ingress) { /* Ingress, clear source port matrix */ - priv->r->mask_port_reg_be(1ULL << port, 0, spm_reg); + priv->r->mask_port_reg_be(1ULL << port, 0, config.spm); } else { /* Egress, clear destination port matrix */ - priv->r->mask_port_reg_be(1ULL << port, 0, dpm_reg); + priv->r->mask_port_reg_be(1ULL << port, 0, config.dpm); } - if (!(sw_r32(spm_reg) || sw_r32(dpm_reg))) { + if (!(sw_r32(config.spm) || sw_r32(config.dpm))) { priv->mirror_group_ports[group] = -1; - sw_w32(0, ctrl_reg); + sw_w32(0, config.ctrl); } +out_unlock: mutex_unlock(&priv->reg_mutex); } @@ -2579,8 +2590,8 @@ const struct dsa_switch_ops rtl83xx_switch_ops = { .port_mdb_add = rtl83xx_port_mdb_add, .port_mdb_del = rtl83xx_port_mdb_del, - .port_mirror_add = rtl83xx_port_mirror_add, - .port_mirror_del = rtl83xx_port_mirror_del, + .port_mirror_add = rtldsa_port_mirror_add, + .port_mirror_del = rtldsa_port_mirror_del, .port_lag_change = rtl83xx_port_lag_change, .port_lag_join = rtl83xx_port_lag_join, diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c index 92bb3e9512..a76558c6d5 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c @@ -261,6 +261,23 @@ static inline int rtl838x_l2_port_new_sa_fwd(int p) return RTL838X_L2_PORT_NEW_SA_FWD(p); } +static int rtldsa_838x_get_mirror_config(struct rtldsa_mirror_config *config, + int group, int port) +{ + config->ctrl = RTL838X_MIR_CTRL + group * 4; + config->spm = RTL838X_MIR_SPM_CTRL + group * 4; + config->dpm = RTL838X_MIR_DPM_CTRL + group * 4; + + /* Enable mirroring to destination port */ + config->val = BIT(0); + config->val |= port << 4; + + /* Enable mirroring to port across VLANs */ + config->val |= BIT(11); + + return 0; +} + inline static int rtl838x_trk_mbr_ctr(int group) { return RTL838X_TRK_MBR_CTR + (group << 2); @@ -1698,9 +1715,7 @@ const struct rtl838x_reg rtl838x_reg = { .mac_port_ctrl = rtl838x_mac_port_ctrl, .l2_port_new_salrn = rtl838x_l2_port_new_salrn, .l2_port_new_sa_fwd = rtl838x_l2_port_new_sa_fwd, - .mir_ctrl = RTL838X_MIR_CTRL, - .mir_dpm = RTL838X_MIR_DPM_CTRL, - .mir_spm = RTL838X_MIR_SPM_CTRL, + .get_mirror_config = rtldsa_838x_get_mirror_config, .read_l2_entry_using_hash = rtl838x_read_l2_entry_using_hash, .write_l2_entry_using_hash = rtl838x_write_l2_entry_using_hash, .read_cam = rtl838x_read_cam, diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h index 469246f0f8..01f83d7271 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h @@ -997,6 +997,23 @@ struct rtl83xx_route { struct rtl93xx_route_attr attr; }; +/** + * struct rtldsa_mirror_config - Mirror configuration for specific group and port + */ +struct rtldsa_mirror_config { + /** @ctrl: control register for mirroring group */ + int ctrl; + + /** @spm: register for the destination port members */ + int spm; + + /** @dpm: register for the source port members */ + int dpm; + + /** @val: @ctrl register settings to enable mirroring */ + u32 val; +}; + struct rtl838x_reg { void (*mask_port_reg_be)(u64 clear, u64 set, int reg); void (*set_port_reg_be)(u64 set, int reg); @@ -1047,9 +1064,7 @@ struct rtl838x_reg { int (*l2_port_new_salrn)(int port); int (*l2_port_new_sa_fwd)(int port); int (*set_ageing_time)(unsigned long msec); - int mir_ctrl; - int mir_dpm; - int mir_spm; + int (*get_mirror_config)(struct rtldsa_mirror_config *config, int group, int port); u64 (*read_l2_entry_using_hash)(u32 hash, u32 position, struct rtl838x_l2_entry *e); void (*write_l2_entry_using_hash)(u32 hash, u32 pos, struct rtl838x_l2_entry *e); u64 (*read_cam)(int idx, struct rtl838x_l2_entry *e); diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c index 9a325b396b..2745f4f339 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl839x.c @@ -293,6 +293,20 @@ static inline int rtl839x_l2_port_new_sa_fwd(int p) return RTL839X_L2_PORT_NEW_SA_FWD(p); } +static int rtldsa_839x_get_mirror_config(struct rtldsa_mirror_config *config, + int group, int port) +{ + config->ctrl = RTL839X_MIR_CTRL + group * 4; + config->spm = RTL839X_MIR_SPM_CTRL + group * 8; + config->dpm = RTL839X_MIR_DPM_CTRL + group * 8; + + /* Enable mirroring to destination port */ + config->val = BIT(0); + config->val |= port << 4; + + return 0; +} + static inline int rtl839x_trk_mbr_ctr(int group) { return RTL839X_TRK_MBR_CTR + (group << 3); @@ -1678,9 +1692,7 @@ const struct rtl838x_reg rtl839x_reg = { .mac_port_ctrl = rtl839x_mac_port_ctrl, .l2_port_new_salrn = rtl839x_l2_port_new_salrn, .l2_port_new_sa_fwd = rtl839x_l2_port_new_sa_fwd, - .mir_ctrl = RTL839X_MIR_CTRL, - .mir_dpm = RTL839X_MIR_DPM_CTRL, - .mir_spm = RTL839X_MIR_SPM_CTRL, + .get_mirror_config = rtldsa_839x_get_mirror_config, .read_l2_entry_using_hash = rtl839x_read_l2_entry_using_hash, .write_l2_entry_using_hash = rtl839x_write_l2_entry_using_hash, .read_cam = rtl839x_read_cam, diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c index 0ac7709248..5ca29e56b1 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c @@ -2446,9 +2446,6 @@ const struct rtl838x_reg rtl930x_reg = { .mac_port_ctrl = rtl930x_mac_port_ctrl, .l2_port_new_salrn = rtl930x_l2_port_new_salrn, .l2_port_new_sa_fwd = rtl930x_l2_port_new_sa_fwd, - .mir_ctrl = RTL930X_MIR_CTRL, - .mir_dpm = RTL930X_MIR_DPM_CTRL, - .mir_spm = RTL930X_MIR_SPM_CTRL, .read_l2_entry_using_hash = rtl930x_read_l2_entry_using_hash, .write_l2_entry_using_hash = rtl930x_write_l2_entry_using_hash, .read_cam = rtl930x_read_cam, diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c index 28602151c0..54f2dc9720 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c @@ -1561,9 +1561,6 @@ const struct rtl838x_reg rtl931x_reg = { .mac_port_ctrl = rtl931x_mac_port_ctrl, .l2_port_new_salrn = rtl931x_l2_port_new_salrn, .l2_port_new_sa_fwd = rtl931x_l2_port_new_sa_fwd, - .mir_ctrl = RTL931X_MIR_CTRL, - .mir_dpm = RTL931X_MIR_DPM_CTRL, - .mir_spm = RTL931X_MIR_SPM_CTRL, .read_l2_entry_using_hash = rtl931x_read_l2_entry_using_hash, .write_l2_entry_using_hash = rtl931x_write_l2_entry_using_hash, .read_cam = rtl931x_read_cam,