From 4342d27ec90cd0988fd3e62ccefbe66f2e691372 Mon Sep 17 00:00:00 2001 From: Birger Koblitz Date: Sat, 1 May 2021 16:36:32 +0200 Subject: [PATCH] realtek: Setup all VLANs with default configurations This sets up all VLANs with a default configuration on reset: - forward based on VLAN-ID and not the FID/MSTI - forward based on the inner VLAN-ID (not outer) Signed-off-by: Birger Koblitz --- .../files-5.4/drivers/net/dsa/rtl83xx/dsa.c | 34 +++++++++++++++++++ .../drivers/net/dsa/rtl83xx/rtl838x.c | 11 ++++++ .../drivers/net/dsa/rtl83xx/rtl838x.h | 7 ++++ .../drivers/net/dsa/rtl83xx/rtl839x.c | 11 ++++++ .../drivers/net/dsa/rtl83xx/rtl930x.c | 12 +++++++ 5 files changed, 75 insertions(+) diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c index 1e902a1d7aae..40130c287a33 100644 --- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c +++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c @@ -153,6 +153,36 @@ static enum dsa_tag_protocol rtl83xx_get_tag_protocol(struct dsa_switch *ds, int return DSA_TAG_PROTO_TRAILER; } +/* + * Initialize all VLANS + */ +static void rtl83xx_vlan_setup(struct rtl838x_switch_priv *priv) +{ + struct rtl838x_vlan_info info; + int i; + + pr_info("In %s\n", __func__); + + priv->r->vlan_profile_setup(0); + priv->r->vlan_profile_setup(1); + pr_info("UNKNOWN_MC_PMASK: %016llx\n", priv->r->read_mcast_pmask(UNKNOWN_MC_PMASK)); + priv->r->vlan_profile_dump(0); + + info.fid = 0; // Default Forwarding ID / MSTI + info.hash_uc_fid = false; // Do not build the L2 lookup hash with FID, but VID + info.hash_mc_fid = false; // Do the same for Multicast packets + info.profile_id = 0; // Use default Vlan Profile 0 + info.tagged_ports = 0; // Initially no port members + + // Initialize all vlans 0-4095 + for (i = 0; i < MAX_VLANS; i ++) + priv->r->vlan_set_tagged(i, &info); + + // Set forwarding action based on inner VLAN tag + for (i = 0; i < priv->cpu_port; i++) + priv->r->vlan_fwd_on_inner(i, true); +} + static int rtl83xx_setup(struct dsa_switch *ds) { int i; @@ -188,6 +218,8 @@ static int rtl83xx_setup(struct dsa_switch *ds) rtl83xx_init_stats(priv); + rtl83xx_vlan_setup(priv); + ds->configure_vlan_while_not_filtering = true; /* Enable MAC Polling PHY again */ @@ -228,6 +260,8 @@ static int rtl930x_setup(struct dsa_switch *ds) // TODO: Initialize statistics + rtl83xx_vlan_setup(priv); + ds->configure_vlan_while_not_filtering = true; rtl83xx_enable_phy_polling(priv); diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.c index b31b1ae6baf7..9ecd189d91d0 100644 --- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.c +++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.c @@ -92,6 +92,16 @@ static void rtl838x_vlan_set_untagged(u32 vlan, u64 portmask) rtl_table_release(r); } +/* Sets the L2 forwarding to be based on either the inner VLAN tag or the outer + */ +static void rtl838x_vlan_fwd_on_inner(int port, bool is_set) +{ + if (is_set) + sw_w32_mask(BIT(port), 0, RTL838X_VLAN_PORT_FWD); + else + sw_w32_mask(0, BIT(port), RTL838X_VLAN_PORT_FWD); +} + static inline int rtl838x_mac_force_mode_ctrl(int p) { return RTL838X_MAC_FORCE_MODE_CTRL + (p << 2); @@ -406,6 +416,7 @@ const struct rtl838x_reg rtl838x_reg = { .mac_force_mode_ctrl = rtl838x_mac_force_mode_ctrl, .vlan_profile_dump = rtl838x_vlan_profile_dump, .vlan_profile_setup = rtl838x_vlan_profile_setup, + .vlan_fwd_on_inner = rtl838x_vlan_fwd_on_inner, .stp_get = rtl838x_stp_get, .stp_set = rtl838x_stp_set, .mac_port_ctrl = rtl838x_mac_port_ctrl, diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.h index 35d5b1702a25..5990b6453aaa 100644 --- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.h +++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.h @@ -216,6 +216,12 @@ #define RTL931X_RMA_BPDU_FLD_PMSK (0x8950) #define RTL839X_RMA_BPDU_FLD_PMSK (0x125C) +#define RTL838X_L2_PORT_LM_ACT(p) (0x3208 + ((p) << 2)) +#define RTL838X_VLAN_PORT_FWD (0x3A78) +#define RTL839X_VLAN_PORT_FWD (0x27AC) +#define RTL930X_VLAN_PORT_FWD (0x834C) +#define RTL838X_VLAN_FID_CTRL (0x3aa8) + /* Port Mirroring */ #define RTL838X_MIR_CTRL (0x5D00) #define RTL838X_MIR_DPM_CTRL (0x5D20) @@ -460,6 +466,7 @@ struct rtl838x_reg { struct ethtool_eee *e, int port); u64 (*read_mcast_pmask)(int idx); void (*write_mcast_pmask)(int idx, u64 portmask); + void (*vlan_fwd_on_inner)(int port, bool is_set); }; struct rtl838x_switch_priv { diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c index 825655cd544c..bf2e3d39808e 100644 --- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c +++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c @@ -115,6 +115,16 @@ static void rtl839x_vlan_set_untagged(u32 vlan, u64 portmask) rtl_table_release(r); } +/* Sets the L2 forwarding to be based on either the inner VLAN tag or the outer + */ +static void rtl839x_vlan_fwd_on_inner(int port, bool is_set) +{ + if (is_set) + rtl839x_mask_port_reg_be(BIT_ULL(port), 0ULL, RTL839X_VLAN_PORT_FWD); + else + rtl839x_mask_port_reg_be(0ULL, BIT_ULL(port), RTL839X_VLAN_PORT_FWD); +} + static inline int rtl839x_mac_force_mode_ctrl(int p) { return RTL839X_MAC_FORCE_MODE_CTRL + (p << 2); @@ -669,6 +679,7 @@ const struct rtl838x_reg rtl839x_reg = { .vlan_set_untagged = rtl839x_vlan_set_untagged, .vlan_profile_dump = rtl839x_vlan_profile_dump, .vlan_profile_setup = rtl839x_vlan_profile_setup, + .vlan_fwd_on_inner = rtl839x_vlan_fwd_on_inner, .stp_get = rtl839x_stp_get, .stp_set = rtl839x_stp_set, .mac_force_mode_ctrl = rtl839x_mac_force_mode_ctrl, diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl930x.c index a6e5cb763fd3..a80a6d89b29e 100644 --- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl930x.c +++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl930x.c @@ -132,6 +132,17 @@ static void rtl930x_vlan_set_untagged(u32 vlan, u64 portmask) rtl_table_release(r); } +/* Sets the L2 forwarding to be based on either the inner VLAN tag or the outer + */ +static void rtl930x_vlan_fwd_on_inner(int port, bool is_set) +{ + // Always set all tag modes to fwd based on either inner or outer tag + if (is_set) + sw_w32_mask(0, 0xf, RTL930X_VLAN_PORT_FWD + (port << 2)); + else + sw_w32_mask(0xf, 0, RTL930X_VLAN_PORT_FWD + (port << 2)); +} + static void rtl930x_vlan_profile_setup(int profile) { u32 p[5]; @@ -727,6 +738,7 @@ const struct rtl838x_reg rtl930x_reg = { .vlan_set_untagged = rtl930x_vlan_set_untagged, .vlan_profile_dump = rtl930x_vlan_profile_dump, .vlan_profile_setup = rtl930x_vlan_profile_setup, + .vlan_fwd_on_inner = rtl930x_vlan_fwd_on_inner, .stp_get = rtl930x_stp_get, .stp_set = rtl930x_stp_set, .mac_force_mode_ctrl = rtl930x_mac_force_mode_ctrl, -- 2.30.2