TL;DR: the problem is usually in corrupted data in SPI NAND flash, you need to download the original config data and flash back working modem firmware.
I noticed there is quite a lot of offers with used not working 4G router TL-MR100 in aukro.cz . I bought one with hope I can easily fix and use it. But the fix turned out to be not that easy.
The router boots, shows WiFi network, you can connect to it but the problem is that the web management doesn’t work. I’ve found out that the device consists of two interconnected systems:
– MT7628AN SoC providing WiFi and Ethernet
– some “NezhaC” 4G modem providing web management and mobile connectivity via USB interface
The first one was working fine but its logs were showing problems to communicate with the modem and indeed – the modem was not booting. I de-soldered the flash dedicated to the modem and tried to dump it but there were ECC errors and the data was damaged. So I obtained another working device to get a working flash contents and it worked: I dumped the whole flash, flashed to my broken one and I’ve got a clone of the working one (including IMEI which is quite a problem).
From the logs I discovered, that there is only a short block (0x20000 – 0x60000) containing device specific data (IMEI, calibration, configuration,…) so I copied the block from my broken device over to the working image and… Great success!
I also found (J10: 115200, 1-Tx, 2-Rx, 3-GND) an UART interface of the modem (I had to buy 1.8V compatible USB-TTL adapter) and I could see the modem booting:
0x00000000 PMIC ID: 0x00000013 Cold power up switch clk to XO NO Production Mode GuiLin Buck1 active voltage Reg: 0x00000098 GuiLin Buck1 active voltage Reg: 0x0000009c cpcore -> 624M AXI -> 208M DDR -> 1066M FlashNumber: 0x0000001a Bus clock: 13MHz QSPI_CLK_RES_CTRL: 0x5b tx_desc: 0x7c188e0 use_intr=1 en_tx_dma=1 use_xip=1 SPI-NAND: GD5F1GQ4RBxIG is found in table SPI-NAND type mfr_id: c8, dev_id: c1 Set rx_pins: 4 tx_pins: 4 AHB data transfer size: 512 XIP Read mode enabled Fixed LUT bit-map: 0x3fc block_size=0x20000 page_size=0x800 bitflip_threshold=6 Bus clock: 78MHz QSPI_CLK_RES_CTRL: 0x19b pFlashP->NumBlocks: 1020 Tr069 Config Init Done BoardType: 0x00000000 PlatformCI2Ready PlatformCI2Ready end Wait for USB ready USB Enum timeout Allow to boot up LTG_LWG_Version_Flag: 0xffffffff No need to upgrade TR069 return 0x00000001 LWG/LTG switch flag 0xffffffff Select to 3Mnde LWG CRC check OK with flash address 0x00020000 MRD FlashAddress Passed to CP: 0x00020000 CRC check OK with flash address 0x00040000 LWG uboot Primary/Backup MRD are both OK cpcore -> 208M DDR -> 533M end... 0 buadrate=0 UART Boot Completed 0 GPIOPhase2Init:[zc]---Before set ICU GPIO_INT 30 0 FPIOPhase2Init:[zc]---After set ICU GPIO_INT 3f 0 UsimDetectTaskEntry:enter 1 GPIOPhase2Init:[zc]---Usim_Detect_Gpio default level =0 2 Board Type: NezhaC MIFI DKB 2 Project Type: Nezha PCIE Dongle 3 PMIC Type: 88PM801/Ustica 4 Mode Type: LWG Only 4 BSP board type: 0x0 4 Software version: NEZHAC_CP_1.064.004 Jan 17 2021 15:26:46 5 Compilation date: Jan 17 2021 and time: 15:26:46 6 Last time is not silent reset 7 Sildnt Reset Magic =f55555d5 55155d5d 8 ======= CIU register ======= 8 0xd4282d00: 0x2 9 0xd4282d04: 0x100 9 0xd4282d08: 0x0 9 0xd4282d38: 0x0 a 0xd4282d3c: 0x0 a 0xd4282d40: 0x0 a 0xd4282d44: 0x100 b 0xd4282d48: 0x80010 b 0xd4282d4c: 0x20000 b OBM set Flash type: SPI Nand c Manufacture ID: 0xc8, Device ID: 0xc1 d SPINAND is already unprotected, protection 0x0 e sn_feature: 0x11 e Flash Type: 8, NumBlocks: 1020, BlkSize: 131072, PageSize: 2048 10 FlashManager_Init:Version= 30400 11 [BBT: 0] 11 FlashManager_Init done 11 BlockCacheCount 3, FlashBlockSize 131072 22 BMT0 Version 0x73 32 BMT1 Version 0x72 32 [Version 0x73] The next update partition 1 42 FATTable1=2, FATTable2=25, FATsecs=23, MaxClusters=6140 43 RootSector=32, SecPerClust=16, UserData=82, RootDirectory=48 44 Read guard sector 80 55 psm header size:0x20, buffer addr:0x79b0014 56 flash addr:0x40e0000 5e flash addr:0x40e0000, ddr addr:0x7138680 5e magic num:0x5a5a5a5a,0xefefefef 5f flash addr:0x4100000 67 flash addr:0x4100000, ddr addr:0x71386e0 68 blk_num:1,len:0x0 68 flash addr:0x4120000 70 flash addr:0x4120000, ddr addr:0x7138740 71 blk_num:2,len:0x0 71 flash addr:0x4140000 79 flash addr:0x4140000, ddr addr:0x71387a0 7a blk_num:3,len:0x45b 7a psm file is not NULL 7a psm_block_init, file_num is 0,blk1 is 3 7b psm_block_init psm_fdi_info[0] is 3 7c psm_block_init, file_num is 1,blk1 is 1 7d psm_block_init psm_fdi_info[1] is 1 7d psm_block_init, file_num is 2,blk1 is 2 7e psm_block_init psm_fdi_info[2] is 2 ab BOOTING COMPLETED
There is also list of supported SPI NANDs in the firmware:
GD5F1GQ4RBxIG – this is ours
GD5F2GQ4RBxIG
W25N01GWxxIx
W25N02GWxxIx
DS35M1GAxx
ZD35M1GAxx
PN26Q01AWSIUG
F50D1G41LB
MT29F1G01ABBFD
How to fix your device
Download my repo with tools: https://github.com/danielkucera/tl-mr100-fix
Remove the top cover of your device – I haven’t found a way to open it without breaking tabs, maybe you will have more luck than me:
De-solder the flash – I use a hot plate because there is a huge GND pad on the bottom side of the flash:
I use 1.27mm pin headers to conveniently plug/unplug the flash to my programmer so I always solder an adapter board and the connector. I started using a self-made WSON8 adapter board with pogo-pins. The flash is supposed to work with 1.8V VCC but it happily works on 3.3V too.
Next, it’s time to dump the original NAND contents:
You can use SNANDer to dump the NAND. By default, you will probably see this message because your flash is corrupted:
$ ~/Apps/SNANDer/src/SNANDer -r nand-230104.bin SNANDer - Serial Nor/nAND/Eeprom programmeR v.1.7.5 by McMCC <mcmcc@mail.ru> Found programmer device: WinChipHead (WCH) - CH341A Device revision is 3.0.4 spi_nand_probe: mfr_id = 0xc8, dev_id = 0xc1, dev_id_2 = 0xc8 Get Status Register 1: 0x00 Get Status Register 2: 0x01 Using Flash ECC. Detected SPI NAND Flash: GIGADEVICE GD5F1GQ4UA, Flash Size: 128 MB READ: Read addr = 0x0000000000000000, len = 0x0000000008000000 [spinand_ecc_fail_check] : ECC cannot recover detected !, page = 0x31 spi_nand_read_page: Bad Block, ECC cannot recovery detecte, page = 0x31 Status: BAD(-1)
To overcome this, you can specify -d
parameter and the program will happily dump your flash:
$ ~/Apps/SNANDer/src/SNANDer -d -r nand-230104.bin SNANDer - Serial Nor/nAND/Eeprom programmeR v.1.7.5 by McMCC <mcmcc@mail.ru> Found programmer device: WinChipHead (WCH) - CH341A Device revision is 3.0.4 spi_nand_probe: mfr_id = 0xc8, dev_id = 0xc1, dev_id_2 = 0xc8 Get Status Register 1: 0x00 Get Status Register 2: 0x11 Disable Flash ECC. Detected SPI NAND Flash: GIGADEVICE GD5F1GQ4UA, Flash Size: 128 MB READ: Read addr = 0x0000000000000000, len = 0x0000000008400000 Read 100% [138412032] of [138412032] bytes Elapsed time: 1118 seconds Status: OK
The interface is slow so it will take several minutes. Now you need to truncate the ECC bytes which are appended after each block with:
python3 cut-ecc.py nand-230104.bin
This will create nand-230104.bin.noecc
file. Now you can dump the config block:
dd if=nand-230104.bin.noecc
bs=1 skip=$((0x20000)) count=$((0x40000)) of=config-230104.bin
There are actually two config blocks there: 0x20000 and 0x40000 with the same contents for redundancy. You can compare and review them using Meld with following script and try to fix potential corruptions:
./compare.sh config-230104.bin
If you are happy with the contents, you can now assemble the final firmware file, erase flash and write the file to it using a script:
$ ./mkfix.sh 230104 262144+0 records in 262144+0 records out 262144 bytes (262 kB, 256 KiB) copied, 0,622619 s, 421 kB/s SNANDer - Serial Nor/nAND/Eeprom programmeR v.1.7.5 by McMCC <mcmcc@mail.ru> Found programmer device: WinChipHead (WCH) - CH341A Device revision is 3.0.4 spi_nand_probe: mfr_id = 0xc8, dev_id = 0xc1, dev_id_2 = 0xc8 Get Status Register 1: 0x00 Get Status Register 2: 0x01 Using Flash ECC. Detected SPI NAND Flash: GIGADEVICE GD5F1GQ4UA, Flash Size: 128 MB ERASE: Set full erase chip! Erase addr = 0x0000000000000000, len = 0x0000000008000000 spi_nand_erase_block : erase block fail, block = 0x3ff, status = 0x4 spi_nand_erase_internal : Erase Fail at addr = 0x7fe0000, len = 0x8000000, block_idx = 0x3ff Erase 100% [134217728] of [134217728] bytes Status: BAD(-1) SNANDer - Serial Nor/nAND/Eeprom programmeR v.1.7.5 by McMCC <mcmcc@mail.ru> Found programmer device: WinChipHead (WCH) - CH341A Device revision is 3.0.4 spi_nand_probe: mfr_id = 0xc8, dev_id = 0xc1, dev_id_2 = 0xc8 Get Status Register 1: 0x00 Get Status Register 2: 0x11 Using Flash ECC. Detected SPI NAND Flash: GIGADEVICE GD5F1GQ4UA, Flash Size: 128 MB WRITE: Write addr = 0x0000000000000000, len = 0x0000000008000000 spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffc0, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffc1, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffc2, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffc3, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffc4, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffc5, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffc6, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffc7, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffc8, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffc9, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffca, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffcb, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffcc, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffcd, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffce, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffcf, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffd0, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffd1, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffd2, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffd3, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffd4, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffd5, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffd6, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffd7, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffd8, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffd9, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffda, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffdb, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffdc, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffdd, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffde, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffdf, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffe0, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffe1, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffe2, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffe3, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffe4, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffe5, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffe6, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffe7, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffe8, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffe9, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffea, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffeb, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffec, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffed, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffee, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffef, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfff0, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfff1, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfff2, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfff3, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfff4, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfff5, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfff6, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfff7, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfff8, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfff9, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfffa, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfffb, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfffc, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfffd, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xfffe, status = 0xc spi_nand_write_page : Program Fail at addr_offset = 0x0, page_number = 0xffff, status = 0xc Written 100% [134217728] of [134217728] bytes Status: BAD(-1)
You can ignore the errors at the end, it will work just fine. Now you can insert or solder the flash back to board and after boot, you should be able to access the web configuration.
If your main SoC firmware is not 1.4, you also need to upgrade v1.4. Copy included tp_recovery.bin
to a tftp server, connect with the router, set server IP to 192.168.0.225 and start the router while holding reset button. Release the button when you see all LEDs flash. This is what you should see on the UART if you are watching:
U-Boot 1.1.3 (Mar 2 2020 - 13:55:27) Board: Ralink APSoC DRAM: 32 MB gpiomode1 55054404. gpiomode2 05550555. ######GPIO CTRL 1 for GPIO 32~64 OUTPUT tmp(0x00005f90)##### ######GPIO CTRL 1 for GPIO 32~64 INPUT tmp(0x00005f90)##### flash manufacture id: 1c, device id 70 16 find flash: EN25QH32B ============================================ Ralink UBoot Version: 4.3.0.0 -------------------------------------------- ASIC 7628_MP (Port5<->None) DRAM component: 256 Mbits DDR, width 16 DRAM bus: 16 bit Total memory: 32 MBytes Flash component: SPI Flash Date:Mar 2 2020 Time:13:55:27 ============================================ icache: sets:512, ways:4, linesz:32 ,total:65536 dcache: sets:256, ways:4, linesz:32 ,total:32768 ##### The CPU freq = 580 MHZ #### estimate memory size =32 Mbytes RESET MT7628 PHY!!!!!!.................................................. starting recovery... TODO, Read MAC Address from Flash netboot_common, argc= 3 KSEG1ADDR(NetTxPacket) = 0xA1FE7380 NetLoop,call eth_halt ! NetLoop,call eth_init ! Waitting for RX_DMA_BUSY status Start... done ETH_STATE_ACTIVE!! TFTP from server 192.168.0.225; our IP address is 192.168.0.2 Filename 'tp_recovery.bin'. TIMEOUT_COUNT=10,Load address: 0x80060000 Loading: T Got ARP REPLY, set server/gtwy eth addr (50:7b:9d:6a:42:ba) Got it ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ###########################Got ARP REQUEST, return our IP ###################################### ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# # done Bytes transferred = 17641990 (10d3206 hex) NetBootFileXferSize= 010d3206 Erase flash !! From 0x10000 length 0x3D0000 ............................................................. Copy 0x80080000 to 0x00010000, count 0x3D0000.... .............................................................
You are welcome 🙂
This is impressive!! Do you know if it is possible to increase the 4g signal? I think the two rsa connectors are wifi outputs instead of the 4g receiver. Based on the photos you attached, would you tell me where connector 4 is located?
No, the external SMA connectors are going to the modem so they are for 4G. Wifi (2,4 and 5G) have internal antennas.
Hello
Thank you for your tutorial.
Plz help me.
I downloaded your files and program the “spinand-noconfig.bin” on the nand ic completely with a ch341 programmer but my modem is not ok still.
Is there any other point?
Im sorry for my bad English.
You need to apply your config.
Excuse me.
I don’t understand your mean.
Which config?how?
You need to run the mkfix.sh
If you don’t understand what is going on in there you shouldn’t be doing it.
You mean I can’t fix the modem by programming a file on the SPINAND?
Hello, great tutorial, it’s impressive that you found out the issue!
I have the same problem and don’t want to throw out the modem when HW is still in good condition (just 2.5 years of service).
But since this is a bit too much for my soldering skills, would it be possible to use a clip like this instead?
https://www.neven.cz/kategorie/elektronicke-soucastky/elektronicky-vyvoj/prislusenstvi-k-programovani/sop8-programovaci-a-testovaci-svorka/
Thanks a lot
Hi Filip, unfortunatelly not, you need to desolder the chip for programming (using hot air gun or hotplate).
Can you help please?
Hello, after I soldered the serial port according to your operation, only printing can not input anything to the serial port, is this normal?
I remember interacting with the main SoC uboot so I think it worked for me.
do you remember the serial port configuration for MT7628? J3: 115200, 1-Tx, 2-Rx, 3-GND?
do you have a memory dump of this flash that supports MT7628?
Hi ,
Help me please This TL-MR100.
Do you know where are address location of MAC address in binary file 0x0…..?
Thank’s
I think it can be set using u-boot
$ strings -t x fullflash.bin | grep ethaddr
9dc1 ethaddr=”00:0A:EB:13:09:69″
d3bc ethaddr
dad0 *** ERROR: `ethaddr’ not set
f159 ethaddr=”00:0A:EB:13:09:69″
Thank’s your answer.
I don’t use u-boot but I use CH341 programmer for change MAC address in dump binary file.
Other model TL-MR200 I cand find Hex code MAC address location 0x0… inside binary file.
But for TL-MR100 can’t find .
Then maybe this:
Read MAC from flash(0x3FF900) ffffffd8-47-32-ffffffe2-5a-24
GMAC1_MAC_ADRH — : 0x0000d847
GMAC1_MAC_ADRL — : 0x32e25a24
Ralink APSoC Ethernet Driver Initilization. v3.1 256 rx/tx descriptors allocated, mtu = 1500!
spiflash_ioctl_read, Read from 0x003ff900 length 0x6, ret 0, retlen 0x6
Read MAC from flash(0x3FF900) ffffffd8-47-32-ffffffe2-5a-24
GMAC1_MAC_ADRH — : 0x0000d847
GMAC1_MAC_ADRL — : 0x32e25a24
PROC INIT OK!
Thank’s danman
I tried to upload file from nand flash another good mr100 and reinstalled the dump file to broken mr100.
This works and I checked the Mac address is correct I not changing any Mac address in the memory location source dump file because I have not found it. The method is different from other mr200 or other models.
Thank you again for your answer writing this blog is best for solving difficult solutions.