[openwrt/openwrt] realtek: rtl930x: Allow to overwrite LED portmask

LEDE Commits lede-commits at lists.infradead.org
Mon Oct 6 15:15:47 PDT 2025


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/ebb79d0f846a957b3046825ed644b8b936451431

commit ebb79d0f846a957b3046825ed644b8b936451431
Author: Harshal Gohel <hg at simonwunderlich.de>
AuthorDate: Fri Jul 11 14:50:37 2025 +0000

    realtek: rtl930x: Allow to overwrite LED portmask
    
    There are switches which share the same overall hardware design but remove
    just a couple of components for the low cost variant. For example, a 8+2
    (ethernet+SFP) switch might have a low cost variant which only has 8
    ethernet ports. In this case, the PCB will be shared but components for SFP
    will just be dropped.
    
    The LED shift registers will be the same between the two switches but the
    ports are different. But since the rtl930x_led_init code is trying to
    calculate the number of LEDs using the LED ports, the ethernet status ports
    will then suddenly be shifted by two ports.
    
    It is therefore necessary to have a mechanism to overwrite the detection of
    the ethernet ports in the LED initialization and force some ports to
    "virtually there" for the LED controller.
    
    Signed-off-by: Harshal Gohel <hg at simonwunderlich.de>
    Co-developed-by: Sven Eckelmann <se at simonwunderlich.de>
    Signed-off-by: Sven Eckelmann <se at simonwunderlich.de>
    Link: https://github.com/openwrt/openwrt/pull/20300
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl930x.c   | 31 +++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

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));
 




More information about the lede-commits mailing list