From 254c9ac40bdb93f8b015e42039ca597bc9bde57f Mon Sep 17 00:00:00 2001 From: Harshal Gohel Date: Tue, 15 Jul 2025 19:53:07 +0200 Subject: [PATCH] realtek: rtl931x: Cleanup LED set initialization The LED sets must be configured before per-port LEDs are actually assigned. At the same time, the LED set configuration was basically unreadable and the RTL930x from commit 2cfb1ecf1035 ("rtl930x: Rework per port LED configuration") does a better job. Instead of moving the old implementation around, just adopt the one from RTL930x. Signed-off-by: Harshal Gohel Signed-off-by: Sven Eckelmann Link: https://github.com/openwrt/openwrt/pull/20300 Signed-off-by: Hauke Mehrtens --- .../drivers/net/dsa/rtl83xx/rtl838x.h | 9 +++ .../drivers/net/dsa/rtl83xx/rtl931x.c | 56 +++++++++++++------ 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h index 66b761fdd5..9102442231 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h @@ -584,6 +584,15 @@ typedef enum { #define RTL931X_LED_GLB_ACTIVE_LOW BIT(21) +#define RTL931X_LED_SETX_0_CTRL(x) (RTL931X_LED_SET0_0_CTRL - (x * 8)) +#define RTL931X_LED_SETX_1_CTRL(x) (RTL931X_LED_SETX_0_CTRL(x) - 4) + +/* get register for given set and led in the set */ +#define RTL931X_LED_SETX_LEDY(x,y) (RTL931X_LED_SETX_0_CTRL(x) - 4 * (y / 2)) + +/* get shift for given led in any set */ +#define RTL931X_LED_SET_LEDX_SHIFT(x) (16 * (x % 2)) + #define MAX_VLANS 4096 #define MAX_LAGS 16 #define MAX_PRIOS 8 diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c index 8ac9bcc177..ca2a5ff5d8 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c @@ -1494,6 +1494,45 @@ static void rtldsa_931x_led_init(struct rtl838x_switch_priv *priv) return; } + for (int set = 0; set < 4; set++) { + char set_name[16] = {0}; + u32 set_config[4]; + int leds_in_this_set = 0; + + /* Reset LED set configuration */ + sw_w32(0, RTL931X_LED_SETX_0_CTRL(set)); + sw_w32(0, RTL931X_LED_SETX_1_CTRL(set)); + + /* Each LED set has (up to) 4 LEDs, and each LED is configured + * with 16 bits. So each 32 bit register holds configuration for + * 2 LEDs. Therefore, each set requires 2 registers for + * configuring all 4 LEDs. + */ + snprintf(set_name, sizeof(set_name), "led_set%d", set); + leds_in_this_set = of_property_count_u32_elems(node, set_name); + + if (leds_in_this_set <= 0 || leds_in_this_set > ARRAY_SIZE(set_config)) { + if (leds_in_this_set != -EINVAL) { + dev_err(dev, "%s invalid, skipping this set, leds_in_this_set=%d, should be (0, %d]\n", + set_name, leds_in_this_set, ARRAY_SIZE(set_config)); + } + + continue; + } + + dev_info(dev, "%s has %d LEDs configured\n", set_name, leds_in_this_set); + + if (of_property_read_u32_array(node, set_name, set_config, leds_in_this_set)) + break; + + /* Write configuration for selected LEDs */ + for (int i = 0, led = leds_in_this_set - 1; led >= 0; led--, i++) { + sw_w32_mask(0xffff << RTL931X_LED_SET_LEDX_SHIFT(led), + (0xffff & set_config[i]) << RTL931X_LED_SET_LEDX_SHIFT(led), + RTL931X_LED_SETX_LEDY(set, led)); + } + } + for (int i = 0; i < priv->cpu_port; i++) { int pos = (i << 1) % 32; u32 set; @@ -1518,23 +1557,6 @@ static void rtldsa_931x_led_init(struct rtl838x_switch_priv *priv) sw_w32_mask(0, set << pos, RTL931X_LED_PORT_FIB_SET_SEL_CTRL(i)); } - for (int i = 0; i < 4; i++) { - const __be32 *led_set; - char set_name[9]; - u32 setlen; - u32 v; - - sprintf(set_name, "led_set%d", i); - dev_dbg(dev, ">%s<\n", set_name); - led_set = of_get_property(node, set_name, &setlen); - if (!led_set || setlen != 16) - break; - v = be32_to_cpup(led_set) << 16 | be32_to_cpup(led_set + 1); - sw_w32(v, RTL931X_LED_SET0_0_CTRL - 4 - i * 8); - v = be32_to_cpup(led_set + 2) << 16 | be32_to_cpup(led_set + 3); - sw_w32(v, RTL931X_LED_SET0_0_CTRL - i * 8); - } - /* Set LED mode to serial (0x1) */ sw_w32_mask(0x3, 0x1, RTL931X_LED_GLB_CTRL); -- 2.30.2