diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c index b9639a6b3b..0a83a0624c 100644 --- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c +++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c @@ -2339,10 +2339,33 @@ static void rtl930x_set_distribution_algorithm(int group, int algoidx, u32 algom sw_w32(newmask << l3shift, RTL930X_TRK_HASH_CTRL + (algoidx << 2)); } +static void rtldsa_930x_led_get_forced(const struct device_node *node, + const u8 leds_in_set[4], + u8 forced_leds_per_port[RTL930X_CPU_PORT]) +{ + DECLARE_BITMAP(mask, RTL930X_CPU_PORT); + unsigned int port; + char set_str[36]; + u32 pm; + + for (u8 set = 0; set < 4; set++) { + snprintf(set_str, sizeof(set_str), "realtek,led-set%d-force-port-mask", set); + if (of_property_read_u32(node, set_str, &pm)) + continue; + + bitmap_from_arr32(mask, &pm, RTL930X_CPU_PORT); + + for_each_set_bit(port, mask, RTL930X_CPU_PORT) + forced_leds_per_port[port] = leds_in_set[set]; + } +} + static void rtl930x_led_init(struct rtl838x_switch_priv *priv) { + u8 forced_leds_per_port[RTL930X_CPU_PORT] = {}; struct device_node *node; struct device *dev = priv->dev; + u8 leds_in_set[4] = {}; u32 pm = 0; node = of_find_compatible_node(NULL, NULL, "realtek,rtl9300-leds"); @@ -2377,6 +2400,7 @@ static void rtl930x_led_init(struct rtl838x_switch_priv *priv) continue; } dev_info(dev, "%s has %d LEDs configured\n", set_name, leds_in_this_set); + leds_in_set[set] = leds_in_this_set; if (of_property_read_u32_array(node, set_name, set_config, leds_in_this_set)) { break; @@ -2390,6 +2414,8 @@ static void rtl930x_led_init(struct rtl838x_switch_priv *priv) } } + rtldsa_930x_led_get_forced(node, leds_in_set, forced_leds_per_port); + for (int i = 0; i < priv->cpu_port; i++) { int pos = (i << 1) % 32; u32 set; @@ -2397,9 +2423,12 @@ static void rtl930x_led_init(struct rtl838x_switch_priv *priv) sw_w32_mask(0x3 << pos, 0, RTL930X_LED_PORT_FIB_SET_SEL_CTRL(i)); sw_w32_mask(0x3 << pos, 0, RTL930X_LED_PORT_COPR_SET_SEL_CTRL(i)); - if (!priv->ports[i].phy) + if (!priv->ports[i].phy && !(forced_leds_per_port[i])) continue; + if (forced_leds_per_port[i] > 0) + priv->ports[i].leds_on_this_port = forced_leds_per_port[i]; + /* 0x0 = 1 led, 0x1 = 2 leds, 0x2 = 3 leds, 0x3 = 4 leds per port */ sw_w32_mask(0x3 << pos, (priv->ports[i].leds_on_this_port -1) << pos, RTL930X_LED_PORT_NUM_CTRL(i));