From 48b242733a47a3e4e0b528b28df5006005cc3680 Mon Sep 17 00:00:00 2001 From: Jonas Jelonek Date: Thu, 30 Apr 2026 09:13:11 +0000 Subject: [PATCH] realtek: add support for Zyxel XGS1930-28HP Add support for the RTL9301-based Zyxel XGS1930-28HP, a 28-port Gigabit PoE+ switch. The XGS1930 is an EOL Zyxel series of RTL9301-based switches available with 28 or 52 ports, with and without PoE. Hardware ======== - RTL9301 SoC - 512 MiB DDR3 RAM - 32 MiB SPI-NOR flash - 24x 10/100/1000M RJ45 ports - 4x 1G/10G SFP+ cages - PoE: - 802.3af/at on all 24 RJ45 ports - 375 W total power budget - RTL8231 for port LEDs - Front LEDs: PWR, SYS, CLOUD, LOCATOR, PoE usage bar (5 steps) - Buttons: 1x "Restore" - Console: TTL 3.3V, 115200 8N1, 4-pin header - pinout (front to back): GND RX TX - - Software chain: - Bootbase/stripped-down U-Boot - RAS/ZyNOS MAC address =========== Single MAC address derived from the board partition. Applied to all switch ports. Disclaimer ========== PoE is not yet supported. Flashing OpenWrt overwrites ZyNOS. The Bootbase/U-Boot remains intact and can be used for recovery. Installation ============ Simple web upgrade: 1. Take the OpenWrt factory.bin image generated by the build. 2. In the ZyNOS web UI, login and go to Maintenance -> Firmware Upgrade. 3. If the device runs ZyNOS 5.00, untick "Enhanced firmware integrity check sha256sum". Otherwise the upload check will reject the image. 4. Select and upload the factory.bin image and click upgrade. 5. After flashing has finished, reboot the switch. It will now boot into OpenWrt. Initramfs boot ============== Luckily the switch uses a standard design, thus networking works with a default hardware profile of RTK U-boot. 1. Connect to the serial console and interrupt the boot process by spamming '$' during the DRAM test to drop into Bootbase/U-Boot. 2. Bring up the network: > rtk network on Use a copper port; the SFP+ cages are likely not usable from the bootloader. 3. Load the initramfs image via TFTP: > tftpboot 0x82000000 : 4. Run the image (not bootm, the image has no uImage header): > go 0x82000000 Return to stock firmware ======================== 1. Download the stock firmware for the switch from the Zyxel website and unzip it; there should be a .bin file with an alphanumeric name. 2. Upload that file to the running OpenWrt instance. 3. Flash it (use -F since the image has no OpenWrt metadata): > sysupgrade -F .bin 4. Wait for sysupgrade to finish and the switch to reboot. ZyNOS should come up again. Signed-off-by: Jonas Jelonek Link: https://github.com/openwrt/openwrt/pull/23389 Signed-off-by: Robert Marko --- .../base-files/lib/upgrade/platform.sh | 1 + .../dts/rtl9301_zyxel_xgs1930-28hp.dts | 427 ++++++++++++++++++ target/linux/realtek/image/rtl930x.mk | 11 + 3 files changed, 439 insertions(+) create mode 100644 target/linux/realtek/dts/rtl9301_zyxel_xgs1930-28hp.dts diff --git a/target/linux/realtek/base-files/lib/upgrade/platform.sh b/target/linux/realtek/base-files/lib/upgrade/platform.sh index cddf5315b75..549f96d70d2 100644 --- a/target/linux/realtek/base-files/lib/upgrade/platform.sh +++ b/target/linux/realtek/base-files/lib/upgrade/platform.sh @@ -44,6 +44,7 @@ platform_do_upgrade() { linksys,lgs352c) nand_do_upgrade "$1" ;; + zyxel,xgs1930-28hp|\ zyxel,xmg1915-10e|\ zyxel,xmg1915-10ep|\ zyxel,xs1930-10|\ diff --git a/target/linux/realtek/dts/rtl9301_zyxel_xgs1930-28hp.dts b/target/linux/realtek/dts/rtl9301_zyxel_xgs1930-28hp.dts new file mode 100644 index 00000000000..13aef60a06b --- /dev/null +++ b/target/linux/realtek/dts/rtl9301_zyxel_xgs1930-28hp.dts @@ -0,0 +1,427 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later or MIT) +/dts-v1/; + +#include +#include +#include + +#include "rtl930x.dtsi" + +/ { + compatible = "zyxel,xgs1930-28hp", "realtek,rtl9301-soc"; + model = "Zyxel XGS1930-28HP"; + + aliases { + label-mac-device = ðernet0; + led-boot = &led_sys_green; + led-running = &led_sys_green; + led-failsafe = &led_sys_red; + led-upgrade = &led_sys_green; + }; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x10000000>, /* 256 MiB lowmem */ + <0x20000000 0x10000000>; /* 256 MiB highmem */ + }; + + led_set@0 { + compatible = "realtek,rtl9300-leds"; + active-low; + + led_set0 = ; + led_set1 = <(RTL93XX_LED_SET_10G | RTL93XX_LED_SET_LINK | RTL93XX_LED_SET_ACT) + (RTL93XX_LED_SET_1G | RTL93XX_LED_SET_LINK | RTL93XX_LED_SET_ACT)>; + }; + + leds { + compatible = "gpio-leds"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_disable_sys_led>; + + led-0 { + color = ; + function = LED_FUNCTION_POWER; + gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + led-1 { + color = ; + function = LED_FUNCTION_POWER; + gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + led_sys_green: led-2 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + }; + + led_sys_red: led-3 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + }; + + led-4 { /* PoE usage - bar 1 (from bottom) */ + color = ; + function = "poe-usage"; + function-enumerator = <1>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; + }; + + led-5 { /* PoE usage - bar 2 */ + color = ; + function = "poe-usage"; + function-enumerator = <2>; + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; + }; + + led-6 { /* PoE usage - bar 3 */ + color = ; + function = "poe-usage"; + function-enumerator = <3>; + gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; + }; + + led-7 { /* PoE usage - bar 4 */ + color = ; + function = "poe-usage"; + function-enumerator = <4>; + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + }; + + led-8 { /* PoE usage - bar 5 */ + color = ; + function = "poe-usage"; + function-enumerator = <5>; + gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + }; + + led-9 { /* Locator */ + color = ; + function = "locator"; + gpios = <&gpio1 35 GPIO_ACTIVE_HIGH>; + }; + + led-10 { /* Cloud (amber) */ + color = ; + function = "cloud"; + gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + }; + + led-11 { /* Cloud (green) */ + color = ; + function = "cloud"; + gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; + }; + }; + + fan0: gpio-fan { + compatible = "gpio-fan"; + gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>; + + gpio-fan,speed-map = + <0 0>, /* slow - GPIO LOW */ + <1 1>; /* fast - GPIO HIGH */ + #cooling-cells = <2>; + }; + + keys { + compatible = "gpio-keys"; + + restore { + label = "restore"; + gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + sfp0: sfp-p25 { + compatible = "sff,sfp"; + i2c-bus = <&i2c4>; + mod-def0-gpio = <&gpio1 1 GPIO_ACTIVE_LOW>; + tx-disable-gpio = <&gpio1 29 GPIO_ACTIVE_HIGH>; + tx-fault-gpio = <&gpio1 25 GPIO_ACTIVE_HIGH>; + los-gpio = <&gpio1 21 GPIO_ACTIVE_HIGH>; + }; + sfp1: sfp-p26 { + compatible = "sff,sfp"; + i2c-bus = <&i2c5>; + mod-def0-gpio = <&gpio1 2 GPIO_ACTIVE_LOW>; + tx-disable-gpio = <&gpio1 30 GPIO_ACTIVE_HIGH>; + tx-fault-gpio = <&gpio1 26 GPIO_ACTIVE_HIGH>; + los-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>; + }; + sfp2: sfp-p27 { + compatible = "sff,sfp"; + i2c-bus = <&i2c6>; + mod-def0-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>; + tx-disable-gpio = <&gpio1 31 GPIO_ACTIVE_HIGH>; + tx-fault-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>; + los-gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>; + }; + sfp3: sfp-p28 { + compatible = "sff,sfp"; + i2c-bus = <&i2c7>; + mod-def0-gpio = <&gpio1 11 GPIO_ACTIVE_LOW>; + tx-disable-gpio = <&gpio1 32 GPIO_ACTIVE_HIGH>; + tx-fault-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>; + los-gpio = <&gpio1 24 GPIO_ACTIVE_HIGH>; + }; +}; + +&gpio0 { + sfp_enable_hog { + gpio-hog; + gpios = <7 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "sfp-enable"; + }; + + poe_mcu_enable_hog { + gpio-hog; + gpios = <19 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "poe-mcu-enable"; + }; +}; + +&i2c_mst1 { + status = "okay"; + + i2c0: i2c@0 { + reg = <0>; + /* PoE MCU sits here at 0x20 */ + }; +}; + +&i2c_mst2 { + status = "okay"; + + i2c4: i2c@4 { + reg = <4>; + }; + i2c5: i2c@5 { + reg = <5>; + }; + i2c6: i2c@6 { + reg = <6>; + }; + i2c7: i2c@7 { + reg = <7>; + }; +}; + +&mdio_aux { + status = "okay"; + + gpio1: gpio@0 { + compatible = "realtek,rtl8231"; + reg = <0>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&gpio1 0 0 37>; + + led-controller { + compatible = "realtek,rtl8231-leds"; + status = "disabled"; + }; + + poe_enable_hog { + gpio-hog; + gpios = <12 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "poe-enable"; + }; + }; +}; + +/* + * GPIO 4 on RTL8231 is the global reset shared by all PHYs across all + * MDIO busses. It is intentionally not declared as reset-gpios on any + * bus: the MDIO driver / phylink only support a reset GPIO per bus, not + * on the parent controller. Attaching it to a single bus would still + * reset the PHYs on the other busses as a side effect, leaving their + * software state out of sync with the hardware and likely breaking them. + */ + +&mdio_bus0 { + PHY_C22(0, 0) + PHY_C22(1, 1) + PHY_C22(2, 2) + PHY_C22(3, 3) + PHY_C22(4, 4) + PHY_C22(5, 5) + PHY_C22(6, 6) + PHY_C22(7, 7) +}; + +&mdio_bus1 { + PHY_C22(8, 8) + PHY_C22(9, 9) + PHY_C22(10, 10) + PHY_C22(11, 11) + PHY_C22(12, 12) + PHY_C22(13, 13) + PHY_C22(14, 14) + PHY_C22(15, 15) +}; + +&mdio_bus2 { + PHY_C22(16, 16) + PHY_C22(17, 17) + PHY_C22(18, 18) + PHY_C22(19, 19) + PHY_C22(20, 20) + PHY_C22(21, 21) + PHY_C22(22, 22) + PHY_C22(23, 23) +}; + +&spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "BootBase"; + reg = <0x0 0x80000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + factory_macaddr: macaddr@7fff8 { + reg = <0x7fff8 0x6>; + }; + }; + }; + + /* DbgArea */ + partition@80000 { + label = "reserved"; + reg = <0x80000 0x20000>; + read-only; + }; + + partition@a0000 { + label = "RomDir2"; + reg = <0xa0000 0x120000>; + read-only; + + /* boot image index at offset 0x151 */ + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + boot_selector: boot-selector@151 { + reg = <0x151 0x1>; + }; + }; + }; + + partition@1c0000 { + label = "reserved"; + reg = <0x1c0000 0xa0000>; + read-only; + }; + + /* BootBase has dual-image support. Second partition starts at + * 0x1260000 and has same layout as first partition but smaller size + */ + partition@260000 { + reg = <0x260000 0x1da0000>; + label = "factory"; + + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "loader"; + reg = <0x0 0x10000>; + }; + + partition@10000 { + label = "firmware"; + reg = <0x10000 0x1d90000>; + compatible = "openwrt,uimage", "denx,uimage"; + }; + }; + }; + }; +}; + +&switch0 { + ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + + SWITCH_PORT_LED(0, 1, 0, 0, qsgmii) + SWITCH_PORT_LED(1, 2, 0, 0, qsgmii) + SWITCH_PORT_LED(2, 3, 0, 0, qsgmii) + SWITCH_PORT_LED(3, 4, 0, 0, qsgmii) + SWITCH_PORT_LED(4, 5, 1, 0, qsgmii) + SWITCH_PORT_LED(5, 6, 1, 0, qsgmii) + SWITCH_PORT_LED(6, 7, 1, 0, qsgmii) + SWITCH_PORT_LED(7, 8, 1, 0, qsgmii) + + SWITCH_PORT_LED(8, 9, 2, 0, usxgmii) + SWITCH_PORT_LED(9, 10, 2, 0, usxgmii) + SWITCH_PORT_LED(10, 11, 2, 0, usxgmii) + SWITCH_PORT_LED(11, 12, 2, 0, usxgmii) + SWITCH_PORT_LED(12, 13, 2, 0, usxgmii) + SWITCH_PORT_LED(13, 14, 2, 0, usxgmii) + SWITCH_PORT_LED(14, 15, 2, 0, usxgmii) + SWITCH_PORT_LED(15, 16, 2, 0, usxgmii) + + SWITCH_PORT_LED(16, 17, 3, 0, usxgmii) + SWITCH_PORT_LED(17, 18, 3, 0, usxgmii) + SWITCH_PORT_LED(18, 19, 3, 0, usxgmii) + SWITCH_PORT_LED(19, 20, 3, 0, usxgmii) + SWITCH_PORT_LED(20, 21, 3, 0, usxgmii) + SWITCH_PORT_LED(21, 22, 3, 0, usxgmii) + SWITCH_PORT_LED(22, 23, 3, 0, usxgmii) + SWITCH_PORT_LED(23, 24, 3, 0, usxgmii) + + SWITCH_PORT_SFP(24, 25, 4, 1, 0) + SWITCH_PORT_SFP(25, 26, 6, 1, 1) + SWITCH_PORT_SFP(26, 27, 8, 1, 2) + SWITCH_PORT_SFP(27, 28, 9, 1, 3) + + port@28 { + reg = <28>; + ethernet = <ðernet0>; + phy-mode = "internal"; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; +}; + +ðernet0 { + nvmem-cells = <&factory_macaddr>; + nvmem-cell-names = "mac-address"; +}; diff --git a/target/linux/realtek/image/rtl930x.mk b/target/linux/realtek/image/rtl930x.mk index 36fe61111e4..acf8a2582d8 100644 --- a/target/linux/realtek/image/rtl930x.mk +++ b/target/linux/realtek/image/rtl930x.mk @@ -253,6 +253,17 @@ define Device/zyxel_xgs1250-12-b1 endef TARGET_DEVICES += zyxel_xgs1250-12-b1 +define Device/zyxel_xgs1930-28hp + SOC := rtl9301 + DEVICE_MODEL := XGS1930-28HP + DEVICE_PACKAGES := kmod-hwmon-gpiofan + FLASH_ADDR := 0xb4260000 + IMAGE_SIZE := 30336k + ZYNFW_ALIGN := 0x10000 + $(Device/zyxel_zynos) +endef +TARGET_DEVICES += zyxel_xgs1930-28hp + define Device/zyxel_xmg1915 SOC := rtl9302 FLASH_ADDR := 0xb4270000