Support for RTL838x based managed switches

I don't think that's correct. A0 can be muxed as the sys-led, A2/A3 as the MDIO bus for an RTL8231. The five JTAG pins are muxed on B2-B6, but JTAG normally isn't used. Seeing the RTL8231 implementation, I wouldn't put it past TP-Link to use more GPIOs for bit-banged I2C busses. There should be 24 GPIO lines in total on an RTL838x. I haven't found all control bits for them yet, but of course it's also possible not all of them can be muxed to a pin.

Going by the thickness of the traces, I think this picture shows 6 pull-ups per SFP-module:

  • SCK (possibly shared)
  • SDA
  • Loss Of Signal
  • Module absent
  • Tx disable (possibly shared)
  • Tx fault

If these are all linked to the SoC, that would require between 18 (shared SCK and Tx disable) and 24 GPIO lines. This would be, by far, the largest number of SoC GPIO lines I've ever seen used on an RTL838x device!

Looking at https://raw.githubusercontent.com/libc0607/Realtek_switch_hacking/files/RTL8214FC-VC-CG_Datasheet_1.2.pdf figure 11, it appears at least the RTL8214FC would not be able to read the SFP module status signals. Maybe they are not read out at all as in that figure.

1 Like

I was just playing around with the firmware upload feature in the stock firmware, when I noticed that since I flashed the full u-boot, communication is now only working on the SoC internal PHY ports on stock firmware.

port 0 patch ready fail 0
port 1 patch ready fail 0
port 2 patch ready fail 0
port 3 patch ready fail 0
port 4 patch ready fail 0
port 5 patch ready fail 0
port 6 patch ready fail 0
port 7 patch ready fail 0
port 8 patch ready fail 0
port 9 patch ready fail 0
port 10 patch ready fail 0
port 11 patch ready fail 0
port 12 patch ready fail 0
port 13 patch ready fail 0
port 14 patch ready fail 0
port 15 patch ready fail 0
port 16 patch ready fail 0
port 17 patch ready fail 0
port 18 patch ready fail 0
port 19 patch ready fail 0
port 20 patch ready fail 0
port 21 patch ready fail 0
port 22 patch ready fail 0
port 23 patch ready fail 0

Getting those on stock firmware boot. Indeed there seems to be some trickery going on.
Maybe the external PHY's would be correctly detected in my openwrt image with stock u-boot in the flash?

TP-Link's firmware format seems to be a bit mixed up compared to openwrt default:

$ binwalk T1600G-28TSv3_en_3.0.6_\[20200805-rel55968\]_up.bin 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
512           0x200           Squashfs filesystem, little endian, version 4.0, compression:lzma, size: 4173556 bytes, 47 inodes, blocksize: 131072 bytes, created: 2020-08-05 07:42:00
4174336       0x3FB200        uImage header, header size: 64 bytes, header CRC: 0xF85DCDDC, created: 2020-08-05 07:41:41, image size: 3869836 bytes, Data Address: 0x80000000, Entry Point: 0x80003710, data CRC: 0xDB7329CD, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: gzip, image name: "3.0.0"
4174400       0x3FB240        gzip compressed data, maximum compression, has original file name: "vmlinux_org.bin", from Unix, last modified: 2020-08-05 07:41:41
8306376       0x7EBEC8        Copyright string: "Copyright (c) "
8328464       0x7F1510        CRC32 polynomial table, little endian
8354164       0x7F7974        JFFS2 filesystem, big endian
$ binwalk openwrt-realtek-generic-tp-link_t1600g-28ts-squashfs-sysupgrade.bin 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             uImage header, header size: 64 bytes, header CRC: 0x3788DFCD, created: 2021-04-24 19:11:33, image size: 2867029 bytes, Data Address: 0x80000000, Entry Point: 0x80000400, data CRC: 0x2300ED23, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: gzip, image name: "MIPS OpenWrt Linux-5.4.113"
64            0x40            gzip compressed data, maximum compression, from Unix, last modified: 1970-01-01 00:00:00 (null date)
2883584       0x2C0000        Squashfs filesystem, little endian, version 4.0, compression:xz, size: 2033450 bytes, 730 inodes, blocksize: 262144 bytes, created: 2021-04-24 19:11:33

uImage and Squashfs trading places coming after a custom header and a trailing jffs2 filesystem with

#-TAIL-#
BgIAAACkAABSU0ExAAQAAAEAAQD7hbsK1FurprcGdQQRS1lA/shOpyZfa2mP4+kFfyLCVQi96b623eFZrg17K7Z2pS+saS3c6Hpa3+OLKSQG6237bqjcBhp9j6peKSRmabOb4H1b39SSyCFcF+tWh4wcDEafFtppq5mqd2gUtb7SRg89tbfJA7PsLkYr2rpdne2Yxg==
7C1D1FC5BF9333473D8C8052701E9BE4

in it, and the whole thing is DES encrypted.

you did see https://biot.com/switches/image_formats/tplink ?

Yes, I started implementing this into the image generation routine. If thats not already done by someone?

Edit: Bodged together a firmware image and uploaded it via the stock webinterface.

Failed to verify Rsa.

is dumped on serial console. Their core binary in the stock firmware seems to be really verifying it. With a hardcoded version of the key inside the binary, identical to the one in the firmware file, though.

I think you just have to append the rsa key at the end of the image. It is a fixed key that seems to be the same for all tp-link switches since forever.

The pubkey is in the jffs part but it seems to be not used by the binary handling the firmware upgrade. The last 128 bytes seems to be the signature created with tplinks private key? Or did I misunderstand something?

Yeah, i meant the signature in the last 128 bytes. you could check with various firmware files, but to me it looked as if the signature was generic and not actually dependend on the firmware. but maybe i mixed something up there during testing. can't currently check myself, i'm off to work.

Comparing the T1600G-18TSv2 with T1600G-28TSv3, the signature in the final 128 bytes is different. On the EAP2x5 devices it's possible to disable the signature check though. Anything similar in the code here?

On the EAP225v1 and EAP245v1 you needed to patch the binary that performs the upgrade. On later devices in that series you can just run cliclientd stopcs as an unprivileged user to disable the signature checks. :grinning_face_with_smiling_eyes:

Thanks for that information. On first glance it seems TP-Link does not include this feature on their switches. Was not able to find cliclientd nor stopcs in the firmware. I will check the application flow in the core binary in more detail after work.

Edit: Just checked the disassembly of the core binary. I don't see a way to skip the firmwareRsaSignVerify call at first glance.

I might have possibly compared an image to itself, it was very late when i wrote this. Sorry for the confusion. The eap devices run a custom openwrt if i remember correctly, the switches use something i cannot identify besides being a flavor of gnu/linux. Still waiting for the GPL-Sources

I added the code for GS1900-16
I don’t know if I should push
soc name..... errrr......

Since the firmware upload detour was not that great of a success I'm now back on the PHY patch issue. Do you see any chance that if I raw flash my openwrt image and also revert back to the stock uboot that the PHY patch errors go away? I'm asking this because the tplink firmware also prints patch errors and external PHY ports are not working when bootet by the full uboot image?

You don't push, you open a PR against master, which will get reviewed. From what I can tell the GS1900-16 isn't supported in master yet either, so you won't get this merged in 21.02. Support needs to go into master first, then might get backported to 21.02.

See the wiki:

I got my kernel flashed to mtdblock2 and squashfs flashed to mtdblock3 however while booting the kernel panics not finding its rootfs.

[   10.100635] /dev/root: Can't open blockdev
[   10.114409] VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
[   10.139287] Please append a correct "root=" boot option; here are the available partitions:
[   10.167100] 0100            4096 ram0 
[   10.167114]  (driver?)
[   10.187414] 0101            4096 ram1 
[   10.187424]  (driver?)
[   10.207803] 0102            4096 ram2 
[   10.207815]  (driver?)
[   10.228209] 0103            4096 ram3 
[   10.228220]  (driver?)
[   10.248614] 0104            4096 ram4 
[   10.248625]  (driver?)
[   10.269021] 0105            4096 ram5 
[   10.269032]  (driver?)
[   10.289423] 0106            4096 ram6 
[   10.289435]  (driver?)
[   10.309828] 0107            4096 ram7 
[   10.309839]  (driver?)
[   10.330232] 0108            4096 ram8 
[   10.330243]  (driver?)
[   10.350636] 0109            4096 ram9 
[   10.350648]  (driver?)
[   10.371041] 010a            4096 ram10 
[   10.371052]  (driver?)
[   10.391733] 010b            4096 ram11 
[   10.391744]  (driver?)
[   10.412427] 010c            4096 ram12 
[   10.412439]  (driver?)
[   10.433120] 010d            4096 ram13 
[   10.433131]  (driver?)
[   10.453845] 010e            4096 ram14 
[   10.453856]  (driver?)
[   10.474531] 010f            4096 ram15 
[   10.474542]  (driver?)
[   10.495224] 1f00             896 mtdblock0 
[   10.495235]  (driver?)
[   10.516978] 1f01             128 mtdblock1 
[   10.516989]  (driver?)
[   10.538807] 1f02            6144 mtdblock2 
[   10.538818]  (driver?)
[   10.560650] 1f03           10240 mtdblock3 
[   10.560661]  (driver?)
[   10.582493] 1f04           10240 mtdblock4 
[   10.582504]  (driver?)
[   10.604336] 1f05            4096 mtdblock5 
[   10.604348]  (driver?)
[   10.626091] 1f06            1024 mtdblock6 
[   10.626102]  (driver?)
[   10.647914] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[   10.675308] Rebooting in 1 seconds..
[   11.684962] System restart.

I tried adding rootfs=mtdblock3 and rootfs=/dev/mtdblock3 to the bootargs in uboot but still same result. Isn't this the correct place to define or has this already been defined while building the image?

Edit: Nevermind, was able to figure it out. Had the wrong label in my devicetree file. In the flash layout it was called userimg1 but it should be called rootfs in the devicetree file.

This needs to be defined in the .dts. The command line is not used for this. The rootfs is identified based on the name in the .dts. Have a look at the other .dts es examples.

1 Like

Well, tplink's stock uboot does not like to boot the openwrt image, only the full uboot version does.

@anon13997276 if I might come back to your earlier post regarding the PHY's:

By "connected to" you mean physically on the board from lan port (over magnetics) to pins on the PHY? I might be able to trace that out if that's of any help. How would I then hint this information to the driver, also via the devicetree file? I have to admit that this goes a bit beyond my comfort zone.

Or has this all to do with some strange uboot quirk tplink isn't telling us about since their stock firmware also can't operate the external PHY's when bootet from their full uboot built from their gpl source dump?

I was able to get a capture from the MDIO bus to the front panel's RTL8231 if that brings any additional insight?

1 Like

The stock firmware, both u-boot and the kernel use a fixed hardware description to identify which PHY are used that is compiled in. Mainline Linux/OpenWRT tries to auto-detect PHYs based on their PHY ids. If it is possible to configure this in the .dts then we are not using it for this target. The patching fails because our auto-detect fails (the u-boot configuration is irrelevant for OpenWRT) and for the stock-firmware because the configuration compile into u-boot does not match, or maybe you touched configuration variables somewhere in the flash?

What confuses me is that you state that the board model is RTL8382M_8218B_INTPHY_8218B_8214QF_DEMO
This would be a setup with

  • 8 Ports connected to an 8218B PHY (the bread-and-butter used everywhere in these switches)
  • 8 Ports connected to the internal PHY of the RTL8382M SoC
  • 8 Ports connected to second external 8218B PHY
  • 4 Ports connected via an RTL8214QF PHY
    But I am not able to find a board configuration for this in my TPLink sources, only one with an RTL8214FC, and I thought we had the latest version of this (they use a very old version of the SDK, namely v2, while recent Realtek devices use SDK v4) Are you sure it's in the u-boot source code you compiled? It should be somehere in this directory
t2500g-10ts_gpl/ldk_realtek/realtek_v2.1.4/u-boot-2011.12/board/Realtek/switch/rtk/conf/rtl8382m_8218b_intphy_8218b_8214fc_demo_board.c

Tracing lines is not necessary if we would have the hardware configuration file for this board.

Cool, thanks for the capture! I'll have look later, but I should be able to tell which registers are used. :slight_smile: