Support for RTL838x based managed switches

I just submitted a pull request to GitHub for the ZyXEL GS1900-16. Would appreciate reviews and tested by. I've done some initial testing locally.

Will be proceeding to work on ZyXEL GS1900-24E and GS1900-24EP.


I have finally managed to get the SFP+ ports on the Zyxel XGS1210 and XGS1250 to work. I tested 10GBit fiber modules, 1GBit fiber, a 10GBit DAC cable (2m long) and a 1GBit copper module. They all work and because of full SFP SPI support on the RTL9300 it is even possible to switch them out in the same port while the device is running. Below you can see this for the XGS1210's right SFP+ port:

----- We start with no network plugged in
root@OpenWrt:/# ping
PING ( 56 data bytes
---- 1GBit fibre module inserted to right SFP slot: lan12
[  144.964025] sfp sfp-p12: module DIGITUS          DN-81000-01      rev A    sn 18050124         dc 180502  
[  144.974819] sfp sfp-p12: Is passive copper (DAC): 0, active 0, length 0
[  145.042416] sfp_sm_link_check_los detected link up
[  145.047756] rtl930x_switch_irq link status: 18000000, media 0c000000
[  145.047769] rtl930x_switch_irq link faults: 0fffff00
[  145.047774] rtl930x_switch_irq RX symbol errors: 00000204
[  145.067277] rtl93xx_phylink_mac_link_state called, port 27
[  145.073386] rtl93xx_phylink_mac_link_state: link state port 27: 8000000, media c000000
[  145.082258] rtl93xx_phylink_mac_link_state: speed is: 2 1000
[  145.088589] rtl93xx_phylink_mac_link_up called for port 27
[  145.094753] rtl83xx-switch switch@1b000000 lan12: Link is Up - 1Gbps/Full - flow control rx/tx
[  145.105403] rtl93xx_phylink_mac_link_state called, port 27
[  145.111515] rtl93xx_phylink_mac_link_state: link state port 27: 8000000, media c000000
[  145.120396] rtl93xx_phylink_mac_link_state: speed is: 2 1000
[  145.126737] switch: port 12(lan12) entered blocking state
[  145.132737] switch: port 12(lan12) entered forwarding state
[  145.141512] IPv6: ADDRCONF(NETDEV_CHANGE): switch: link becomes ready
[  145.150583] IPv6: ADDRCONF(NETDEV_CHANGE): switch.1: link becomes ready
---- Ping starts working
64 bytes from seq=12 ttl=64 time=1.055 ms
[  146.714711] rtl83xx_fib_event: FIB_RULE ADD/DELL for IPv6 not supported
[  146.722145] rtl83xx_fib_event: FIB_RULE ADD/DELL for IPv6 not supported
64 bytes from seq=13 ttl=64 time=0.993 ms
64 bytes from seq=14 ttl=64 time=0.606 ms
64 bytes from seq=15 ttl=64 time=0.594 ms
64 bytes from seq=16 ttl=64 time=0.821 ms
64 bytes from seq=17 ttl=64 time=0.839 ms
64 bytes from seq=18 ttl=64 time=0.577 ms
64 bytes from seq=19 ttl=64 time=0.730 ms
64 bytes from seq=20 ttl=64 time=0.623 ms
---- Pulling out fibre
[  154.715365] rtl930x_switch_irq link status: 10000000, media 0c000000
[  154.715371] rtl930x_switch_irq link faults: 0fffff00
[  154.715376] rtl930x_switch_irq RX symbol errors: 00000204
[  154.758173] rtl83xx-switch switch@1b000000 lan12: Link is Down
[  154.766459] rtl93xx_phylink_mac_link_state called, port 27
[  154.772569] rtl93xx_phylink_mac_link_state: link state port 27: 0, media c000000
[  154.780866] rtl93xx_phylink_mac_link_state called, port 27
[  154.787034] rtl93xx_phylink_mac_link_state: link state port 27: 0, media c000000
----- Pulling out 1GBit module
[  158.685665] sfp sfp-p12: module removed
------ Inserting 10GBit fibre module
[  166.084030] sfp sfp-p12: module UBNT             UF-MM-10G        rev      sn FT21022303379    dc 210223  
[  166.094820] sfp sfp-p12: Is passive copper (DAC): 0, active 0, length 0
[  166.102199] rtl83xx-switch switch@1b000000 lan12: switched to inband/10gbase-r link mode
[  166.111260] rtl93xx_phylink_mac_config port 27, mode 2, phy-mode: 10gbase-r, speed -1, link 0
[  166.120780] rtl93xx_phylink_mac_config SDS is 9
[  166.131850] rtl9300_configure_serdes CMU BAND is 16
[  166.137309] rtl9300_sds_rst SDS 9 to mode 0x1f
[  166.142245] rtl9300_sds_set set serdes 9 to mode 0x1f
[  166.157891] rtl9300_sds_set set serdes 9 to mode 0x1f
[  166.173514] rtl9300_sds_rst: 194:007d07df 198:000007df 2a0:007df7df 2a4:000007df
[  166.181767] rtl9300_configure_serdes PATCHING SerDes 9
[  166.188510] rtl9300_phy_enable_10g_1g 1gbit phy: 00001140
[  166.195539] rtl9300_phy_enable_10g_1g 1gbit phy enabled: 00001140
[  166.203305] rtl9300_phy_enable_10g_1g 10gbit phy: 00002040
[  166.210427] rtl9300_phy_enable_10g_1g 10gbit phy after: 00002040
[  166.218133] rtl9300_phy_enable_10g_1g set medium: 00000002
[  166.225258] rtl9300_phy_enable_10g_1g set medium after: 00000002
[  166.251928] rtl9300_configure_serdes: Configuring RTL9300 SERDES 9
[  166.260830] rtl9300_serdes_mac_link_config: registers before 00000000 00001403
[  166.272887] rtl9300_serdes_mac_link_config: registers after 00000000 00001403
[  166.280859] rtl9300_force_sds_mode: SDS: 9, PHY mode 0
[  166.286607] rtl9300_force_sds_mode: forcing SDS mode 1f
[  166.298438] rtl9300_force_sds_mode: SDS: 9, PHY mode 25
[  166.304245] rtl9300_force_sds_mode: forcing SDS mode 1a
[  166.333805] rtl930x_switch_irq link status: 18000000, media 0c000000
[  166.340871] rtl930x_switch_irq link faults: 0fffff00
[  166.346383] rtl930x_switch_irq RX symbol errors: 00000204
[  166.550330] rtl9300_force_sds_mode toggling LC or Ring for 10gr, round 0
[  166.741811] rtl9300_force_sds_mode end power 0x20 0 30
[  166.747567] rtl9300_force_sds_mode -------------------- serdes 9 forced to 1a DONE
[  166.758012] start_1.1.1 initial value for sds 9
[  166.802803] rtl930x_switch_irq link status: 18000000, media 0c000000
[  166.809864] rtl930x_switch_irq link faults: 0fffff00
[  166.815371] rtl930x_switch_irq RX symbol errors: 00000204
[  166.838622] end_1.1.1 --
[  166.841441] start_1.1.2 Load DFE init. value
[  166.848210] end_1.1.2
[  166.850734] start_1.1.3 disable LEQ training,enable DFE clock
[  166.869146] end_1.1.3 --
[  166.871958] start_1.1.4 offset cali setting
[  166.878639] end_1.1.4
[  166.881155] start_1.1.5 LEQ and DFE setting
[  166.899820] end_1.1.5
[  166.902352] rtl9300_sds_tx_config SerDes 9, pre-amp enable 1, pre-amp val 2, main-amp 9, post-amp enable 1, post-amp val 2, impedance 8
[  166.993551] sfp_sm_link_check_los detected link up
[  166.999289] rtl93xx_phylink_mac_link_state called, port 27
[  167.005485] rtl93xx_phylink_mac_link_state: link state port 27: 8000000, media c000000
[  167.014282] rtl93xx_phylink_mac_link_state: speed is: 4 10000
[  167.020713] rtl93xx_phylink_mac_link_up called for port 27
----- 10GBit link comes up
[  167.026868] rtl83xx-switch switch@1b000000 lan12: Link is Up - 10Gbps/Full - flow control off
[  167.037466] rtl93xx_phylink_mac_link_state called, port 27
[  167.043576] rtl93xx_phylink_mac_link_state: link state port 27: 8000000, media c000000
[  167.052456] rtl93xx_phylink_mac_link_state: speed is: 4 10000
[  167.058896] switch: port 12(lan12) entered blocking state
[  167.064947] switch: port 12(lan12) entered forwarding state
----- ping continues
64 bytes from seq=33 ttl=64 time=1.227 ms
64 bytes from seq=34 ttl=64 time=0.588 ms
64 bytes from seq=35 ttl=64 time=0.888 ms
64 bytes from seq=36 ttl=64 time=0.599 ms
64 bytes from seq=37 ttl=64 time=0.837 ms
64 bytes from seq=38 ttl=64 time=0.844 ms
--- ping statistics ---
39 packets transmitted, 15 packets received, 61% packet loss
round-trip min/avg/max = 0.577/0.788/1.227 ms
root@OpenWrt:/# ethtool lan12
S[  273.003482] rtl93xx_phylink_mac_link_state called, port 27
e[  273.009697] rtl93xx_phylink_mac_link_state: link state port 27: 8000000, media c000000
t[  273.018599] rtl93xx_phylink_mac_link_state: speed is: 4 10000
tings for lan12:
        Supported ports: [ FIBRE ]
        Supported link modes:   1000baseX/Full 
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  1000baseX/Full 
        Advertised pause frame use: Symmetric Receive-only
        Advertised auto-negotiation: Yes
        Advertised FEC modes: Not reported
        Speed: 10000Mb/s
        Duplex: Full
        Port: FIBRE
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: on
        Supports Wake-on: d
        Wake-on: d
        Link detected: yes

The code is in the rtl8214qf branch of my git repository. While I still have all the details of the bizarre SerDes of the RTL9300 in my brain (which is aching to forget it ASAP) I will work to make the 8 1GBit ports on the Zyxel XGS devices to come up without the help of u-boot. The 2.5 GBit ports on the XGS1210 and evidently the SFP+ ports already do that. I also need to revisit the Ubiquity USW switch to see whether now the SFP+ ports allow hot-swapping (they should) and support DAC cables. At that point the basic network support of the RTL9300 would be complete. Again quite a bit of code was necessary to get there, there should be however usable commits this time. I will check with Daniel whether we can push some to master. Anyone who wants to try can already test the code in my repo, most of it should apply to master.
It might be better to try to also first get the RTL931x network finally to work without the help of u-boot which will bring support for the Zyxel XS1930-10 into reach. The argument there is that my understanding of the RTL93xx SerDes is still fresh and there are probably a lot of synergies in the code which might lead to rewriting some of the RTL9300 SerDes code.


I also have a D-Link DGS-1210-28 and am trying to install OpenWRT on it. I have installed the initramfs image using tftpboot. But I can't install the sysupgrade image. After each reboot, the system is in the base configuration.

I have posted the whole process here:

I use the image from here:

I followed these instructions:

Does anyone have any tips on what I can do to make the system bootsafe?


P.S.: I need a wiki account so that I can document the installation of OpenWRT on a D-Link DGS-1210-28 with photos. :slight_smile:

Try the install instructions for the DGS-1210-16. That is the only official install instruction for the D-Link device family but it seems to work on all the family devices.

That was the first instruction I had used to do the installation. The result is always that it is not bootsafe.

I have read through these instructions again:
and carried out the steps again with copy&paste. Now it works.
I hadn't done the part with the checksum before and hadn't written /tmp/ before the image. Those were probably the errors.

Now I only need an account in the wiki. :slight_smile:

Doubt it!
Checksum only verifies the file size for good practice, maybe if the first file was corrupt it would make any difference but that kind of fault would end up in a bricked router, not a “not installed after reboot” router.

Not write /tmp/…maybe but this is only the address to the folder where you put the actual file.
If you made this mistake before the file name it would directly result in a major error like “the file not found” since you specified the wrong address to the file.

Are you sure you actually installed anything the first try since the description “it was gone after reboot” fits the function of the ramfs file loaded in to ram?
I built the ramfs file with luci preinstalled and opened luci from ram and installed the real OpenWrt as usual from luci instead of installing the real firmware file from terminal.

Could you please post the image you are working on? I bought this switch for OPENWRT because I really don't like the system it came with. Even if OpenWRT has bugs, it's not problem for me.
I mean Zyxel XGS1210.

I have put images for the XGS1250 and XGS1210 here:

they are compiled from Daniel's cleaned up version of the latest development work, which can be found here:
They are "vanilla" OpenWRT master images, i.e. you need to install e.g. LuCI as a web-interface yourself via opkg. You need to connect via USB-Serial adapter, boot from within u-boot the initramfs image using tftp, and whether then the sysupgrade image will install is something I am not sure has been done already. At least I did not do it. The installation instructions for the 1250 should be helpful though, whatever is described there should also work for the XGS1210.

There are also images for the Ubiquiti USW switch from my current work, also that works very nicely, except that 1G SFP modules don't light the Port-LEDs and port 5 does not work because the present Linux sfp-code does not support sharing the sfp-i2c bus with other devices, in this case a GPIO expander. All devices other than the SFP EEPROMS seem to be considered to be PHYs.

The present status is that Daniel did a cleanup of the commits I provided with the latest development results. So now these patches are at the level of the OWRT master. The code might need some more cleanup still, because getting the MAC, SoC and PHYs to work with each other for 10G on the Realtek SoCs is shockingly complex and the SDK is a large heap of spaghetti code, for which I have not yet been entirely able to disentangle the code-paths. So now we are looking what needs to be done and at the same time I apply what I learned about the RTL9300 SFP+ ports to the RTL9310 in order to get them to work there, too.


Thanks a lot for sharing these images. I am very grateful. The only question is, are there any recommendations on your part for backing up the original system?

The easiest way would be to run the initramfs system from memory, upon which you can backup the mtd devices via the network. If you want back to the original OS, just copy them back. Because you have access to u-boot via serial console it is not soooo easy to brick the device. You could invest 10 €/$ into a flash programmer and then you can always flash back the mtd partitions even if you have locked yourself out of u-boot.

1 Like

If you use a programmer, do you need to solder the wires to the memory? I am asking because, if I remember correctly, some devices can be repaired using JTAG or something similar.

No soldering. Search e.g. amazon for "ch431a programmer". You will find plenty of offers for sets including a sop8 or soic8 clip (a synonym) that looks similar to a fastener for laundry on a line. While the switch is off, you can clip it onto the flash chip and then read or write flash memory using e.g. the flashrom tool. I never had to do this to rescue something in the past several years. It is mostly to prevent you from not trying out something that might be dangerous because you are worried you might destroy a device that cost real money. I use these clips mostly to read out flash to analyze it or enable u-boot command prompts when access has been disabled or obscured. But they also allow you to repair any rtl83xx/93xx switch I have so far encountered that might be software-bricked.

1 Like

Just a reminder that the "ch431a programmer" may need a 3,3v mod instead of 5v depending which model you buy, otherwise you may damage your flash chips!

1 Like

Excuse my ignorance as an OpenWrt newbie. I built an image for the ALLNET ALL-SG8208M with CONFIG_TARGET_realtek_rtl838x_DEVICE_allnet_all-sg8208m=y and leaving the rest of the options to their default.

build_dir/target-mips_4kec_musl/linux-realtek_rtl838x/tmp/openwrt-realtek-rtl838x-allnet_all-sg8208m-squashfs-sysupgrade.bin has a size of 5.8 MB. Is that the image I can flash using the vendor upgrade feature with HTTP upload?

Has somebody tested images built from the master branch recently?

I built and flashed linux-realtek_rtl838x/tmp/openwrt-realtek-rtl838x-allnet_all-sg8208m-squashfs-sysupgrade.bin using the vendor Web interface, but unfortunately, the ALLNET ALL-SG8208M seems to be in a reboot loop, and I am never able to ping it. If somebody, with that device and a working serial console, could test that image, that’d be much appreciated.

Then this device is probably doing the same as many others: it expects the uimage to contain a self-sufficient initramfs, and all trailing data is discarded. For sysupgrade images, this means the device will discard the squashfs trailing the uimage with the kernel. Which leaves you with a rebooting system.

You will have to get access to the serial console to tftp an initramfs, from which you can properly install OpenWrt.


And fortunately this is trivial to accomplish on this device (same hardware as the gs1900-8, but different firmware/ flash partitioning), three standard philips head screws, a pre-populated and marked (from the perspective of your usb2serial adapter) serial header (3.3V) with 2.54mm spacing - and u-boot should get you going again.


Please excuse my ignorance, on the board is that the spot marked JP2 with the four pins labeled GND, TX, RX, VCC, or the unpopulated spot JP1 with a RS232 serial motherboard header connector pinout?

JP2 (3.3V). While JP1 is part of the board design, it's left unpopulated and missing half a dozen crucial components.