openwrt/target/linux/realtek/image/rtl930x.mk
Jonas Jelonek e4ed8e7fe7
realtek: add support for Ubiquiti UniFi USW Aggregation
Add support for the RTL9303-based Ubiquiti UniFi USW Aggregation, an
8-port 10G SFP+ aggregation switch.

Hardware
========

  - RTL9303 SoC
  - 256 MiB DDR
  - 16 MiB SPI-NOR flash
  - 8x 1G/10G SFP+ cages
  - Per-port LEDs: 1x white LED per SFP+ cage
  - Buttons: 1x Reset
  - Console: TTL 3.3V, 115200 8N1, internal unpopulated 4-hole THT
    footprint (the device must be opened to solder a header)
    - pinout (with the front panel facing you, left to right):
      VCC/unused, RX, TX, GND
  - Front touch display (see below)
  - Software chain:
    - U-Boot (Ubiquiti-flavoured)
    - UniFi OS (OpenWrt-based)

MAC address
===========

Single MAC address derived from the eeprom partition. Applied to all
switch ports.

Front touch display
===================

The unit has a touch-capable front display, driven by a dedicated
STM32-based MCU connected to the host via UART. The MCU runs Ubiquiti's
LCM firmware and exposes a high-level JSON protocol (page selection,
button-press events, etc.); arbitrary pixel-level control is not
possible without replacing the MCU firmware. The display is therefore
not supported beyond what the stock LCM firmware offers.

Disclaimer
==========

Stock uses a dual-bank layout (kernel0/kernel1, 7 MiB each). OpenWrt
replaces both banks with a single contiguous firmware partition.
Flashing OpenWrt overwrites both stock kernel slots; U-Boot remains
intact and can be used for recovery.

The stock firmware blob is RSA-signed and cannot be flashed via the
UniFi web UI. Installation has to be done from a root shell on the
running UniFi OS.

Installation
============

1. Enable SSH on the stock UniFi OS and log in as root.

2. Copy the OpenWrt sysupgrade image to /tmp on the switch (e.g. via
   scp).

3. Adjust IMG below to point at the copied file, then run the block as
   a whole. It writes kernel0, splits into kernel1 if the image is
   larger than that slot (otherwise invalidates kernel1 so U-Boot
   cannot pick a stale bank), and reboots:

   IMG=/tmp/openwrt-realtek-rtl930x-ubnt_usw-aggregation-squashfs-sysupgrade.bin
   K0_BLOCKS=$((0x710000 / 0x10000))

   dd if="$IMG" of=/dev/mtdblock2 bs=64k count=$K0_BLOCKS conv=fsync
   if [ "$(wc -c < "$IMG")" -gt $((0x710000)) ]; then
       dd if="$IMG" of=/dev/mtdblock3 bs=64k skip=$K0_BLOCKS conv=fsync
   else
       dd if=/dev/zero of=/dev/mtdblock3 bs=64k count=1 conv=fsync
   fi
   sync
   reboot

   The switch comes up in OpenWrt after reboot.

It does not matter which bank stock booted from when the dd block
runs: both banks are touched in the same pass (kernel0 written, kernel1
either written or invalidated). With kernel1 invalidated, U-Boot's
internal fallback kicks in and permanently switches to kernel0 on the
next boot, so the device stays on OpenWrt as long as kernel0 is
bootable.

Recovery
========

Since the installation procedure invalidates or partially overwrites
the second bank, recovery requires serial console access (see Hardware
above for pinout).

1. Interrupt U-Boot autoboot by spamming a key during early boot to
   drop into the U-Boot prompt.

2. Bring up networking:

   rtk network on

3. Transfer an OpenWrt initramfs image via TFTP and boot it:

   tftpboot 0x82000000 <server>:<initramfs.bin>
   bootm 0x82000000

4. From the running initramfs OpenWrt, re-run the installation
   procedure above (the dd block, with $IMG pointing at the image on
   /tmp).

Return to stock firmware
========================

There is no fully-supported revert path. The stock firmware blob is a
Ubiquiti UBNT archive (header + parts, see firmware-utils' fw.h) that
embeds a u-boot and a kernel0 uImage payload; only the latter is
relevant when writing back to the kernel partitions.

The snippet below extracts the kernel0 uImage from such a blob by
locating the uImage magic and using the size carried in the uImage
header itself, without parsing any UBNT framing. It is provided as a
best-effort starting point; verify the result before flashing,
otherwise you're on your own:

   BLOB=US.rtl930x_X.Y.Z.bin
   OFF=$(grep -aboF $'\x27\x05\x19\x56' "$BLOB" | head -1 | cut -d: -f1)
   SIZE=$(( $(dd if="$BLOB" bs=1 skip=$((OFF + 12)) count=4 2>/dev/null \
               | hexdump -e '1/4 "%u"') + 64 ))
   dd if="$BLOB" of=kernel0.uImage bs=1 skip="$OFF" count="$SIZE"

Once you have a clean uImage, write it to both kernel banks (since
the bootselect mechanism is not yet decoded, this guarantees U-Boot
picks the stock image regardless of bank):

   dd if=kernel0.uImage of=/dev/mtdblock2 bs=64k conv=fsync
   dd if=kernel0.uImage of=/dev/mtdblock3 bs=64k conv=fsync

Link: https://github.com/openwrt/openwrt/pull/23506
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-24 19:32:31 +02:00

299 lines
7.0 KiB
Makefile

# SPDX-License-Identifier: GPL-2.0-only
include ./common.mk
define Device/d-link_dgs-1250-28x
SOC := rtl9301
DEVICE_VENDOR := D-Link
DEVICE_MODEL := DGS-1250-28X
DEVICE_PACKAGES += kmod-hwmon-lm75
IMAGE_SIZE := 24576k
$(Device/kernel-lzma)
endef
TARGET_DEVICES += d-link_dgs-1250-28x
define Device/hasivo_s1100w-8xgt-se
SOC := rtl9303
DEVICE_VENDOR := Hasivo
DEVICE_MODEL := S1100W-8XGT-SE
IMAGE_SIZE := 12288k
DEVICE_PACKAGES := rtl8264b-firmware
$(Device/kernel-lzma)
endef
TARGET_DEVICES += hasivo_s1100w-8xgt-se
define Device/hasivo_s1100wp-8gt-se
SOC := rtl9303
DEVICE_VENDOR := Hasivo
DEVICE_MODEL := S1100WP-8GT-SE
IMAGE_SIZE := 12288k
$(Device/kernel-lzma)
endef
TARGET_DEVICES += hasivo_s1100wp-8gt-se
define Device/hasivo_s600wp-5gt-2sx-se
SOC := rtl9303
DEVICE_VENDOR := Hasivo
DEVICE_MODEL := S600WP-5GT-2SX-SE
IMAGE_SIZE := 12288k
$(Device/kernel-lzma)
endef
TARGET_DEVICES += hasivo_s600wp-5gt-2sx-se
define Device/plasmacloud-common
SOC := rtl9302
UIMAGE_MAGIC := 0x93000000
DEVICE_VENDOR := Plasma Cloud
DEVICE_PACKAGES := poemgr
IMAGE_SIZE := 15872k
BLOCKSIZE := 64k
KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | uImage lzma
KERNEL := kernel-bin | append-dtb | lzma | uImage lzma | pad-to $$(BLOCKSIZE)
IMAGES += factory.bin
IMAGE/factory.bin := append-kernel | append-rootfs | pad-rootfs | check-size
IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata
endef
define Device/plasmacloud_mcx3
$(Device/plasmacloud-common)
DEVICE_MODEL := MCX3
endef
TARGET_DEVICES += plasmacloud_mcx3
define Device/plasmacloud_psx8
$(Device/plasmacloud-common)
DEVICE_MODEL := PSX8
endef
TARGET_DEVICES += plasmacloud_psx8
define Device/plasmacloud_psx10
$(Device/plasmacloud-common)
DEVICE_MODEL := PSX10
endef
TARGET_DEVICES += plasmacloud_psx10
define Device/tplink_tl-st1008f-v2
SOC := rtl9303
UIMAGE_MAGIC := 0x93030000
DEVICE_VENDOR := TP-Link
DEVICE_MODEL := TL-ST1008F
DEVICE_VARIANT := v2.0
DEVICE_PACKAGES := kmod-gpio-pca953x
SUPPORTED_DEVICES += tplink,tl-st1008f,v2
IMAGE_SIZE := 31808k
$(Device/kernel-lzma)
endef
TARGET_DEVICES += tplink_tl-st1008f-v2
define Device/ubnt_usw-aggregation
SOC := rtl9303
DEVICE_VENDOR := Ubiquiti
DEVICE_MODEL := UniFi USW Aggregation
IMAGE_SIZE := 14464k
$(Device/kernel-lzma)
endef
TARGET_DEVICES += ubnt_usw-aggregation
define Device/vimin_vm-s100-0800ms
SOC := rtl9303
UIMAGE_MAGIC := 0x93000000
DEVICE_VENDOR := Vimin
DEVICE_MODEL := VM-S100-0800MS
IMAGE_SIZE := 13312k
$(Device/kernel-lzma)
endef
TARGET_DEVICES += vimin_vm-s100-0800ms
define Device/xikestor_sks7300-4x4t
SOC := rtl9303
DEVICE_VENDOR := XikeStor
DEVICE_MODEL := SKS7300-4X4T
DEVICE_PACKAGES := kmod-hwmon-lm75
KERNEL_SIZE:= 8192k
IMAGE_SIZE := 28160k
KERNEL := \
kernel-bin | \
append-dtb | \
lzma | \
xikestor-sks7300-img
KERNEL_INITRAMFS := \
kernel-bin | \
append-dtb | \
lzma | \
xikestor-sks7300-img
IMAGE/sysupgrade.bin := \
append-kernel | \
pad-to 8192k | \
append-rootfs | \
pad-rootfs | \
check-size | \
append-metadata
endef
TARGET_DEVICES += xikestor_sks7300-4x4t
define Device/xikestor_sks8300-8t
SOC := rtl9303
UIMAGE_MAGIC := 0x93000000
DEVICE_VENDOR := XikeStor
DEVICE_MODEL := SKS8300-8T
DEVICE_PACKAGES := kmod-hwmon-lm75 rtl8261n-firmware
IMAGE_SIZE := 20480k
$(Device/kernel-lzma)
IMAGE/sysupgrade.bin := \
pad-extra 16 | \
append-kernel | \
pad-to 64k | \
append-rootfs | \
pad-rootfs | \
check-size | \
append-metadata
endef
TARGET_DEVICES += xikestor_sks8300-8t
define Device/xikestor_sks8300-8x
SOC := rtl9303
DEVICE_VENDOR := XikeStor
DEVICE_MODEL := SKS8300-8X
DEVICE_ALT0_VENDOR := ONTi
DEVICE_ALT0_MODEL := ONT-S508CL-8S
BLOCKSIZE := 64k
KERNEL_SIZE := 8192k
IMAGE_SIZE := 30720k
IMAGE/sysupgrade.bin := pad-extra 256 | append-kernel | xikestor-nosimg | \
jffs2 nos.img -e 4KiB -x lzma | pad-to $$$$(KERNEL_SIZE) | \
append-rootfs | pad-rootfs | append-metadata | check-size
endef
TARGET_DEVICES += xikestor_sks8300-8x
define Device/xikestor_sks8300-12e2t2x
SOC := rtl9302
UIMAGE_MAGIC := 0x93000000
DEVICE_VENDOR := XikeStor
DEVICE_MODEL := SKS8300-12E2T2X
DEVICE_PACKAGES := rtl8261n-firmware
IMAGE_SIZE := 20480k
$(Device/kernel-lzma)
IMAGE/sysupgrade.bin := \
pad-extra 16 | \
append-kernel | \
pad-to 64k | \
append-rootfs | \
pad-rootfs | \
check-size | \
append-metadata
endef
TARGET_DEVICES += xikestor_sks8300-12e2t2x
define Device/xikestor_sks8310-8x
SOC := rtl9303
UIMAGE_MAGIC := 0x93000000
DEVICE_VENDOR := XikeStor
DEVICE_MODEL := SKS8310-8X
DEVICE_PACKAGES := kmod-hwmon-lm75
IMAGE_SIZE := 20480k
$(Device/kernel-lzma)
IMAGE/sysupgrade.bin := \
pad-extra 16 | \
append-kernel | \
pad-to 64k | \
append-rootfs | \
pad-rootfs | \
check-size | \
append-metadata
endef
TARGET_DEVICES += xikestor_sks8310-8x
define Device/zyxel_xgs1010-12-a1
SOC := rtl9302
UIMAGE_MAGIC := 0x93001010
DEVICE_VENDOR := Zyxel
DEVICE_MODEL := XGS1010-12
DEVICE_VARIANT := A1
KERNEL_SIZE := 7168k
IMAGE_SIZE := 13184k
$(Device/kernel-lzma)
endef
TARGET_DEVICES += zyxel_xgs1010-12-a1
define Device/zyxel_xgs1210-12-a1
$(Device/zyxel_xgs1210-12)
SUPPORTED_DEVICES += zyxel,xgs1210-12
DEVICE_VARIANT := A1
endef
TARGET_DEVICES += zyxel_xgs1210-12-a1
define Device/zyxel_xgs1210-12-b1
$(Device/zyxel_xgs1210-12)
DEVICE_VARIANT := B1
endef
TARGET_DEVICES += zyxel_xgs1210-12-b1
define Device/zyxel_xgs1250-12-common
SOC := rtl9302
UIMAGE_MAGIC := 0x93001250
ZYXEL_VERS := ABWE
DEVICE_VENDOR := Zyxel
DEVICE_MODEL := XGS1250-12
DEVICE_PACKAGES := kmod-hwmon-gpiofan kmod-thermal
IMAGE_SIZE := 13312k
KERNEL := \
kernel-bin | \
append-dtb | \
rt-compress | \
rt-loader | \
uImage none
KERNEL_INITRAMFS := \
kernel-bin | \
append-dtb | \
rt-compress | \
zyxel-vers | \
rt-loader | \
uImage none
endef
define Device/zyxel_xgs1250-12-a1
$(Device/zyxel_xgs1250-12-common)
SUPPORTED_DEVICES += zyxel,xgs1250-12
DEVICE_VARIANT := A1
endef
TARGET_DEVICES += zyxel_xgs1250-12-a1
define Device/zyxel_xgs1250-12-b1
$(Device/zyxel_xgs1250-12-common)
DEVICE_VARIANT := B1
DEVICE_PACKAGES += rtl8261n-firmware
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
IMAGE_SIZE := 30336k
ZYNFW_ALIGN := 0x10000
$(Device/zyxel_zynos)
endef
define Device/zyxel_xmg1915-10e
DEVICE_MODEL := XMG1915-10E
$(Device/zyxel_xmg1915)
endef
TARGET_DEVICES += zyxel_xmg1915-10e
define Device/zyxel_xmg1915-10ep
DEVICE_MODEL := XMG1915-10EP
$(Device/zyxel_xmg1915)
DEVICE_PACKAGES := realtek-poe
endef
TARGET_DEVICES += zyxel_xmg1915-10ep