Adding support for TP-Link WPA8631P V3.0

Hi,

This thread covers supporting the TP-Link WPA8631P V3.0.

I added some pull requests for this device:

http://lists.openwrt.org/pipermail/openwrt-devel/2022-February/038075.html

Everything appears to be working.

Compared to the WPA8630P v2:

  • The SoC is an ramips MT7621, previous was ath79 QCA9563
  • The RAM is only 64MiB, previous was 128MiB
  • The partition scheme is much more sensible and uniform on this device (thanks TP-Link:), so support should be a lot easier.
  • There is 7MiB available to OpenWRT, previous was 6MiB

If anyone would like to ALPHA test some images, let me know and I can send you a built image. You will need an SOIC-8 flash programmer on-hand (or SOIC-8 clip and Raspberry Pi) to recover in case something goes wrong, as there doesn't appear to be any built-in TFTP recovery on these units. If you don't have one, it's better to wait until the official images are released as during testing you may end up with a bricked unit.

You must get a pinctrl related error on the latest snapshot since rgmii2 pins are used as GPIO on the device. Can you check this over serial?

The input buttons and output LEDs were all working fine when I built from snapshot a week ago. Has something changed recently? Can you tell me how to check? I'll try a fresh build over the next few days.

I just copied this section from similar devices:

&state_default {
	gpio {
		groups = "rgmii2", "wdt";
		function = "gpio";
	};
};

Yes:

On snapshots that include the commit above, there will be pinctrl errors on the bootlog preventing the device from initialising the ethernet driver. pinctrl-0 property needs to be overwritten without claiming the rgmii2 pin group for the ethernet node.

I also don't see wdt pin (18) used anywhere on the devicetree. We can also remove that. For further reference check here:
https://github.com/torvalds/linux/blob/master/drivers/pinctrl/ralink/pinctrl-mt7621.c

I can send a patch to address these.

Ok, looks like it needs that update, here is the current snapshot:

[    1.219649] rt2880-pinmux pinctrl: pin io22 already requested by pinctrl; cannot claim for 1e100000.ethernet
[    1.239347] rt2880-pinmux pinctrl: pin-22 (1e100000.ethernet) status -22
[    1.252722] rt2880-pinmux pinctrl: could not request pin 22 (io22) from group rgmii2  on device rt2880-pinmux
[    1.272483] mtk_soc_eth 1e100000.ethernet: Error applying setting, reverse things back
[    1.288290] mtk_soc_eth: probe of 1e100000.ethernet failed with error -22

Are you saying gpio { groups = "wdt" is only needed when GPIO pin 18 is used by a button? If so, it looks like the following devices also have that issue:

$ grep -L "&gpio 18" $(grep -l 'groups.*=.*"wdt"' mt7621_*)
mt7621_adslr_g7.dts
mt7621_elecom_wrc-gs-1pci.dtsi
mt7621_elecom_wrc-gs-2pci.dtsi
mt7621_mikrotik_routerboard-750gr3.dts
mt7621_mikrotik_routerboard-760igs.dts
mt7621_mikrotik_routerboard-m11g.dts
mt7621_mikrotik_routerboard-m33g.dts
mt7621_tplink_re350-v1.dts
mt7621_tplink_tl-wpa8631p-v3.dts
mt7621_xiaomi_mi-router-3g.dts
mt7621_xiaomi_mi-router-4.dts
mt7621_xiaomi_router-ac2100.dtsi
mt7621_zyxel_nr7101.dts

Thanks, that would be great, thanks for catching this!

Not exactly. The magic word here is GPIO, if a pin is used as general purpose input/output which could connect an LED, button, etc., that pin needs to be given the gpio function. Since we can't do this for each pin individually, we do this for the pin group instead.

One important detail is that not all the pins which are used as GPIO on the device will be defined on the devicetree. Best way to check is to take a look at the firmware tarball of the company, find the file where GPIO specification of the device is documented.

Here's Asus RT-AC88U's GPIO spec, different target but still a good example:

Would you like to help me correct them? I've been looking over ways with grep/sed/awk to automatically check and correct the inconsistencies on ~120 files. I have more details as to how, if you're interested.

I wouldn't be comfortable doing tree-wide changes TBH :grin:, seems better suited for one of the ramips maintainers. To get this device working, I just copied&pasted similar DTS files based on matching hardware, referencing OEM docs and testing out on my local device to check everything worked. If you want, I can submit the patch to fix this unit's Ethernet, and the cleanup can be done later seperately.

Well, I am. :slight_smile: I plan to maintain mt7621 devicetrees on upstream so I want to prepare the devicetrees on OpenWrt to be included on upstream. I have an upcoming feature patch along with better pinctrl definitions.

I just need someone with grep/awk/sed expertise to make the changes more easily.

Sounds good. Put it right above &gmac0 and remove wdt pin group from &state_default as discussed.

Here's my tag to be included on the patch log:
Reported-by: Arınç ÜNAL <arinc.unal@arinc9.com>

PRs has been merged a few days ago. Wiki page added.

This should be production-ready once 22.03 is released. I'll keep this thread open while we are testing the 22.03 release on it, then close it if everything looks good.

1 Like

Thank you @jwmullally. I installed the snapshot on my WPA8631P few days ago. Works great so far.
I tried to also install luci but there was not enough space.

1 Like

You can grab the 22.03-SNAPSHOT images here, which include LuCI and have ~290k free.

*Warning for the thread: until the official release is made, snapshot images can brick your device. See the warning at the top of this post. If you are using snapshot, 22.03-SNAPSHOT is much safer than regular SNAPSHOT!

@xavierly , to "downgrade" from /master SNAPSHOT to 22.03, I suggest using sysupgrade -n to flush all old config, in case some config has changed recently since the branch.

1 Like

Installed the 22.03-SNAPSHOT with LuCI. Reconfigured all the SSID and VLANs. Working great. Thank you @jwmullally for making this possible.

Hello. I just bricked my unit and now it's some kind of endless boot loop. Looks like the boot loader chooses automatically option 3 and I don't have any idea how can I choose another option to upload new image. Any ideas? (Well... Just ordered SOIC-8 clip but at the moment I don't have any experience how to use that with Raspberry Pi.)

===================================================================
                MT7621   stage1 code Mar 12 2015 14:43:30 (ASIC)
                CPU=500000000 HZ BUS=125000000 HZ
==================================================================
Change MPLL source from XTAL to CR...
do MEMPLL setting..
MEMPLL Config : 0x11000000
3PLL mode + External loopback
=== XTAL-40Mhz === DDR-800Mhz ===
PLL3 FB_DL: 0xc, 1/0 = 550/474 31000000
PLL2 FB_DL: 0xe, 1/0 = 527/497 39000000
PLL4 FB_DL: 0x18, 1/0 = 639/385 61000000
do DDR setting..[01F40000]
Apply DDR2 Setting...(use default AC)
          0    8   16   24   32   40   48   56   64   72   80   88   96  104  112  120
      --------------------------------------------------------------------------------
0000:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0001:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0002:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0003:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0004:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0005:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0006:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    1    1
0007:|    0    0    0    0    0    0    1    1    1    1    1    1    1    1    1    1
0008:|    1    1    1    1    1    1    1    1    1    1    1    1    1    0    0    0
0009:|    1    1    1    1    1    0    0    0    0    0    0    0    0    0    0    0
000A:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
000B:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
000C:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
000D:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
000E:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
000F:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0010:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0011:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0012:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0013:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0014:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0015:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0016:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0017:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0018:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
0019:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
001A:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
001B:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
001C:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
001D:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
001E:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
001F:|    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
DRAMC_DQSCTL1[0e0]=1A000000
DRAMC_DQSGCTL[124]=80000000
rank 0 coarse = 8
rank 0 fine = 48
B:|    0    0    0    0    1    1    1    0    0    0    0    0    0    0    0    0
opt_dle value:5
DRAMC_DDR2CTL[07c]=40001253
DRAMC_PADCTL4[0e4]=00000005
DRAMC_DQIDLY1[210]=0B0C0A0B
DRAMC_DQIDLY2[214]=090B0B09
DRAMC_DQIDLY3[218]=0A0A0907
DRAMC_DQIDLY4[21c]=09090A06
DRAMC_R0DELDLY[018]=00002D2D
==================================================================
                RX      DQS perbit delay software calibration 
==================================================================
1.0-15 bit dq delay value
==================================================================
bit|     0  1  2  3  4  5  6  7  8  9
--------------------------------------
0 |    9 8 11 11 9 7 9 7 7 7 
10 |    9 9 6 9 9 9 
--------------------------------------

==================================================================
2.dqs window
x=pass dqs delay value (min~max)center 
y=0-7bit DQ of every group
input delay:DQS0 =45 DQS1 = 45
==================================================================
bit     DQS0     bit      DQS1
0  (1~85)43  8  (2~89)45
1  (1~86)43  9  (0~86)43
2  (1~87)44  10  (1~88)44
3  (1~89)45  11  (1~88)44
4  (1~89)45  12  (1~90)45
5  (1~82)41  13  (1~88)44
6  (1~86)43  14  (1~89)45
7  (1~86)43  15  (2~89)45
==================================================================
3.dq delay value last
==================================================================
bit|    0  1  2  3  4  5  6  7  8   9
--------------------------------------
0 |    11 10 12 11 9 11 11 9 7 9 
10 |    10 10 6 10 9 9 
==================================================================
==================================================================
     TX  perbyte calibration 
==================================================================
DQS loop = 15, cmp_err_1 = ffff0000 
dqs_perbyte_dly.last_dqsdly_pass[0]=15,  finish count=1 
dqs_perbyte_dly.last_dqsdly_pass[1]=15,  finish count=2 
DQ loop=15, cmp_err_1 = ffff0000
dqs_perbyte_dly.last_dqdly_pass[0]=15,  finish count=1 
dqs_perbyte_dly.last_dqdly_pass[1]=15,  finish count=2 
byte:0, (DQS,DQ)=(8,8)
byte:1, (DQS,DQ)=(8,8)
DRAMC_DQODLY1[200]=88888888
DRAMC_DQODLY2[204]=88888888
20,data:88
[EMI] DRAMC calibration passed

===================================================================
                MT7621   stage1 code done 
                CPU=500000000 HZ BUS=125000000 HZ
===================================================================


U-Boot 1.1.3 (Mar 30 2022 - 14:28:15)

Board: Ralink APSoC DRAM:  64 MB
relocate_code Pointer at: 83fb8000

Config XHCI 40M PLL 
flash manufacture id: 20, device id 70 17
Warning: un-recognized chip ID, please update bootloader!
*** Warning - bad CRC, using default environment




===========================TL-WPA8631Pv3 PERSET GPIO init in uboot=========================
read register GPIO_MODE(0xbe000060), value = 0x0004d52c
set register GPIO_MODE(0xbe000060), value = 0x0004d52c
read register GPIO_CTRL_0(0xbe000600), value = 0x35c00000
set register GPIO_CTRL_0(0xbe000600), value = 0x35c80000
read register GPIO_DATA_0(0xbe000620), value = 0xc83de81c
set register GPIO_DATA_0(0xbe000620), value = 0xc835e81c
=========================TL-WPA8631Pv3 PERSET GPIO init in uboot done==========================


============================================ 
Ralink UBoot Version: 4.3.0.0
-------------------------------------------- 
ASIC MT7621A DualCore (MAC to MT7530 Mode)
DRAM_CONF_FROM: Auto-Detection 
DRAM_TYPE: DDR2 
DRAM bus: 16 bit
Xtal Mode=3 OCP Ratio=1/4
Flash component: SPI Flash
Date:Mar 30 2022  Time:14:28:15
============================================ 
icache: sets:256, ways:4, linesz:32 ,total:32768
dcache: sets:256, ways:4, linesz:32 ,total:32768 

 ##### The CPU freq = 880 MHZ #### 
 estimate memory size =64 Mbytes
#Reset_MT7530
=========TL-WPA8631Pv3 GPIO init in uboot=========
RALINK_PIO_BASE(0xbe000600) Reg: 0x4852c
RALINK_PIO_BASE + 4(0xbe000604) Reg: 0x0
RALINK_GPIOMODE_REG(0xbe000060) Reg: 0x4852c
=========TL-WPA8631Pv3 GPIO init in uboot done=========

Please choose the operation: 
   1: Load system code to SDRAM via TFTP. 
   2: Load system code then write to Flash via TFTP. 
   3: Boot system code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial. 
   9: Load Boot Loader code then write to Flash via TFTP. 

You choosed 3

 0 
   
3: System Boot system code via Flash.
(ntohs(targetModel[0]) : 0x0376, ntohs(value[0]) : 0x0376
(ntohs(targetModel[1]) : 0x6376, ntohs(value[1]) : 0x6376
## Booting image at bfc20000 ...
text base: ffffffff
entry point: ffffffff
   Uncompressing Kernel Image ... LZMA ERROR 1 - must RESET board to recover

If you send "1" or "2" when seeing that menu, it should immediately respond. It sounds like a problem with the TX line of your serial connection? (Or maybe serial settings, flow control etc). A regular 3.3V FTDI cable works for me. Can you send me a pic of your connection? I'll try upload a working one to the wiki. According to other forum posts here for MT7621 devices, it should be possible to boot the OpenWrt initramfs image using option 1.

Be careful when using an SOIC-8 clip on this device. Surrounding the flash chip are many tiny SMT components which are extremely easy to knock off just by brushing the connector off them, which killed an earlier device I had. The Pomona clips are high quality so should be OK to use. I was using an "KeeYees SOP8 SOIC8 Test Clip and CH341A USB Programmer". The USB programmer is great, but the tips of the SOIC-8 connector are not so good and need alot of jiggling around to get it to fit right, which is where I knocked off those SMT resistors/caps.

What caused the device to be bricked? Which OpenWrt version/commit, steps you took etc. Just want to make sure there is no problems with the upcoming release, as you can see its a pain to recover this device without automatic TFTP boot :frowning:

No luck with pressing keys. I can see that keystrokes are going to terminal screen via ttl serial. (without tx pin there is no output characters so I'm pretty sure that USB TTL cable works.) It seems that the default option 3 timeout is too short or fixed value. Anyway it's impossible to choose anything.

I just got SOIC-8 clip and after all it seems to work with Raspberry Pi:

sippe@raspberrypi:~ $ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=2000 -V
...
===
SFDP has autodetected a flash chip which is not natively supported by flashrom yet.
All standard operations (read, verify, erase and write) should work, but to support all possible features we need to add them manually.
You can help us by mailing us the output of the following command to flashrom@flashrom.org:
'flashrom -VV [plus the -p/--programmer parameter]'
Thanks for your help!
===
Found Unknown flash chip "SFDP-capable chip" (8192 kB, SPI) on linux_spi.
Probing for AMIC unknown AMIC SPI chip, 0 kB: probe_spi_rdid_generic: id1 0x20, id2 0x7017
Probing for Atmel unknown Atmel SPI chip, 0 kB: probe_spi_rdid_generic: id1 0x20, id2 0x7017
Probing for Eon unknown Eon SPI chip, 0 kB: probe_spi_rdid_generic: id1 0x20, id2 0x7017
Probing for Macronix unknown Macronix SPI chip, 0 kB: probe_spi_rdid_generic: id1 0x20, id2 0x7017
Probing for PMC unknown PMC SPI chip, 0 kB: probe_spi_rdid_generic: id1 0x20, id2 0x7017
Probing for SST unknown SST SPI chip, 0 kB: probe_spi_rdid_generic: id1 0x20, id2 0x7017
Probing for ST unknown ST SPI chip, 0 kB: probe_spi_rdid_generic: id1 0x20, id2 0x7017
Probing for Sanyo unknown Sanyo SPI chip, 0 kB: probe_spi_rdid_generic: id1 0x20, id2 0x7017
Probing for Winbond unknown Winbond (ex Nexcom) SPI chip, 0 kB: probe_spi_rdid_generic: id1 0x20, id2 0x7017
Probing for Generic unknown SPI chip (RDID), 0 kB: probe_spi_rdid_generic: id1 0x20, id2 0x7017
Probing for Generic unknown SPI chip (REMS), 0 kB: probe_spi_rems: id1 0x20, id2 0x16
Found Unknown flash chip "SFDP-capable chip" (8192 kB, SPI).
No operations were specified.

At the moment I am little lost because I don't have clever idea how to make correct flash operation so I'm asking help to make correct steps with flashrom.

Reading works fine:

sippe@raspberrypi:~ $ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=2000 -r bricked_tp-link.bin
flashrom v1.2 on Linux 5.15.32-v8+ (aarch64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
===
SFDP has autodetected a flash chip which is not natively supported by flashrom yet.
All standard operations (read, verify, erase and write) should work, but to support all possible features we need to add them manually.
You can help us by mailing us the output of the following command to flashrom@flashrom.org:
'flashrom -VV [plus the -p/--programmer parameter]'
Thanks for your help!
===
Found Unknown flash chip "SFDP-capable chip" (8192 kB, SPI) on linux_spi.
Reading flash... done.

If I try to write something flashrom says that binary file is too small:

sippe@raspberrypi:~ $ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=2000 -w openwrt-ramips-mt7621-tplink_tl-wpa8631p-v3-squashfs-factory.bin
flashrom v1.2 on Linux 5.15.32-v8+ (aarch64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
===
SFDP has autodetected a flash chip which is not natively supported by flashrom yet.
All standard operations (read, verify, erase and write) should work, but to support all possible features we need to add them manually.
You can help us by mailing us the output of the following command to flashrom@flashrom.org:
'flashrom -VV [plus the -p/--programmer parameter]'
Thanks for your help!
===
Found Unknown flash chip "SFDP-capable chip" (8192 kB, SPI) on linux_spi.
Error: Image size (6617623 B) doesn't match the flash chip's size (8388608 B)!

You asked how I bricked my device. Well... It was stupid brainfart. I tried to install ssl-luci and it was too big to write to flash drive. Then I wondered that easiest way is flash openwrt-ramips-mt7621-tplink_tl-wpa8631p-v3-squashfs-factory.bin again via command line and now I am here with my tiny and cute bricked device. :upside_down_face:

Here is the setup at the moment:

Did you manage to read your entire flash? What you'll need to do is backup that image (it has your device's unique radio calibration values, MAC addresses, serial numbers etc), then repair it using dd to write in a good kernel and rootfs. Either the OEM or OpenWrt images. You just need to make sure the addresses line up with the flash's partition table. Then you can flash back the entire image.

E.g. Get a working OpenWrt Kernel and Rootfs partition contents using ImageBuilder tools:

$ staging_dir/host/bin/tplink-safeloader -x bin/targets/ramips/mt7621/openwrt-22.03.0-rc1-ramips-mt7621-tplink_tl-wpa8631p-v3-squashfs-factory.bin -d extracted
$ ls extracted
file-system  os-image  partition-table  soft-version  support-list
$ cat extracted/partition-table
...
partition os-image base 0x20000 size 0x291e07
partition file-system base 0x2c0000 size 0x450000
...
$ dd if=extracted/os-image of=flash.img bs=1 seek="$(printf '%d\n' 0x20000)" conv=notrunc
$ dd if=extracted/file-system of=flash.img bs=1 seek="$(printf '%d\n' 0x2c0000)" conv=notrunc

If your flash image is completely hosed, I can send you the backup I took of mine, but you'll lose your calibration data, MAC addresses, etc unless you do more surgery on the image.

Ah yeah, sysupgrade is very basic but it does include some metadata to do a device model safety check before flashing, unless --force is given. In this case it would have written the OEM-format upgrade image (including header etc) over where the Linux kernel goes. sysupgrade should work smoothly (and without --force) with the -sysupgrade.bin file.

Edit: Add dd examples.


In general, as this device needs to be disassembled to recover from broken boot situations, people should be very careful when using ImageBuilder as its possible to build images that don't actually boot (e.g. removing critical packages or breaking boot). If you don't want to brick and flash your device, just stick with the default OpenWrt images :slight_smile:

1 Like

Hello again.

Just wondering how to fit snmpd and poweline management to image... Is it even possible? 8Mb is almost too tiny to try features like this... :roll_eyes:

It's outside the scope of this thread (there should be a few other threads here with good info), but you can check out these wiki guides:

I find -ppp -ppp-mod-pppoe is the most practical, the rest start cutting into core functionality. Baking the packages into the image instead of installing later can also reduce the size with better compression/packing, especially for packages with many small files (luci etc).

1 Like

Everything tests OK on 22.03-rc4, so should be ready to use once 22.03 is released.

2 Likes

Ok, I know this thread is a bit old now but, I have a v3 device and have pulled it apart! I have found J1, I'm assuming this is the Serial UART? My question is, is it possible to flash OpenWRT via serial RS232?

Is there a good guide on how to do so?

Thanks in advance!