Support for RTL838x based managed switches

Luci is on the image. If it pings and gets an IP from the router, then everything works fine. The issue is the very strange initial setup. You need to enable VLAN on your desktop and configure it correctly, there are instructions earlier in the forum, maybe @edwinistrator can help.

Thanks for the status update, we are just utilizing the regmap MDIO for the qca8k.
Does the RTL8231 support pull-up/down configuration?

I have buzzed the SDA/SCL pins on the LM63 to pins on RTL8231 and bitbanged I2C on them but it just does not see the LM63 at all.
When checking with a multimeter I see voltage changes on the SDA but SCL is low (0.25V) so I would say that they did not include an external pull-up.

Thanks for the status update, we are just utilizing the regmap MDIO for the qca8k.

Cool! Glad to hear there's another user already :slight_smile:

Does the RTL8231 support pull-up/down configuration?

I have buzzed the SDA/SCL pins on the LM63 to pins on RTL8231 and bitbanged I2C on them but it just does not see the LM63 at all.
When checking with a multimeter I see voltage changes on the SDA but SCL is low (0.25V) so I would say that they did not include an external pull-up.

IIRC the pins have internal pull-ups. You should be able to find a datasheet online, or linked somewhere on the wiki. But those are probably quite weak. I think you can force-drive the clock, instead of being open drain with pull-up. It's in the I2C-gpio binding somewhere.

I found the datasheet in the meantime, yeah it's a 75k pull-up so it's really weak.
I tried using the i2c-gpio,scl-output-only, but haven't removed the OPEN_DRAIN.

Nah, even with open-drain removed it's still low.

It is indeed an engineering sample for a Chinese OEM that doesn't provide much data about the device. I am able to enter the diagnosis "dia" mode. Is there a specific command you want me to run there?

Hi devs,
I unfortunately managed to partly brick my DGS-1210-16 switch. Maybe someone of you has an idea on how to un-brick it. I know it was a little stupid to not wait longer in between my actions. So the lesson here is not to do bigger changes late in the night. Thanks in advance in case you have an idea.

Has anybody ever managed to compile the Realtek SDK?

I just can't figure out where did D-link hide all of their custom stuff and even in Ubuntu 14.04 compilation fails.
They stripped the CLI so there is no diag or debug that I can enter into to get some more details and the GPL code is really weird.
They somehow got the I2C-GPIO for LM63 working while it just wont work in OpenWrt, the SCL pin always remains LOW.
But the weird thing is that I can manually toggle it HIGH/LOW

With the sysfs interface, do you see incorrect behaviour when changing the level at the same time as the pin direction (i.e. writing high or low to direction instead of just in or out)? I have a suspicion the issue might be there.

I'm pretty sure you will need the patch below. It should ensure that you are reading the (previously set) output value, and that the pin value is set before it is changed to output. Without it, you could be updating other bits unintentionally with RMW cycles.

--- a/target/linux/realtek/files-5.10/drivers/gpio/gpio-rtl8231.c
+++ b/target/linux/realtek/files-5.10/drivers/gpio/gpio-rtl8231.c
@@ -152,7 +152,7 @@ static int rtl8231_pin_dir_get(struct rtl8231_gpios *gpios, u32 gpio, u32 *dir)
 static int rtl8231_pin_set(struct rtl8231_gpios *gpios, u32 gpio, u32 data)
-       u32 v = rtl8231_read(gpios, RTL8231_GPIO_DATA(gpio));
+       u32 v = rtl8231_read_cached(gpios, RTL8231_GPIO_DATA(gpio));
        pr_debug("%s: %d to %d\n", __func__, gpio, data);
        if (v & 0x80000000) {
@@ -198,10 +198,10 @@ static int rtl8231_direction_output(struct gpio_chip *gc, unsigned int offset, i
        pr_debug("%s: %d\n", __func__, offset);
-       err = rtl8231_pin_dir(gpios, offset, 0);
-       mutex_unlock(&smi_lock);
+       err = rtl8231_pin_set(gpios, offset, value);
        if (!err)
-               err = rtl8231_pin_set(gpios, offset, value);
+               err = rtl8231_pin_dir(gpios, offset, 0);
+       mutex_unlock(&smi_lock);
        return err;
@@ -241,7 +241,9 @@ int rtl8231_init(struct rtl8231_gpios *gpios)
        pr_info("%s called, MDIO bus ID: %d\n", __func__, gpios->smi_bus_id);
-       gpios->reg_cached = 0;
+       /* Mark data (output) registers as cached */
+       gpios->reg_cached = BIT(RTL8231_GPIO_DATA(0))
+               | BIT(RTL8231_GPIO_DATA(16)) | BIT(RTL8231_GPIO_DATA(32));
        if ( == RTL8390_FAMILY_ID) {
                // RTL8390: Enable external gpio in global led control register

Hi, I tried various combos, and echoing high/low to direction works fine as well as manually changing the value through sysfs.
Unfortunately, even with your patch it still doesn't work, it will basically float at 0.2V on the SCL while SDA will work fine from what I can see.

Weird thing is that I can see a 4.7k pull-up between the RTL8231 GPIO31 (SCL) and 3.3V but not between the SCL pin on LM63 and 3.3V which is weird as its a direction connection between the GPIO31 and SCL pin.

The SDK provided from ZyXEL for the GS1900-10HP compiles for me, using their pre-built toolchain.

I believe most of the GPL packages from other vendors are incomplete, as usual.

I tried spinning up a 14.04 32 bit VM and it actually compiled.
I mean, it's only 930kb the "OS" image but it will actually boot, looks like it's the kernel only.
Still need to figure a way to access the shell as root.

## Booting kernel from Legacy Image at b4e80000 ...
   Image Name:   
   Created:      2021-12-17  13:38:50 UTC
   Image Type:   MIPS Linux Kernel Image (gzip compressed)
   Data Size:    933545 Bytes = 911.7 KB
   Load Address: 80000000
   Entry Point:  80222000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK

Starting kernel ...

Linux version 2.6.19 (robimarko@temp) (gcc version 3.4.4 mipssde-6.03.00-20051020) #2 PREEMPT Fri Dec 17 13:38:37 CET 2021
CPU revision is: 00019070
Determined physical RAM map:
 memory: 02000000 @ 00000000 (usable)
User-defined physical RAM map:
 memory: 07a00000 @ 00000000 (usable)
Built 1 zonelists.  Total pages: 30988
Kernel command line: console=ttyS0,115200 mem=122M noinitrd root=/dev/mtdblock7 rw rootfstype=squashfs csb=0x0142C1E0 cso=0x0793FEAE csf=0x56B69CCF sfin=<NULL>,32MB,0;10887200 
Primary instruction cache 16kB, physically tagged, 4-way, linesize 16 bytes.
Primary data cache 16kB, 2-way, linesize 16 bytes.
Synthesized TLB refill handler (20 instructions).
Synthesized TLB load handler fastpath (32 instructions).
Synthesized TLB store handler fastpath (32 instructions).
Synthesized TLB modify handler fastpath (31 instructions).
PID hash table entries: 512 (order: 9, 2048 bytes)
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 121344k/124928k available (1786k kernel code, 3460k reserved, 393k data, 104k init, 0k highmem)
Mount-cache hash table entries: 512
Checking for 'wait' instruction...  available.
NET: Registered protocol family 16
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 4096 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 4096 bind 2048)
TCP reno registered
squashfs: version 3.3 (2007/10/31) Phillip Lougher
JFFS2 version 2.2. (NAND) (C) 2001-2006 Red Hat, Inc.
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
Serial: 8250/16550 driver $Revision: $ 1 ports, IRQ sharing disabled
serial8250: ttyS0 at MMIO 0x0 (irq = 31) is a 16550A
Probe: SPI CS1 Flash Type MX25L25635F
Creating 9 MTD partitions on "Total SPI FLASH":
0x00000000-0x00080000 : "BOOT"
0x00080000-0x000c0000 : "BDINFO"
0x000c0000-0x00100000 : "BDINFO2"
0x00100000-0x00280000 : "KERNEL1"
0x00280000-0x00e80000 : "ROOTFS1"
0x00e80000-0x01000000 : "KERNEL2"
0x01000000-0x01040000 : "SYSINFO"
0x01040000-0x01c40000 : "ROOTFS2"
0x01c40000-0x02000000 : "JFFS2"
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
VFS: Mounted root (squashfs filesystem) readonly.
Freeing unused kernel memory: 104k freed
init started:  BusyBox v1.00 (2020.06.22-07:08+0000) multi-call binary
Starting pid 14, console : '/etc/rc'
Init RTCORE Driver Module....OK
tun: Universal TUN/TAP device driver, 1.6
tun: (C) 1999-2004 Max Krasnyansky <>
passwd file exit
ssdh_config file exit

 Complete NpHwInit  
RTK.0> open /bin/poe.bin fail
device TAP0 entered promiscuous mode

|-------Smart Fan Register Write and Check-------|
Offset : 0x4a  Write Data : 0x28  Read Data : 0x28
Offset : 0x4b  Write Data : 0x0  Read Data : 0x0
Offset : 0x4d  Write Data : 0x17  Read Data : 0x17
Offset : 0x4c  Write Data : 0x1c  Read Data : 0x1c
Offset : 0x50  Write Data : 0x0  Read Data : 0x0
Offset : 0x51  Write Data : 0x1c  Read Data : 0x1c
Offset : 0x52  Write Data : 0x2f  Read Data : 0x2f
Offset : 0x53  Write Data : 0x2e  Read Data : 0x2e
Offset : 0x4f  Write Data : 0x3  Read Data : 0x3
Offset : 0x4a  Write Data : 0x8  Read Data : 0x8
Check Result : PASSJan  1 00:00:56 passwd[129]: password for `admin' changed by user `root'

Nice of them to provide the whole LM63 config sequence

I could solve my issue by reslashing to stable. Has anyone ever experienced serial access reliability issues? But it could also be my serial adapter, that is not always reliable (anymore).

This may not help, but have you tried using my proposed driver for upstream? The patch set is a bit more invasive than the current driver, but I'm quite confident setting pin directions and values works correctly with that one. I've used it to test SFP modules and LM75A sensors on my Cisco SG220-26P. Hardware details might differ, of course, but at least bitbanged I2C works with the driver.

Not yet, it's next on my list to try.
I just need to figure out the MDIO pins.

Ok, got it compiled and DTS sorted out but it's the same.
For whatever reason, it's floating at 0.2V.

It just makes no sense

Does the RTL8382 have an MDIO controller?

1 Like

For the RTL8231? It does, the RTL8382 isn't too dissimilar from the RTL8380, just supports more ethernet ports IIRC. I think I had an MDIO-controller implementation written for that auxilairy bus, but I may have to dig quite deep to find it (if I still have it somewhere...).

Does it also have the PHY-s on the AUX MDIO or they are SMI only?
I know that I am asking annoying questions, but this design is quite confusing for me.

No worries about the questions :slight_smile:
The phy-s are on a different bus.

This is all kind of contradictory to the designs I am used to, been working with various ARM/ARM64 router/switch platforms for too long it seems.

1 Like

Sounds like you've been spending too much time with sane hardware. The registers space for the networking part is pure chaos!

1 Like

I would call it semi-sane at best, Qualcomm and Marvell really like to do funny stuff, especially in the networking PHY-s.

And don't get me started on the CPLD implementations on Marvell Prestera switches.