LEDE for WR841N v13/WR840N v4

Этот пост на русском языке

Damn. I just wanted to start a blog and left it alone after the introduction post. It’s time to return.

TP-Link continues to migrate onto the new Mediatek chipsets. They’ve released new versions of two popular routers recently: WR841N and WR840N.

Some guy called svobodavac made a patch for wr840n v4 initial support by LEDE. That pull request was declined by LEDE and was temporary closed.

Unfortunately, the mt76 wireless open-source driver is not able to provide a stable wireless connection. With this driver I had continuous disconnects, missing beacons, packet loses, low power signal (this was fixed with new EEPROM location in dts). I don’t know if it works or not properly for all mt76xx devices or just mt7603.

So I decided to build LEDE with a proprietary MTK driver.

All images are LEDE 17.01.

For WR841N v13:



For WR840N v4 (WARNING! This firmware wasn’t tested on WR840N V4! I doubt that you’ll face any issues, because this two devices are similar, but I have warned you):




How to install?
The installation is only possible via TFTP. Nothing special, just like on any other TP-Link. The file name must be tp_recovery.bin.

More info about using TP-Link TFTP recovery can be found here (Windows-only).

How to update from LEDE/OpenWrt?
You can do it via LuCI Backup/Flash Firmware, or via sysupgrade over SSH. Just use the sysupgrade image. The factory image flashing via OpenWrt/LEDE won’t work for now.

If you have installed a firmware WR840N v4 on WR841N v13 or vice-versa, it’s better to update via TFTP (more info in previous spoiler).

Will I ever be able to flash this via stock web-interface?
Probably, yes. There are some discussions about it in the pull request comments. It seems that new TP-Link firmware have a new header. Now all LEDE/OpenWrt firmwares are built with empty header and because of that it can be flashed only via TFTP.
Where is the driver was taken from?
The driver for 4.1.X.X kernel was taken from the Padavan for Asus RT-N56U firmware. Makefile for the kernel package was taken from here. Some dependencies was taken from padavan firmware and from witi-openwrt.
How stable it is?
It seems that it is very stable. I didn’t have disconnects or packet loss.
What was tested and works?
The wireless itself :), UCI control, MultiSSID.
What does not work?
Controlling via LuCI. This is because of iwinfo doesn’t work properly with this driver and can’t provide any information about device. Now you can only set SSID and WEP encryption via LuCI, any other setting can be changed over ssh.

Also, the wireless LED doesn’t work too. You can set it to rai0 interface in LuCI LED Configuration to make it flash when data received or transmitted :).

What probably works?
WDS and client mode. I haven’t tested it yet, but the driver supports it. Generally speaking, this driver must have full support of this device. The problems can be occurred during a UCI to .dat config translation.
How to configure wireless via SSH?
The documentation for all UCI params can be found here. Right after the first boot wireless broadcasts with SSID “MT7628” and without encryption. It is connected to the br-lan bridge by default. So you can found the example configuration in /etc/config/wireless file.
'Wireless is disabled or not associated'!
This is because of iwinfo, which can’t provide any information. So, LuCI is unable to get real wireless status. The wireless itself should work and you should be able to see it on other devices.
There is no wlan0 interface!
The driver creates rai0, rai1, rai2… interfaces instead of wlan0, wlan1, wlan2…
What about package repositories?
I’ve replaced core repo with my own repo, which will be hosted on my server. Core repo contains all kernel modules provided with LEDE. You can’t install kernel modules from the lede-project.org because of hashsum mismatch (this was done by OpenWrt developers). All other repos (base, routing, telephony…) are default, from lede-project.org. You only need to uncomment them in /etc/opkg/distfeeds.conf.
How long you gonna keep this repo?
I’ll try to keep it as long as possible. All new builds will be in separate directories, so that way I’ll not break opkg when new build will be released.
Is source code or patch available?
I’ve created the LEDE feed with this driver. It is available here: https://github.com/worm202/lede-mt7603
Why don't you make a pull request to the LEDE repo?
LEDE will not approve this, because MTK driver is non-free. To make LEDE officially support those devices we need to fix the open-source driver. Moreover, there was a problem with firmware header, this needs to be fixed too.

I’m working on it. If I fix it, I’ll make pull request to LEDE.

Why wr840n v4 wasn't tested?
It’s easy – I don’t have a device. Because of it’s similarity to wr841n v13 it probably work as well.
What is the difference between wr841n v13 and wr840n v4?
As I know, there is a difference in LEDs. WR841N v13 has 4 LAN LEDs, but WR840N v4 only one. Generally, this two devices are similar (or same). LEDE firmwares are compatiable, so WR841N v13 can work with WR840N v4 firmware.
Can this driver work with other Mediatek Wi-Fi chips?
Probably, yes. It has support for multiple chips including, for example, MT7610E (802.11 AC chip, which isn’t available on LEDE/OpenWrt yet). The problem with packages in my repo is that it was modified to build and work on this two devices specifically.
It doesn't work / I didn't understand anything, how to revert back to the stock firmware?

Stock TP-Link firmware without boot: WR840N v4, WR841N v13.


The filename of firmware should be tp_recovery.bin.

19 thoughts on “LEDE for WR841N v13/WR840N v4”

  1. Hi Raxp

    Can you be so kind to write tutorial how to build fresh openwrt firmware with this driver?
    I tested and works perfectly.


    1. Yeah, damn, I totally forgot. I apologize, but I didn’t had much time to clean things up. I decided to just publish this as it is.
      I’ll try to do this as soon as possible

      1. Hi,

        Even if you don’t have time to write a tutorial just yet, can you at least rebuild this version and post the binaries? The opensource version of the driver is still not working right, and I’m having troubles to re-implement what you did here.

      1. Hi and thank you for info, but it does not compile under current openwrt. I switched back to latest stable 17.01.4 and there’s no profile for wr841n v13 🙁 Could you please build latest stable 17.01.4 binary? (preferably bare without luci)
        These are the errors I get whet I try to compile:
        make[4]: Entering directory ‘/home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux-4.14.32’
        CC [M] /home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap/../mt7628/embedded/common/eeprom.o
        /home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap/../mt7628/embedded/common/eeprom.c: In function ‘NICReadEEPROMParameters’:
        /home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap/../mt7628/embedded/common/eeprom.c:324:59: error: passing argument 4 of ‘ra_mtd_read_nm’ from incompatible pointer type [-Werror=incompatible-pointer-types]
        ra_mtd_read_nm(“romfile”, 0xF100&0xFFFF, sizeof(USHORT), &Addr01);
        /home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap/../mt7628/embedded/common/eeprom.c:265:12: note: expected ‘u_char * {aka unsigned char *}’ but argument is of type ‘USHORT * {aka short unsigned int *}’
        extern int ra_mtd_read_nm(char *name, loff_t from, size_t len, u_char *buf);
        /home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap/../mt7628/embedded/common/eeprom.c:325:59: error: passing argument 4 of ‘ra_mtd_read_nm’ from incompatible pointer type [-Werror=incompatible-pointer-types]
        ra_mtd_read_nm(“romfile”, 0xF102&0xFFFF, sizeof(USHORT), &Addr23);
        /home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap/../mt7628/embedded/common/eeprom.c:265:12: note: expected ‘u_char * {aka unsigned char *}’ but argument is of type ‘USHORT * {aka short unsigned int *}’
        extern int ra_mtd_read_nm(char *name, loff_t from, size_t len, u_char *buf);
        /home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap/../mt7628/embedded/common/eeprom.c:326:59: error: passing argument 4 of ‘ra_mtd_read_nm’ from incompatible pointer type [-Werror=incompatible-pointer-types]
        ra_mtd_read_nm(“romfile”, 0xF104&0xFFFF, sizeof(USHORT), &Addr45);
        /home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap/../mt7628/embedded/common/eeprom.c:265:12: note: expected ‘u_char * {aka unsigned char *}’ but argument is of type ‘USHORT * {aka short unsigned int *}’
        extern int ra_mtd_read_nm(char *name, loff_t from, size_t len, u_char *buf);
        cc1: some warnings being treated as errors
        scripts/Makefile.build:328: recipe for target ‘/home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap/../mt7628/embedded/common/eeprom.o’ failed
        make[5]: *** [/home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap/../mt7628/embedded/common/eeprom.o] Error 1
        Makefile:1526: recipe for target ‘_module_/home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap’ failed
        make[4]: *** [_module_/home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/mt7628_ap] Error 2
        make[4]: Leaving directory ‘/home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux-4.14.32’
        Makefile:75: recipe for target ‘/home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/.built’ failed
        make[3]: *** [/home/compiler/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/mt7628-p4rev-110971/.built] Error 2
        make[3]: Leaving directory ‘/home/compiler/openwrt/feeds/mt7603/mt7628’
        package/Makefile:107: recipe for target ‘package/feeds/mt7603/mt7628/compile’ failed
        make[2]: *** [package/feeds/mt7603/mt7628/compile] Error 2
        make[2]: Leaving directory ‘/home/compiler/openwrt’
        package/Makefile:103: recipe for target ‘/home/compiler/openwrt/staging_dir/target-mipsel_24kc_musl/stamp/.package_compile’ failed
        make[1]: *** [/home/compiler/openwrt/staging_dir/target-mipsel_24kc_musl/stamp/.package_compile] Error 2
        make[1]: Leaving directory ‘/home/compiler/openwrt’
        /home/compiler/openwrt/include/toplevel.mk:216: recipe for target ‘world’ failed
        make: *** [world] Error 2

        1. Hey. Sorry for looooooong delay.
          Yeah, I’ve tried to build 17.01.4 and trunk and it won’t compile.
          I’ve tried to fix this, but now I don’t have this router, so I can’t.

  2. Hi awesome work! I was wondering if you know how can I revert to tp-link firmware without it being in Russian, because tp-link doenst allow to flash other languages.
    Thanks in advance

    1. Damn, I haven’t paid attention that those stock firmwares are RU. I’m sorry. 😀
      If you still need it – I made EN versions. Just re-download them.
      If you need other language – you need a linux box (Virtual machine or something).
      Download firmware from your regional TP-Link website. Unpack it from archive to your home directory and run in linux terminal:

      dd if="filename of original firmware" of="filename of stripped firmware" bs=512 skip=1

      For example: I have a firmware with filename: TL-WR840Nv4_0.9.1_3.16_up_boot(161011).bin. I run:

      dd if="TL-WR840Nv4_0.9.1_3.16_up_boot(161011).bin" of="tlwr840n-v4-stock.bin" bs=512 skip=1

      You’ll get a stripped firmware for your region named tlwr840n-v4-stock.bin.

  3. hi raxp,

    i was tested your own build, work well but only access point (default setting). if i try change to client mode. never success . could you give tutor change to other mode from uci, thanx before

  4. Man, you saved my life, thank you so much, i installed your version and now i can use the router normally, with the Lede version the router disables wifi all the time and i have to reboot, that’s so annoying. I installed in one Wr840n V4 by tftp, and i’m using like a Dumb AP, and it’s so perfect, i never used ssh to make big configurations in openwrt/lede, but i searched and i change wireless configuration, network, dhcp etc. Again i have to say, you’re my hero, thank you man, cheers.

  5. can cake and piece of cake qos work with this? it would be hard for me to learn to use the command line to set it up but i would. does luci still not work with it? this version is EU version correct? i tried flashing other stripped firmwares but it didnt work. got told the firmware i was using was for EU version. does anybody know how to strip the US version for flashing back to stock. if i had the firmware i could flash it with tftp but i dont know how. if this stripped firmware is for EU i dotn think it will work

    1. I’ve tested this on RU version, which seems the same as EU.
      AFAIK there is no division on CN/EU/US versions for this model. If you was able to flash LEDE/Openwrt (from openwrt.org), so there should be no difference.

  6. I had your firmware installed on my TL-WR840N and it worked really well. When I tried to change via sysupgrade for an image that I made using openwrt tool, the router bricked. Using the firmware in the area “It doesn’t work / I didn’t understand anything, how to revert back to the stock firmware?” Fixed it for me.

    The driver used in your firmware and the one available officially in openwrt project (as for today, 5/12/2018), for TL-WR840N, showed the same stability and results concerning to Wi-Fi. Thanks!

  7. Hello @raxp.

    First, thanks for your work!
    I have two doubts:

    1) Can i use your “git repo” to build a new snapshot image, or these drivers are for a specific Kernel?
    2) I have another router, Archer C50 V3 dual band. CPU is also MT7628 , 2.4 Ghz Wifi MT7628 , 5 Ghz Wifi MT7612E. Do you know if it´s possible to use your driver for 2.4 and open source driver for 5.0?


    1. Hey, Juliano.
      1) When I touched this last time I was unable to build a trunk version which has newer kernel. I tried to fix it, but no luck. Now I can’t test it since I don’t have this router anymore.
      2) I can’t say if it is possible. You can try, but you should uncheck all unnecessary mt76 devices (except kmod-mt7612e) when building an image. Also this driver contains some code regarding mt7612e, so it is probably possible to build a mt7603 and mt7612e modules from it. But first this repo needs to be fixed for newer LEDE/Openwrt.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.