realtek: Setup all VLANs with default configurations
authorBirger Koblitz <git@birger-koblitz.de>
Sat, 1 May 2021 14:36:32 +0000 (16:36 +0200)
committerPetr Štetiar <ynezz@true.cz>
Fri, 7 May 2021 05:05:16 +0000 (07:05 +0200)
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 <git@birger-koblitz.de>
target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c
target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.c
target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.h
target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c
target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl930x.c

index 1e902a1d7aaee9fc84941637673ab071e9184032..40130c287a333476e35f25a2a9ad1572597cbf42 100644 (file)
@@ -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);
index b31b1ae6baf71e67aebe95d7a86cb8c41c4f182d..9ecd189d91d07ab81ac029d3a32d2797e756ddc5 100644 (file)
@@ -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,
index 35d5b1702a256fcf4d70f5398b951a37ed127bc6..5990b6453aaac31a1060ef1fd4cbd86bb616bd83 100644 (file)
 #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 {
index 825655cd544c9a1418c333350a88bb98b3a1c211..bf2e3d39808e20f530e63ca572a2718e07d86f3c 100644 (file)
@@ -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,
index a6e5cb763fd3d8df1395bffe856aa81ca123af66..a80a6d89b29edf5699b7de8a252f03db59088c31 100644 (file)
@@ -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,