[openwrt/openwrt] realtek: central unlock for RTL838x write protection

LEDE Commits lede-commits at lists.infradead.org
Thu Feb 12 07:58:52 PST 2026


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/8bf37836d62f001562c78238f41f4d05a31d606a

commit 8bf37836d62f001562c78238f41f4d05a31d606a
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Tue Feb 10 08:40:49 2026 +0100

    realtek: central unlock for RTL838x write protection
    
    The write protection register (0x1b000058) is opened up in prom init
    but closed later in rtl838x_pie_init(). From that moment no more
    special register writes are possible.
    
    Only unlock the write protection register once during prom init.
    Remove all other references. The error has been active since ages
    but was not visible until pcs refactoring. For reference blame the
    refactoring commit.
    
    Fixes: e956adf ("realtek: rtl838x: setup SDS entirely in PCS driver")
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/21956
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 target/linux/realtek/files-6.12/arch/mips/rtl838x/prom.c     | 12 +++++++++++-
 .../realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c     |  4 +---
 .../linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c  |  4 ----
 3 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/target/linux/realtek/files-6.12/arch/mips/rtl838x/prom.c b/target/linux/realtek/files-6.12/arch/mips/rtl838x/prom.c
index 689e862d27..9258bd5675 100644
--- a/target/linux/realtek/files-6.12/arch/mips/rtl838x/prom.c
+++ b/target/linux/realtek/files-6.12/arch/mips/rtl838x/prom.c
@@ -96,6 +96,13 @@ static int rtlsmp_register(void)
 
 #endif
 
+static void __init apply_early_quirks(void)
+{
+	/* Open up write protected registers. Never mess with this elsewhere */
+	if (soc_info.family == RTL8380_FAMILY_ID)
+		sw_w32(0x3, RTL838X_INT_RW_CTRL);
+}
+
 void __init device_tree_init(void)
 {
 	if (!fdt_check_header(&__appended_dtb)) {
@@ -126,7 +133,6 @@ static void __init rtl838x_read_details(u32 model)
 {
 	u32 chip_info, ext_version, tmp;
 
-	sw_w32(0x3, RTL838X_INT_RW_CTRL);
 	sw_w32(0xa << 28, RTL838X_CHIP_INFO);
 
 	chip_info = sw_r32(RTL838X_CHIP_INFO);
@@ -188,6 +194,7 @@ static u32 __init read_model(void)
 		soc_info.id = id;
 		soc_info.family = RTL8380_FAMILY_ID;
 		soc_info.cpu_port = RTL838X_CPU_PORT;
+		apply_early_quirks();
 		rtl838x_read_details(model);
 		return model;
 	}
@@ -198,6 +205,7 @@ static u32 __init read_model(void)
 		soc_info.id = id;
 		soc_info.family = RTL8390_FAMILY_ID;
 		soc_info.cpu_port = RTL839X_CPU_PORT;
+		apply_early_quirks();
 		rtl839x_read_details(model);
 		return model;
 	}
@@ -208,12 +216,14 @@ static u32 __init read_model(void)
 		soc_info.id = id;
 		soc_info.family = RTL9300_FAMILY_ID;
 		soc_info.cpu_port = RTL930X_CPU_PORT;
+		apply_early_quirks();
 		rtl93xx_read_details(model);
 		return model;
 	} else if (id >= 0x9311 && id <= 0x9313) {
 		soc_info.id = id;
 		soc_info.family = RTL9310_FAMILY_ID;
 		soc_info.cpu_port = RTL931X_CPU_PORT;
+		apply_early_quirks();
 		rtl93xx_read_details(model);
 		return model;
 	}
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 1238217869..87d7579f8f 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
@@ -1496,10 +1496,8 @@ static void rtl838x_pie_init(struct rtl838x_switch_priv *priv)
 	/* Delete all present rules */
 	rtl838x_pie_rule_del(priv, 0, priv->n_pie_blocks * PIE_BLOCK_SIZE - 1);
 
-	/* Routing bypasses source port filter: disable write-protection, first */
-	sw_w32_mask(0, 3, RTL838X_INT_RW_CTRL);
+	/* Routing bypasses source port filter */
 	sw_w32_mask(0, 1, RTL838X_DMY_REG27);
-	sw_w32_mask(3, 0, RTL838X_INT_RW_CTRL);
 
 	/* Enable predefined templates 0, 1 and 2 for even blocks */
 	template_selectors = 0 | (1 << 3) | (2 << 6);
diff --git a/target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c b/target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c
index 33fc8b218f..98d099d1bc 100644
--- a/target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c
+++ b/target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c
@@ -59,7 +59,6 @@
 #define RTPCS_838X_SDS_CFG_REG			0x34
 #define RTPCS_838X_RST_GLB_CTRL_0		0x3c
 #define RTPCS_838X_SDS_MODE_SEL			0x0028
-#define RTPCS_838X_INT_RW_CTRL			0x0058
 #define RTPCS_838X_INT_MODE_CTRL		0x005c
 #define RTPCS_838X_PLL_CML_CTRL			0x0ff8
 
@@ -734,9 +733,6 @@ static int rtpcs_838x_init_serdes_common(struct rtpcs_ctrl *ctrl)
 {
 	dev_dbg(ctrl->dev, "Init RTL838X SerDes common\n");
 
-	/* enable R/W of some protected registers */
-	regmap_write(ctrl->map, RTPCS_838X_INT_RW_CTRL, 0x3);
-
 	/* power off and reset all SerDes */
 	regmap_write(ctrl->map, RTPCS_838X_SDS_CFG_REG, 0x3f);
 	regmap_write(ctrl->map, RTPCS_838X_RST_GLB_CTRL_0, 0x10); /* SW_SERDES_RST */




More information about the lede-commits mailing list