[openwrt/openwrt] realtek: Configure initial L2 learning setup

LEDE Commits lede-commits at lists.infradead.org
Fri Oct 8 23:26:24 PDT 2021


blogic pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/28e972b2ea2f55a593defcbd2dc21710cce648c7

commit 28e972b2ea2f55a593defcbd2dc21710cce648c7
Author: Birger Koblitz <git at birger-koblitz.de>
AuthorDate: Wed Sep 8 20:00:31 2021 +0200

    realtek: Configure initial L2 learning setup
    
    Configure a sane L2 learning configuration upon DSA driver load so that the
    switch can start learning L2 addresses. Also configure the correct flood masks
    for broadcast and unknown unicast traffice.
    
    Signed-off-by: Birger Koblitz <git at birger-koblitz.de>
---
 .../realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c  |  4 ++++
 .../files-5.10/drivers/net/dsa/rtl83xx/rtl838x.c      | 19 +++++++++++++++++++
 .../files-5.10/drivers/net/dsa/rtl83xx/rtl838x.h      | 12 ++++++++++++
 .../files-5.10/drivers/net/dsa/rtl83xx/rtl839x.c      | 15 +++++++++++++++
 .../files-5.10/drivers/net/dsa/rtl83xx/rtl930x.c      | 14 +++++++++++++-
 5 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
index 3a0806e70a..8ed0e45bb9 100644
--- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
+++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
@@ -184,6 +184,8 @@ static int rtl83xx_setup(struct dsa_switch *ds)
 
 	ds->configure_vlan_while_not_filtering = true;
 
+	priv->r->l2_learning_setup();
+
 	/* Enable MAC Polling PHY again */
 	rtl83xx_enable_phy_polling(priv);
 	pr_debug("Please wait until PHY is settled\n");
@@ -228,6 +230,8 @@ static int rtl930x_setup(struct dsa_switch *ds)
 
 	ds->configure_vlan_while_not_filtering = true;
 
+	priv->r->l2_learning_setup();
+
 	rtl83xx_enable_phy_polling(priv);
 
 	priv->r->pie_init(priv);
diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.c b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.c
index 2d24eaa337..15a486d724 100644
--- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.c
+++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.c
@@ -491,6 +491,24 @@ static void rtl838x_vlan_profile_setup(int profile)
 	rtl838x_write_mcast_pmask(UNKNOWN_MC_PMASK, 0x1fffffff);
 }
 
+static void rtl838x_l2_learning_setup(void)
+{
+	/* Set portmask for broadcast traffic and unknown unicast address flooding
+	 * to the reserved entry in the portmask table used also for
+	 * multicast flooding */
+	sw_w32(UNKNOWN_MC_PMASK << 12 | UNKNOWN_MC_PMASK, RTL838X_L2_FLD_PMSK);
+
+	/* Enable learning constraint system-wide (bit 0), per-port (bit 1)
+	 * and per vlan (bit 2) */
+	sw_w32(0x7, RTL838X_L2_LRN_CONSTRT_EN);
+
+	// Limit learning to maximum: 16k entries, after that just flood (bits 0-1)
+	sw_w32((0x3fff << 2) | 0, RTL838X_L2_LRN_CONSTRT);
+
+	// Do not trap ARP packets to CPU_PORT
+	sw_w32(0, RTL838X_SPCL_TRAP_ARP_CTRL);
+}
+
 static inline int rtl838x_vlan_port_egr_filter(int port)
 {
 	return RTL838X_VLAN_PORT_EGR_FLTR;
@@ -1605,6 +1623,7 @@ const struct rtl838x_reg rtl838x_reg = {
 	.pie_rule_write = rtl838x_pie_rule_write,
 	.pie_rule_add = rtl838x_pie_rule_add,
 	.pie_rule_rm = rtl838x_pie_rule_rm,
+	.l2_learning_setup = rtl838x_l2_learning_setup,
 	.packet_cntr_read = rtl838x_packet_cntr_read,
 	.packet_cntr_clear = rtl838x_packet_cntr_clear,
 };
diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.h
index e695879da1..6ff59c4348 100644
--- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.h
+++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.h
@@ -198,6 +198,15 @@
 #define RTL930X_L2_TBL_FLUSH_CTRL		(0x9404)
 #define RTL931X_L2_TBL_FLUSH_CTRL		(0xCD9C)
 
+#define RTL838X_L2_LRN_CONSTRT			(0x329C)
+#define RTL839X_L2_LRN_CONSTRT			(0x3910)
+#define RTL930X_L2_LRN_CONSTRT_CTRL		(0x909c)
+#define RTL838X_L2_FLD_PMSK			(0x3288)
+#define RTL839X_L2_FLD_PMSK			(0x38EC)
+#define RTL930X_L2_BC_FLD_PMSK			(0x9068)
+#define RTL930X_L2_UNKN_UC_FLD_PMSK		(0x9064)
+#define RTL838X_L2_LRN_CONSTRT_EN		(0x3368)
+
 #define RTL838X_L2_PORT_NEW_SALRN(p)		(0x328c + (((p >> 4) << 2)))
 #define RTL839X_L2_PORT_NEW_SALRN(p)		(0x38F0 + (((p >> 4) << 2)))
 #define RTL930X_L2_PORT_SALRN(p)		(0x8FEC + (((p >> 4) << 2)))
@@ -303,6 +312,8 @@
 /* 802.1X */
 #define RTL838X_SPCL_TRAP_EAPOL_CTRL		(0x6988)
 #define RTL839X_SPCL_TRAP_EAPOL_CTRL		(0x105C)
+#define RTL838X_SPCL_TRAP_ARP_CTRL		(0x698C)
+#define RTL839X_SPCL_TRAP_ARP_CTRL		(0x1060)
 
 /* QoS */
 #define RTL838X_QM_INTPRI2QID_CTRL		(0x5F00)
@@ -699,6 +710,7 @@ struct rtl838x_reg {
 	int (*pie_rule_write)(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr);
 	int (*pie_rule_add)(struct rtl838x_switch_priv *priv, struct pie_rule *rule);
 	void (*pie_rule_rm)(struct rtl838x_switch_priv *priv, struct pie_rule *rule);
+	void (*l2_learning_setup)(void);
 	u32 (*packet_cntr_read)(int counter);
 	void (*packet_cntr_clear)(int counter);
 };
diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl839x.c
index 8faf6c07e9..4ed2184efa 100644
--- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl839x.c
+++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl839x.c
@@ -542,6 +542,20 @@ void rtl839x_traffic_disable(int source, int dest)
 	rtl839x_mask_port_reg_be(BIT_ULL(dest), 0, rtl839x_port_iso_ctrl(source));
 }
 
+static void rtl839x_l2_learning_setup(void)
+{
+	/* Set portmask for broadcast (offset bit 12) and unknown unicast (offset 0)
+	 * address flooding to the reserved entry in the portmask table used
+	 * also for multicast flooding */
+	sw_w32(UNKNOWN_MC_PMASK << 12 | UNKNOWN_MC_PMASK, RTL839X_L2_FLD_PMSK);
+
+	// Limit learning to maximum: 32k entries, after that just flood (bits 0-1)
+	sw_w32((0x7fff << 2) | 0, RTL839X_L2_LRN_CONSTRT);
+
+	// Do not trap ARP packets to CPU_PORT
+	sw_w32(0, RTL839X_SPCL_TRAP_ARP_CTRL);
+}
+
 irqreturn_t rtl839x_switch_irq(int irq, void *dev_id)
 {
 	struct dsa_switch *ds = dev_id;
@@ -1677,6 +1691,7 @@ const struct rtl838x_reg rtl839x_reg = {
 	.pie_rule_write = rtl839x_pie_rule_write,
 	.pie_rule_add = rtl839x_pie_rule_add,
 	.pie_rule_rm = rtl839x_pie_rule_rm,
+	.l2_learning_setup = rtl839x_l2_learning_setup,
 	.packet_cntr_read = rtl839x_packet_cntr_read,
 	.packet_cntr_clear = rtl839x_packet_cntr_clear,
 };
diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl930x.c
index 4291954234..aa6306c1c6 100644
--- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl930x.c
+++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl930x.c
@@ -254,7 +254,18 @@ static void rtl930x_vlan_profile_setup(int profile)
 	sw_w32(p[2], RTL930X_VLAN_PROFILE_SET(profile) + 8);
 	sw_w32(p[3], RTL930X_VLAN_PROFILE_SET(profile) + 12);
 	sw_w32(p[4], RTL930X_VLAN_PROFILE_SET(profile) + 16);
-	pr_info("Leaving %s\n", __func__);
+}
+
+static void rtl930x_l2_learning_setup(void)
+{
+	// Portmask for flooding broadcast traffic
+	sw_w32(0x1fffffff, RTL930X_L2_BC_FLD_PMSK);
+
+	// Portmask for flooding unicast traffic with unknown destination
+	sw_w32(0x1fffffff, RTL930X_L2_UNKN_UC_FLD_PMSK);
+
+	// Limit learning to maximum: 32k entries, after that just flood (bits 0-1)
+	sw_w32((0x7fff << 2) | 0, RTL930X_L2_LRN_CONSTRT_CTRL);
 }
 
 static void rtl930x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
@@ -1712,6 +1723,7 @@ const struct rtl838x_reg rtl930x_reg = {
 	.pie_rule_write = rtl930x_pie_rule_write,
 	.pie_rule_add = rtl930x_pie_rule_add,
 	.pie_rule_rm = rtl930x_pie_rule_rm,
+	.l2_learning_setup = rtl930x_l2_learning_setup,
 	.packet_cntr_read = rtl930x_packet_cntr_read,
 	.packet_cntr_clear = rtl930x_packet_cntr_clear,
 };



More information about the lede-commits mailing list