]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: central unlock for RTL838x write protection
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Tue, 10 Feb 2026 07:40:49 +0000 (08:40 +0100)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 1 Mar 2026 01:02:29 +0000 (02:02 +0100)
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@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/21956
Signed-off-by: Robert Marko <robimarko@gmail.com>
(cherry picked from commit 8bf37836d62f001562c78238f41f4d05a31d606a)
Manually resolved merge conflicts of prom.c
Signed-off-by: Goetz Goerisch <ggoerisch@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/22087
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/realtek/files-6.12/arch/mips/rtl838x/prom.c
target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.c
target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c

index 2e668ee0785a4493297b0781b2b7d208b9316375..a409d9b0dc1680a6b38fc8c74b4f93dddbb43890 100644 (file)
@@ -76,6 +76,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)) {
@@ -106,7 +113,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);
@@ -167,6 +173,7 @@ static u32 __init read_model(void)
        if ((id >= 0x8380 && id <= 0x8382) || id == 0x8330 || id == 0x8332) {
                soc_info.id = id;
                soc_info.family = RTL8380_FAMILY_ID;
+               apply_early_quirks();
                rtl838x_read_details(model);
                return model;
        }
@@ -176,6 +183,7 @@ static u32 __init read_model(void)
        if ((id >= 0x8391 && id <= 0x8396) || (id >= 0x8351 && id <= 0x8353)) {
                soc_info.id = id;
                soc_info.family = RTL8390_FAMILY_ID;
+               apply_early_quirks();
                rtl839x_read_details(model);
                return model;
        }
@@ -185,11 +193,13 @@ static u32 __init read_model(void)
        if (id >= 0x9301 && id <= 0x9303) {
                soc_info.id = id;
                soc_info.family = RTL9300_FAMILY_ID;
+               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;
+               apply_early_quirks();
                rtl93xx_read_details(model);
                return model;
        }
index 728190d66729acf17b6bed29236635e19ef33b43..661d0285ab93a9aeb1ff82a6a60fa1e0c3cb9685 100644 (file)
@@ -1489,10 +1489,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);
index cc1adeeec6d68fbf600eea1cd7e136873d13ea5f..9147ba1572c1014b24a882a933d351be87022df1 100644 (file)
@@ -58,7 +58,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
 
@@ -527,9 +526,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 */