Support for Horaco ZX-SWTG3424S switches

Did you try rtk network on

More interestingly, you have a switch with a USB port on it? That's super interesting!


Sorry for the withdrawal of the initial post. Needed some time to think.
You are correct, rtk network on works. Somehow i missed it in the text.
Moreover, I was able to tftp the zyxel_xgs1250-12-initramfs-kernel.bin into the unit.
And I was also able to start that, instead of the factory image.
Unfortunately, does not work for this particular unit (what actually is not a big surprise).
Can you recommend how to deploy openwrt on it?
I'm thinking upgrading your u-boot over the factory one. But as you've suggested - i'd really like to backup the current system.
here are some screenshots :slightly_smiling_face: of it:

So, I have a 24 + 4 SFP + console port + USB switch with - i guess - the same hardware like the XGS:

U-Boot 2011.12.( (Dec 20 2022 - 04:42:03)
Board: RTL9300 CPU:800MHz LX:175MHz DDR:600MHz
DRAM:  128 MB
SPI-F: WINBOND/EF4018/MMIO16-1/ModeC 1x16 MB (plr_flash_info @ 83f852e0)
Loading 65536B env. variables from offset 0xe0000
Net:   Net Initialization Skipped
No ethernet found.
Hit Esc key to stop autoboot:  0
RTL9300# # flshow
=============== FLASH Partition Layout ===============
Index  Name       Size       Address
 0     LOADER     0xe0000    0xb4000000-0xb40dffff
 1     BDINFO     0x10000    0xb40e0000-0xb40effff
 2     SYSINFO    0x10000    0xb40f0000-0xb40fffff
 3     JFFS2_CFG  0x100000   0xb4100000-0xb41fffff
 4     JFFS2_LOG  0x100000   0xb4200000-0xb42fffff
 5     RUNTIME1   0xc00000   0xb4300000-0xb4efffff
 6     OEMINFO    0x100000   0xb4f00000-0xb4ffffff
RTL9300# # printenv

Environment size: 283/65532 bytes
RTL9300# # help
?       - alias for 'help'
base    - print or set address offset
boota   - boota  - boot application image from flash partiton

bootm   - boot application image from memory
bootp   - boot image via network using BOOTP/TFTP protocol
cmp     - memory compare
cp      - memory copy
crc32   - checksum calculation
env     - environment handling commands
erase   - erase FLASH memory
flerase - Erase flash partition
flinfo  - print FLASH memory information
flshow  - Show flash partition layout
go      - start application at address 'addr'
help    - print command description/usage
iminfo  - print header information for application image
loadb   - load binary file over serial line (kermit mode)
loads   - load S-Record file over serial line
loady   - load binary file over serial line (ymodem mode)
loop    - infinite loop on address range
md      - memory display
mm      - memory modify (auto-incrementing address)
mtest   - simple RAM read/write test
mw      - memory write (fill)
nm      - memory modify (constant address)
ping    - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
printsys- printsys - print system information variables

protect - enable or disable FLASH write protection
reset   - Perform RESET of the CPU
reset_all- Perform whole chip RESET of the CPU
rtk     - rtk     - Realtek commands

run     - run commands in an environment variable
saveenv - save environment variables to persistent storage
savesys - savesys - save system information variables to persistent storage

setenv  - set environment variables
setsys  - setsys  - set system information variables

sf      - SPI flash sub-system
sleep   - delay execution for some time
tftpboot- boot image via network using TFTP protocol
upgrade - Upgrade loader or runtime image
version - print monitor, compiler and linker version

The intention is to

  1. backup the current flash
  2. clear all unnecessary things
  3. run openwrt


So first off; one of the biggest roadblocks we have right now, is that the rtl930x can't actually switch right now, or rather, data only goes from switch to host, but not from port to port. Some guys on the forum seem to be investigating this however :slight_smile:

Flashing my u-boot variant should be fine, as in the end, it is still the vendor u-boot, just compiled from scratch, with some things disabled (that overwrites random stuff).

So backing stuff up, if you can get the initramfs running, with network support to your host, it'll be easy with 'dd'. The only tricky bit would be that the size of the flash is the same as your iniramfs binary. The partitions don't really matter; because what you'd be doing, is dd (with netcat) each partition, and then on the host you can just concatenate them, and split them into the 'true' partitioning scheme.

That said, it looks like the partition scheme and size is 'the same' so you don't even have to dot hat.

'loader' is u-boot binary partition,, 'bdinfo' is your printenv/saveenv; sysinfo is 'printenv2/saveenv2' (forgot the exact commands) so not crucial, but still good to have.

I haven't (cared to) disect JFFS2_CFG, which contains at least mac-addresses it seems. Not sure if u-boot uses them, but linux seems to. Otherwise, OEMINFO might :slight_smile: I simply don't know. I only have a dumb switch which lacks all these. And again, I don't care anyway. I changed openwrt to get the needed mac-address data from the u-boot environment partition anyway, in a 'openwrt-standard-way'.

P.S.: Did you create a wiki page already? pics? Love to see pics how it's wired up, especially the USB port :slight_smile:

Did you try using the USB port on the vendor firmware? So excited about the USB bit :slight_smile:

Oh more importantly, did you request GPL sourcecode? Which could give us USB insight as well (even though it might be in the dumps we already have :stuck_out_tongue: idk)

The USB port might be a dud though; the datasheet/documentation says '1 console port, and 1 USB serial port'. So might be just a pre-FDTI-ish usb - serial connector. Though technicall the USB-A port is illegal to use for this, as it basically means you'd have to use an illegal USB-A <-> USB-A cable. With USB-C it is easier however, as you can just use a USB-A <-> USB-C cable, technically in reverse.

Anyway, this is getting a bit offtopic with regards to U-Boot, so best to spin off a separate topic. Having said that, I just pushed very initial support for your specific switch. Stuff is probably still wrong all over the place (number of leds, reset pin GPIO) but the switch was very similar to the Mestech one ... So used that as a basis. The MDIO ports could be wrong too(I haven't even compiled it yet :p) .. idk, only one way to find out (in a new topic :p)

I certainly know the rtl930x chips have USB EHCI / OHCI plus a PHY. I haven't yet looked into it too much for my particular switch, since I know the actual USB pins aren't broken out to anything I can use (i.e. it's not exposed in the oem interfaces.. but does show up in the oem boot logs).
My hope is that just throwing in a dts for the EHCI/OHCI and port 1 on the EHCI would be enough with the generic-ehci / generic-ohci to get it working. I'll dig a little deeper on the weekend.
I'll also finally get around to doing the spi flash dump, so will be keen to try your uboot version in it after that. Given my rtk network on doesn't result in working ethernet, I suspect your uboot wouldn't go backwards on that functionality :wink:

1 Like

I think we had this in the past somewhere; but ... no device to validate/confirm these suspicions. Afaik you are correct that it's one of the standard EHCI thingers, and doesn't even need any glue code or anything. But, if the oem firmware shows it, we might find references in the code for it, to figure out the dirty details (if needed at all).

To be fair, the USB node should be in the main dts, but disabled by default :slight_smile: Bigger concerns are register address space; will it be enough if we just pass it a single reg node, or did realtek do some nasty bits. For an interrupt, we know its 28 though :slight_smile:

We also know there's something called 'USB_LED' on pin B14; but what its function is (if it where not used as GPIO, is unknown.

F4 and G4 are the USB- and USB+ pins, maybe someone will get lucky and has resistor pads that can be used to connect with :slight_smile:

I'll check some photo's but this stuff is hard to trace usually, with via's under the SoC ..

I did find missing resistors (without labels) that look very suspisious to the DM+ and DM- lines here marked in red:

From the schematic, USB ought to be R114 and R117, which I can't find, but lots of other resistors that are supposed to be near to those pins are there. Those R110, R111 bank of resistors, are the strapping pins for certain features for example. All of those, are on the inner two rings of the chip-pinout (the outer two rings are routed to the top layer).

Sadly, I don't have a better picture at the moment (I'll get a good close up once I have a reason to open up the switch again) and see if I can connect some wires to those pads. Not sure if those pull-ups are needed though. The schematic lists them as 'dnp 4k7'; but don't know enough about USB if those are required or not, also due to lack of reference :).

Thanks for the reply. Thank you so much for being active on this topic. :+1:
Proceeding slowly :face_with_spiral_eyes:
Now I was able to copy the zyxel_xgs1250-12-initramfs-kernel.bin to the unit. Probably to the wrong address, because it fails starting:

RTL9300# # bootm
## Booting kernel from Legacy Image at 80000000 ...
   Image Name:   MIPS OpenWrt Linux-5.10.161
   Created:      2023-01-03   0:24:21 UTC
   Image Type:   MIPS Linux Kernel Image (gzip compressed)
   Data Size:    6891507 Bytes = 6.6 MB
   Load Address: 80000000
   Entry Point:  80000400
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... Error: inflate() returned -3
GUNZIP: uncompress, out-of-mem or overwrite error - must RESET board to recover

so i still can't perform the very first step, the full backup (have the printenv values though).
:thinking: Is there a step-by-step how-to for dummies? :laughing:
@ wiki page - i was not sure if it is worth to do such a thing. The wiki description suggests not to increase the ToH noise. As you've already mentioned, there are roadblocks. Since this unit is not from the well knowns, i was affarid that this is only the interest of this very few member in this thread :laughing: :joy:
Anyway, if you think it is worth to do, i'm happy to disassemble the unit and share every pieces and bits both on the HW & on the software side.
@ USB - right know i'd say that your intuition on the USB port being dud is 97% correct. There's no menu element for any activity related to USB in the vendor fw. Moreover, on insertion of a stick it gets powered but there's no entry in the log :sob:
@ did you request GPL sourcecode ? - how to do dat?

You could try a higher address, like 0x82000000 (for the tftpboot and the bootm commands).
That might provide enough of a gap between the load memory and the uncompress area to work. The inflate() error is often when the location you've copied the compressed boot image to is too close to where it's trying to uncompress the image (i.e. 0x80000000).

The wiki Olliver will be talking about is:
For information on the Realtek switches in general, and not just around OpenWRT.
And yes please, all the information is helpful to ensure the widest support.

If it doesn't work in the stock image, then it's definitely less likely it would work elsewhere. But you might get lucky. It is possible that the oem just intended this to be some weird way of supplying a 5V supply for stuff.. like charging a phone or something.
You'd need to get a working OpenWRT DTS first, and then you could add in the USB generic-ehci compatible section (if you just search for that generic-ehci term in the OpenWRT source you'd find some examples), for the reg setting you could check some of the other rtl930x boot logs (or potentially the oem boot log you have if it mentions ehci).

Just find the Tech Support contact details for the oem, and email them requesting the GPL source code for the OpenWRT assemblies that they ship, along with the GPL source code for the Uboot assemblies that they ship.
You can direct them to the following license references;a=blob;f=LICENSES/GPL-2.0

Well this thread is about u-boot on rtl930x :slight_smile: so we are very heavily off-topic as it is :slight_smile:
the hasvio and rtl838x threads are generic enough;

anyway, this wiki: is where we keep the realtek switches, pics are valueable as it helps us learn and understand how different models behave :slight_smile:

Well it IS needed for the things we don't know about your particular switch, photo's helps us identify parts, trace routes etc. See what I've done for for example (in the pics section)

I think it's a USB serial converter thingiemabob; once we have linux booting (or you have access to a shell) you can see the kernel log though :slight_smile: here is what we currently have.

btw, try using '0xb4300000' which we often use :slight_smile:

For the USB stuff, I've got what I think might be a start, using Generic EHCI / OHCI (although my hardware doesn't have it broken out to actually test it).

In @olliver 's WIP branch, in the rtl930x.dtsi it would get the following added to it (I just dropped it below the GPIO controller)

		usb_ohci: usb@20000 {
			compatible = "generic-ohci";
			reg = <0x20000 0x1000>;

			interrupt-parent = <&intc>;
			interrupts = <28 0>;

			state = "disabled";

		usb_ehci: usb@21000 {
			compatible = "generic-ehci";
			reg = <0x21000 0x1000>;
			companion = <&usb_ohci>;

			interrupt-parent = <&intc>;
			interrupts = <28 0>;

			phy-names = "usb-phy";
			phys = <&usb_phy>;

			state = "disabled";

			#address-cells = <1>;
			#size-cells = <0>;

			hub_port: port@1 {
				reg = <1>;
				#trigger-source-cells = <0>;

		usb_phy: usb-phy {
			compatible = "realtek,rtl930x-usb-phy";
			reg = < 0x000500 0x100>;

			#phy-cells = <0>;

			status = "disabled";

then in the board-specific dts to actually use them

&usb_ohci {
	status = "okay";
&usb_ehci {
	status = "okay";
&usb_phy {
	status = "okay";

It also needs a tweak to the config-5.15, these should probably be board specific activations (unsure where the best location to bring them in would be)


that should at least get you some USB activity in the boot logs, like below:

[    0.309646] usbcore: registered new interface driver usbfs
[    0.315725] usbcore: registered new interface driver hub
[    0.321676] usbcore: registered new device driver usb
[    2.907432] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    2.914945] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver

As to whether it's enough to actually get USB stuff working, I fear it's not.
I think the PHY needs some magic (which is why I've left it with a realtek compatible in the DT), and it's possible that more is needed around the ehci/ohci stuff also.
It'd be worth giving the above a try, and seeing if it at least reports any Port/PHY activity when a device is added to the bus.

Almost :slight_smile:

The addresses are wrong, and I think it's generic-ehci. Not sure yet if ohci is even used at all; I see it being printed in the horaco log, but not on the hasvio or the zyxel ones, those just seem to have ehci only. The code I found, also only has ehci stuff. I wipped up the following:

But that's just copy/pasting the sdk stuff in. THe devicetree should be decent though.

I think we can drop the host 'glue' stuff, there's nothing in there, and just use the generic-ehci stuff for sure. The PHY stuff we probably will need. I am having a hard time to figure out what goes where. There's a ehci register range (21000), the PHY range (500) but also something called UTMI, which is a USB PHY thing I learned, but from a register space, it sits just behind the EHCI stuff. also, where is the ehci stuff talking to? what registers? I can't see where the generic ehci driver is reading and using the actual register, though obviously there must be some way to talk to the peripherial ...

The generic-ehci pulls in the platform-ehci stuff (in standard linux kernel).
There was some RTK PHY stuff in the SDK, and the UTMI info is good, it’s a controller<->PHY protocol (like SGMII etc). I'll have a look this weekend at what might be involved in mapping across from how the SDK configures the PHY to how modern linux kernel does it. It would really be great if we could just use the generic-ehci/ohci stuff (for USB2.0 / 1.1 respectively) and some updated custom Realtek PHY driver (unless this could be a common existing linux driver).

PS: What was wrong with the addresses? They matched what I’d seen (my oem boot shows both EHCI / OHCI, only the address for EHCI, but it aligns with rtl8197f etc).

Nothing, you are right, I was wrong :slight_smile: So I apologize. I saw the 2000 address which threw me off. But it is quite likely that the rtl819x has it right. Good thinking!

That was my plan too; See if the stock stuf just works. I'm gonna solder some wires onto my UBS pads and find out at some point :slight_smile:

For now, I just copy/pasted the sdk stuff, but I don't see why the generic stuff shouldn't work (bar some flags maybe?) everything in there, is super standaard stuff, all covered in ehci-platform.c afaik. But first, I need something to compare/test against :slight_smile:

The copyright notice at the top of the file is weird though, it speaks of glue code from openwrt, yet the exact string can't be found anywhere. Maybe they copied the file from somewhere, then changed "vendor" to Realtek :stuck_out_tongue: who knows ...

I took your suggestions and put them in my wip branch, haven't compiled it yet though; busy with other stuff atm.

1 Like

The ehci / ohci nodes might need a few other tweaks also.

    dr_mode = "host";
    phy_type = "utmi";

This ensures that the USB controller doesn't fall into OTG / Device mode.
And if we're certain about the PHY interface mode, then putting UTMI just ensures we don't run into problems trying to use ulpi / utmi-wide or other similar mismatched mode.

I'd like to think this is the kind of PHY driver that we could hack up for the Realtek SoC version (I haven't yet compared it to the RTK SDK stuff.., I did try to find PHY registers in the SDK logic code and came up a bit blank though.. registers are defined, just don't appear to be referenced by name)

Yeah, I was gonna add those; but technically,t hey are not needed. "The driver decides" e.g the realtek specific PHY driver. Having said that, it is cleaner to add it to the PHY for sure!

Any idea what the USB_PHY_FM 'might' be?

It's one of those registers that just doesn't seem to sit within an understandable device range.

In regards to the actual PHY, it seems there's not much for that... just the small data window to stream in the various calibration values based on rtl930x/rtl931x (unsure why they're so drastically different).

My best guess at the moment is 'Frequency Mask', but that doesn't match the actual code, so my second best guess is 'Function Mask' where you tell the PHY about it's functionality?

FM_R_FDISCON_MASK could read as FUNCTION_MASK_R_FUNCTION_DISCONNECT. No idea what the R would stand for, read is the first that comes to mind, but that's weird.

Yeah I had the same thought. The PHY is the same, it didn't become a USB3 phy magically. But without documentation of the PHY registers, we really have no idea. Maybe RTL931x is a OTG phy?

Even more funny, is that they have split up the rtl931x registers into calibration and configuration, but don't use the calibration regs on the rtl930x...

There seems to be two clear references though. One is FSL (Freescale) but I think that is copy/paste of which they started from. More likely, is the DW (DesignWare) reference, which is of course in the business of selling IP blocks. Unfortunately, that's where it ends, and I didnt' find a USB phy from DW in the current linux kernel :frowning:

But yes, the phy driver would only expose the read/write interface, and load up the configuration data. I removed the rtl931x from my code-dump to make it read easier to read.

Also if you look closely, the rtl930x revA behaves the same as rtl931x; but later rtl930x are 'simpler'. Maybe the rtl931x is closer to the revA then later models ...

I think the FSL was because it was one of the first 'generic' USB ehci-type controllers in the kernel.

There is the following DesignWare driver. There's also a few variants on a DesignWare USB3 controller

It looks like potentially the standard PHY interface is almost no PHY interface... perhaps the UTMI stuff handles enough of it automatically
Posts like this seem to have the dwc2 usb controller driver and the "usb-nop-xceiv" NOP PHY frequently related.

It does seem that throwing the config and calibration data into a Realtek USB PHY driver and giving it a whirl should be relatively low effort. IF there is something with hardware that has USB already broken out. Having to dodge up wires from vias would make isolating software vs hardware 'faults' trickier..

I didn't find that, but I now see it sits in its own directory, not 'hosts'. though I did grep for it afaik. Though that driver is huge (in lines of code) which doesn't even come close to what realtek has. That doesn't mean realtek is NOT using their IP; but makes it harder to believe :frowning: especially since what we seem to be missing the most, is the USB phy, not so much the HCD stuff ...

Changing to the realtek dump driver, into a proper usb-phy driver should be trivial, and was on the list as next step; but before that, need something we can verify against :slight_smile:
As you saw in my pics/post; both switches I have, brought out the pins to resistor pads, so adding wires is trivial. No idea where 5V would be though, can always through in a 12V -> 5V regulator of course, but don't recall having 5V on my switches. Little anxious on soldering n wires on my poor little zyxel though :slight_smile:

So I tried to compile it; but ... atleast the ehci driver is a mess. It uses ehci internal variables, names and functions, misses all defines, just keeps exploding in my face. So the EHCI driver is probably not worth it to use the vendor one. I just disabled it and see if I can at least compile the PHY driver, but I'm not having high hopes :slight_smile:

btw, I think designware was aquired by synopsis, or rather, I was searching for datasheets for the designware PHY, and ended up on the synopsis site ...

1 Like

Just pushed my wip branch with USB patches from the SDK.

ohci and ehci are the generic stuff; seems to probe, I'd expect errors if things would be wrong there.

The PHY is printing happy thoughts, but zero clue if it actually works. For that we'd need @svidpet :stuck_out_tongue:

1 Like

Is that with a hacked up PHY driver based on the things the SDK does? (i.e. throw down the config and calibration values)

I also would have expected some complaint from ehci/ohci driver if probe registers weren't right. But unsure how quiet it might be in failures. After all, I didn't have any phy driver indicated in my DT, and it didn't spit out any warnings/errors for it.

But as you say, we just need to wait for someone with a real USB capable vendor device to confirm if it works under the OpenWRT stuff (your WIP).