Adding OpenWrt support for TP-Link EAP245

I held a jumper wire directly on the unpopulated resistor point to see if I could get any output at all, but I couldn't see any from my FT2232H programmer. This device has so much potential for OpenWRT and I'm determined to get it working.

The EAP225v3 seems to have left a working UART pinout, according to someone on IRC. I've tried looking for other connections on the board with my voltmeter, but haven't been able to find any with a fluctuating voltage to indicate TX. I've even tried in reset mode by having the reset button permanently held down, which seems to initiate a tftp request.

Also, those unbridged points for the resistor seems to read 2.5v constantly. I wouldn't think an RX would output voltage like that? I could be wrong though..

For reference, there already is a non-mainlined port for the EAP245v1 available, which I have been running on my EAP245v1. j-d-r made a pull request to make support widely available, but since it needed to be flashed via the serial port, which required soldering, sadly this was rejected.

TP-Link "signs" their firmware images by adding a hash at the end of the binary files. There are already other TP-Link devices that incorporate this into their OpenWRT images, but this EAP245v1 port didn't. However, the official images for both the v1 and v3 access points contain this type of signature. This means it should probably be possible to make images for these access points that are easily flashable via their web interface.

Another point to note is that the EAP245v1 port required quite a bit of platform specific code.

Can the v1 version be fleshed through a SPI programmer?

What are the benefits of running OpenWRT over the stock firmware?

I'm very interested in OpenWrt for these and other AP's... What's the benefits? Seems like there would be little for an AP, but a strong benefit would be the advanced queuing and airtime fairness stuff of the make-wifi-fast project. See here https://forum.openwrt.org/t/aql-and-the-ath10k-is-lovely/59002 and other places. For a while some of this work has been in OpenWrt for ath9k radios, just now coming out for the ath10k ones, and a few others I think...

I've been running this on my C7 AP, snapshot of a month or so back, and it's nice to see my 5Ghz radio finally equally low in latency as my 2.4Ghz, and the rest of my cake sql managed network...

Also, I believe the EAP225 v3 is very close in hardware to the C7, which should make it easy, havent found yet what the EAP245 is made with.

Also the support of meshing.

The feature set of these APs is quite good now, but the early versions of the EAP245v1's firmware didn't support DFS channels or IPv6. OpenWrt can now also provide WPA3, whereas I doubt TP-Link (or other manufacturers) will ever backport this to their 11ac APs.

1 Like

Awesome that you're working on this! I was taking a look today on what it how I could go about porting openwrt to EAP245v3 too. I'm happy to be a beta tester if you ever need one! :slight_smile:

Have access to a scope? Its sometimes tough to tell, with just a meter. Port might not be very"chatty", meter might respond too slow to sense fast data, etc. I once found on a certain version of C7 but not others, that the data was being pulled too low or high, forget which, and had to add a lower value pullup to get it "up" enough for my serial port to talk to it... I was hooked up correctly, but just needed that. Would never have seen it without the scope.

I will second my own vote, :slight_smile: for the EAP225v3, besides being a champ in a Small Net Builder real world range test, it's down to $53 on Amazon...

1 Like

My main reasons for this is to support roaming with another OpenWRT device that I have, and the ability to enable other DFS channels that aren't currently available. Plus, TP-Link doesn't have the greatest track record for keeping firmware updates going, so I'd like to prolong the life of it. Plus it's a little challenge :slight_smile:

If it's similar hardware to the C7, maybe I'll try SPI flashing with that firmware to see what happens :slight_smile:

I don't have access to a scope yet, but I think it may be time to get one. There have been other project I've been working on that I wish I had one.

1 Like

I did happen to flash the uboot bootloader that j-d-r wrote and I noticed some strange LED activity on my device after that. This would seem to indicate that the bootloader is at least somewhat working. I'm hopefully going to experiment some more with this (time permitting).

Once you get the UART connected, you can probably log in as root with the password 'admin'. The whole system is (or used to be, at least) read-only, but maybe you can do some useful probing in the TP-Link FW.

I never got around to testing his improved u-boot and ath79 builds. I have the EAP245v1 in active use, so can't do much testing with it.

I got a scope and an EAP 245 v1.
If you want me do check anything just tell me.

I'm having another look at the latest TP-Link firmware for the EAP245v1, to see if we can get around the firmware upload validation and install/do whatever.

The System > User Account page doesn't properly sanitize the "New User Name" field before printf'ing it to a root shell. This means that if you choose as new username "a;telnetd -l /bin/sh&" you will get a root shell when telnetting to the device (default port 23). You could then restore the user account with a valid name (e.g. 'admin') to restore ssh access.

You can then

  1. chmod 777 /tmp
  2. upload the firmware to /tmp/upgrade.bin (user ssh+dd or telnet?),
  3. use uclited -u to upgrade the firmware.

When you upload a firmware via the web interface, it first gets put into /tmp/httpUploadFile.bin. I assume it is then moved to upgrade.bin when found to be valid. But I first want to make sure I have a properly formatted image before trying that :slight_smile:

Edit:
A safeloader image from j-d-r's ar71xx branch appears to be valid, but the upgrade crashes :frowning:

# uclited -u
uclited -u

Begin Debug Mode Fireware Upgrade
Upgrade fireware size is 5444227 bytes
Upgrade fireware md5 checksum is correct!
Process 24759 Catch signal 11: 
  code = 1      errno = 0
Dump regs:
   pc: 76fa076c  
 zero: 00000000     at: 00c23982     v0: 7f8f10f8     v1: 00000000  
   a0: 7f8f10f8     a1: 00000000     a2: 00000014     a3: 00000a40  
   t0: 00000014     t1: 00000000     t2: 00000001     t3: 00565eb3  
   t4: fffffffe     t5: 00000001     t6: 00000000     t7: 00000400  
   s0: 7f8f10f8     s1: 00000003     s2: 00000020     s3: 00000030  
   s4: 0057a5dc     s5: 007ac580     s6: 00000005     s7: 007ac580  
   t8: 00000010     t9: 76fa0720     k0: 0a0a0a0a     k1: 00000000  
   gp: 005b2610     sp: 7f8f10c0  fp/s8: 00000003     ra: 004c05f0  
Dump mem stack: 
 (STACK: 0x7f8d2000 ~ 0x7f8f3000 SP: 0x7f8f10c0)
 0x7f8f10c0: 00000000 00000000 00000000 00000000 005b2610 00000000 00000000 004c5e2c 
 0x7f8f10e0: 00000000 00000000 00000000 00000000 005b2610 00000000 00000000 00000000 
 0x7f8f1100: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f8f1120: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f8f1140: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f8f1160: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f8f1180: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f8f11a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f8f11c0: ......
Dump call stack:
  #00  pc 0002d76c  /lib/libuClibc-0.9.30.so (memcpy+76)
  #01  pc 000c05e8  /usr/bin/uclited (ucCluster_getCfg+40)
  #02  pc 000c5e24  /usr/bin/uclited (swIsClusterMode+64)
  #03  pc 000d1a1c  /usr/bin/uclited (nm_checkUpdateContent+668)
  #04  pc 000d2264  /usr/bin/uclited (nm_buildUpgradeStruct+1268)
  #05  pc 00137f58  /usr/bin/uclited (uclite_upgrade_debug+520)
  #06  pc 00138214  /usr/bin/uclited (main+276)
  #07  pc 0004f858  /lib/libuClibc-0.9.30.so (__uClibc_main+600)
Exiting...

Edit 2:
uclited -u doesn't work with a TP-Link image either, so that won't be very useful.

3 Likes

I was able to flash u-boot-mod from the TP-link firmware. Since the u-boot partition mtd0 is exposed as a writable block device via /dev/mtdblock0, it might be possible to just dd an image to that partition, but after some reading, I didn't feel like that was a great idea. It might work and not be an issue at all, but someone else will have to weigh in on this.

To flash the modded u-boot, I cross compiled flashcp and flash_erase from mtd-utils (v2.0.2), using the TP-Link provided toolchain. I had to set up a CentOS 6 (must be i386) VM to run the toolchain. After installing zlib-devel and the "development tools" group, make could be run as described in TP-Link's readme.txt. The GPL sources don't seem to be available anymore for the EAP245v1, but I still have a copy. The GPL sources can be found at TP-Link's GPL code center.

# flash_erase /dev/mtd0 0 0
flash_erase /dev/mtd0 0 0
libmtd: error!: ECCGETLAYOUT ioctl request failed
        error 122 (Operation not supported)
Erasing 64 Kibyte @ 100
# flashcp uboot.bin /dev/mtd0
flashcp uboot.bin /dev/mtd0
00 -- 100 % complete 

And now I can flash OpenWrt from the u-boot web interface :slight_smile:

I don't know if this would be sufficient to get EAP245v1 support accepted, now that you don't need to solder to flash OpenWrt. I still did a u-boot upgrade and needed to upload extra software. Note that there are no mtdX character devices other than mtd0, so flashing OpenWrt directly from the TP-Link firmware would require some extra work (and making very sure you're running everything from RAM while you overwrite the root filesystem).

4 Likes

This is EAP245v3 hardware:

So I was able to get OpenWRT kernel booting. I still have a long way to go, but it's a start.

The TP-Link bootloader requires all images to be signed using their key, so I couldn't use the tftp recovery method :frowning:

On the underside of the board, there's a unpopulated R225 resistor that was able to connect to to get 115200 baud 8n1 UART output. I need to bridge solder it, but it at least works by holding a jumper wire against it.

I then created a custom U-Boot image with j-d-r's https://github.com/j-d-r/u-boot-QCA956x. Network doesn't seem to work, so I wasn't able to get a web recovery console, even though it was listening on 192.168.1.1. It detects when a cable is plugged in, but it won't bring up a network stack. It's something else for me to look at as well.

I switched the BOOTCOMMAND to "bootm 0x9f0c0000". It was set to "bootelf" before, which works with the existing TP-Link image (it's an ELF image). Because I'm booting an OpenWRT initramfs, I needed to change to "bootm 0x9f0c0000".

Then I overwrote the original image that I dumped from SPI (using dd) with the u-boot image I crafted and the Archer c7 v5 OpenWRT initramfs kernel image I compiled. Then I took this crafted image and flashed it onto my EAP245v3 with my SPI programmer.

Here's output from my UART console (ignore the versioning, I didn't get around to changing it):

***************************************
*     U-Boot 1.1.4-90b788c2-dirty     *
*          Build: 2020-05-28          *
***************************************

** Warning: bad env CRC, using default,
   use 'saveenv' to save it in FLASH

  BOARD: TP-Link EAP245 v1
    SOC: QCA956x rev. 0
    CPU: MIPS 74Kc
    RAM: 128 MB DDR2 16-bit CL6-5-5-13
  FLASH: 16 MB Winbond W25Q128
   PCIe: QCA99X0
    MAC: 00:DE:AD:BE:EF:00
   UART: 111607 bps   
 CLOCKS: CPU/RAM/AHB/SPI/REF
         775/650/258/ 18/ 25 MHz

Hit any key to stop booting:  0

Booting image from 0x9F0C0000...

   Image name:    MIPS OpenWrt Linux-4.14.171
   Build date:    2020-02-27 21:05:12 UTC
   Architecture:  MIPS
   OS/image type: Linux Kernel
   Compression:   LZMA
   Data size:     3.5 MB (3659176 bytes)
   Load address:  0x80060000
   Entry point:   0x80060000

   Header CRC...  OK!
   Data CRC...    skipped

Stopping network... OK!
Uncompressing Kernel... OK!
Starting kernel...

[    0.000000] Linux version 4.14.171 (root@edca4f546068) (gcc version 7.5.0 (OpenWrt GCC 7.5.0 r10947-65030d81f3)) #0 Thu Feb 27 21:05:12 2020
[    0.000000] bootconsole [early0] enabled
[    0.000000] CPU0 revision is: 00019750 (MIPS 74Kc)
[    0.000000] SoC: Qualcomm Atheros QCA956X ver 1 rev 0
[    0.000000] Determined physical RAM map:
[    0.000000]  memory: 08000000 @ 00000000 (usable)
[    0.000000] Initrd not found or empty - disabling initrd
[    0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes.
[    0.000000] Primary data cache 32kB, 4-way, VIPT, cache aliases, linesize 32 bytes
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000000000000-0x0000000007ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x0000000007ffffff]
...............

I do get some errors about network devices not being initialized, but I'll work on that.

So yeah.. progress :slight_smile:

5 Likes

I was looking at the GPL sources for the EAP245v3 yesterday to see just how different it is from the v1. It might actually no longer be necessary to replace the bootloader to get proper network initialization. In fact, there is now a platform specific architecture file mach-eap245v3.c. This is quite different from the mach-ap152.c file used by the v1. The main difference being that there is no longer any custom SERDES/ethernet initialization. I had a look at the entire diff for the included kernel tree (it's not that long), but didn't immediately see that code anywhere else. That means that it might be included in their u-boot version now.

Fun fact: The EAP245v3 sources also refer to an EAP245v2, whose code is more like the v1 than the v3. To my knowledge, the EAP245v2 never made it to the market (no FCC ID either).

It's true, but the factory bootloader does an RSA key check against the image before it will allow it to boot. If the signature doesn't match, then it fails.

There may be a way to bypass that, but I haven't tried that yet.

I saw that! I actually copied it over to my OpenWRT fork to see if I can get a build going of it. The EAP245v3 hardware seems very similar to the Archer C7 v5, so I'm starting with that as a starting point and merging in diffs from the GPL Sources provided by TP-Link for the EAP245v3 :slight_smile: I have no idea how far I'll get with this, but it's a start.

Sorry I missed that in your earlier reply! That doesn't sound too good though...

Doesn't the C7v5 have a QCA9880 like the EAP245v1? Although (I would think) the wireless hardware probably doesn't matter too much for u-boot. I have an EAP245v3 on the way, so I can also start poking at it.