I recently acquired an SKS8300-8T switch, which uses the Realtek RTL9303 SoC with 8x rj45 REALTEK 8261BE 10GbE ports. After a bit of research and based on the work done with the SKS8300-8X switch, I was able to fairly easily boot into OpenWRT. The only problem is that there's a bug with the LAN ports, when a cable is plugged into ports 1-4, the corresponding ports 5-8 are incorrectly activated (port pairing) and ports 5-8 cannot function independently.
So after I found a remote code execution vulnerability in the device, I gained root access to the stock firmware and started gathering information about the device.
/www_wayos # cat /proc/mtd
dev: size erasesize name
mtd0: 001c0000 00010000 "LOADER"
mtd1: 00010000 00010000 "BDINFO"
mtd2: 00010000 00010000 "SYSINFO"
mtd3: 00010000 00010000 "JFFS2 FACTORYDATA"
mtd4: 00010000 00010000 "JFFS2 SYSDATA"
mtd5: 00a00000 00010000 "JFFS2 FILESYSTEM"
mtd6: 01400000 00010000 "RUNTIME"
mtd7: 02000000 00010000 "RUNTIME2"
/www_wayos # cat /proc/cpuinfo
system type : RTL9300
machine : RTL9300
processor : 0
cpu model : MIPS 34Kc V5.5
BogoMIPS : 530.41
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : no
isa : mips1 mips32r2
ASEs implemented : mips16
shadow register sets : 1
kscratch registers : 0
package : 0
core : 0
And here is my current DTS file:
// SPDX-License-Identifier: GPL-2.0-or-later
#include "rtl930x.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/thermal/thermal.h>
/ {
compatible = "xikestor,sks8300-8t", "realtek,rtl930x-soc";
model = "XikeStor SKS8300-8T";
memory@0 {
device_type = "memory";
reg = <0x00000000 0x10000000>,
<0x20000000 0x10000000>;
};
aliases {
led-boot = &led_sys;
led-failsafe = &led_sys;
led-running = &led_sys;
led-upgrade = &led_sys;
};
chosen {
stdout-path = "serial0:115200n8";
};
i2c_master: i2c@1b00036c {
compatible = "realtek,rtl9300-i2c";
reg = <0x1b00036c 0x3c>;
#address-cells = <1>;
#size-cells = <0>;
scl-pin = <8>;
sda-pin = <9>;
clock-frequency = <100000>;
fan_controller: fan-controller@6a {
compatible = "realtek,fan-controller";
reg = <0x6a>;
status = "okay";
};
};
keys {
compatible = "gpio-keys";
button-reset {
label = "reset";
gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
};
leds {
compatible = "gpio-leds";
led_sys: led-0 {
gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_STATUS;
};
};
led_set {
compatible = "realtek,rtl9300-leds";
active-low;
/*
* LED set 0
*
* - LED[0](Green): 10G/LINK/ACT
* - LED[1](Amber): 10M/100M/1G/2.5G/5G/LINK/ACT
*/
led_set0 = <0x0baa 0x0a01>;
};
temp_sensor: temp-sensor@48 {
compatible = "national,lm75";
reg = <0x48>;
};
thermal-zones {
main_thermal: main-thermal {
polling-delay = <5000>;
thermal-sensors = <&temp_sensor 0>;
trips {
fan_on: fan-on {
temperature = <50000>;
hysteresis = <2000>;
type = "active";
};
};
cooling-maps {
map0 {
trip = <&fan_on>;
cooling-device = <&fan_controller 0 1>;
};
};
};
};
};
&mdio_aux {
status = "okay";
gpio1: gpio@0 {
compatible = "realtek,rtl8231";
reg = <0>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&gpio1 0 0 37>;
status = "okay";
led-controller {
compatible = "realtek,rtl8231-leds";
status = "disabled";
};
};
};
&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 = "u-boot";
reg = <0x0 0x100000>;
read-only;
};
/* "flash_raw" on stock */
partition@100000 {
label = "board-info";
reg = <0x100000 0x30000>;
read-only;
};
partition@130000 {
label = "syslog";
reg = <0x130000 0xd0000>;
read-only;
};
/* "flash_user" on stock */
partition@200000 {
compatible = "fixed-partitions";
label = "firmware";
reg = <0x200000 0x1e00000>;
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "kernel";
reg = <0x0 0x800000>;
};
partition@800000 {
label = "rootfs";
reg = <0x800000 0x1600000>;
};
};
};
};
};
ðernet0 {
mdio: mdio-bus {
compatible = "realtek,rtl838x-mdio";
regmap = <ðernet0>;
#address-cells = <1>;
#size-cells = <0>;
phy0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c45";
phy-is-integrated;
reg = <0>;
sds = <2>;
};
phy8: ethernet-phy@8 {
compatible = "ethernet-phy-ieee802.3-c45";
phy-is-integrated;
reg = <8>;
sds = <3>;
};
phy16: ethernet-phy@16 {
compatible = "ethernet-phy-ieee802.3-c45";
phy-is-integrated;
reg = <16>;
sds = <4>;
};
phy20: ethernet-phy@20 {
compatible = "ethernet-phy-ieee802.3-c45";
phy-is-integrated;
reg = <20>;
sds = <5>;
};
phy24: ethernet-phy@18 {
compatible = "ethernet-phy-ieee802.3-c45";
phy-is-integrated;
reg = <24>;
sds = <6>;
};
phy25: ethernet-phy@19 {
compatible = "ethernet-phy-ieee802.3-c45";
phy-is-integrated;
reg = <25>;
sds = <7>;
};
phy26: ethernet-phy@1a {
compatible = "ethernet-phy-ieee802.3-c45";
phy-is-integrated;
reg = <26>;
sds = <8>;
};
phy27: ethernet-phy@1b {
compatible = "ethernet-phy-ieee802.3-c45";
phy-is-integrated;
reg = <27>;
sds = <9>;
};
};
};
&switch0 {
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
label = "lan1";
phy-handle = <&phy0>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@8 {
reg = <8>;
label = "lan2";
phy-handle = <&phy8>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@16 {
reg = <16>;
label = "lan3";
phy-handle = <&phy16>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@20 {
reg = <20>;
label = "lan4";
phy-handle = <&phy20>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@24 {
reg = <24>;
label = "lan5";
phy-handle = <&phy24>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@25 {
reg = <25>;
label = "lan6";
phy-handle = <&phy25>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@26 {
reg = <26>;
label = "lan7";
phy-handle = <&phy26>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@27 {
reg = <27>;
label = "lan8";
phy-handle = <&phy27>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@28 {
ethernet = <ðernet0>;
reg = <28>;
phy-mode = "internal";
fixed-link {
speed = <10000>;
full-duplex;
};
};
};
};
For the port mapping I used this https://svanheule.net/switches/rtl93xx#section9303
- Port 1 (PHY 0) β SerDes 2
- Port 2 (PHY 8) β SerDes 3
- Port 3 (PHY 16) β SerDes 4
- Port 4 (PHY 20) β SerDes 5
- Port 5 (PHY 24) β SerDes 6
- Port 6 (PHY 25) β SerDes 7
- Port 7 (PHY 26) β SerDes 8
- Port 8 (PHY 27) β SerDes 9
And after a bit of work, I finally found the binary that sets up the SerDes, fan functionalities, LEDs, etc..., located at /bin/smdrm
, which I then decompiled with Ghidra. I then managed get all the functions to rewrite the driver and add support for USXGMII with auto-negotiation in /target/linux/realtek/files-6.6/drivers/net
but all my attempts ended in failure...
If a Realtek driver expert happens to read this, I would really appreciate some help or guidance.
EDIT: bootloader with some debug added https://pastebin.com/5yiVT67c
EDIT 2: I have also uploaded all the reversed functions from the stock firmware related to SerDes and USXGMII initialization https://pastebin.com/2vKG9Buu