Skip to content
Permalink
Browse files

ramips: add support for TP-Link TL-WR840N v4 and TL-WR841N v13

TP-Link TL-WR840N v4 and TL-WR841N v13 are simple N300 routers with
5-port FE switch and non-detachable antennas. Both are very similar
and are based on MediaTek MT7628NN (aka MT7628N) WiSoC.

The difference between these two models is in number of available
LEDs, buttons and power input switch.

This work is partially based on GitHub PR#974.

Specification:

- MT7628N/N (580 MHz)
- 64 MB of RAM (DDR2)
- 8 MB of FLASH
- 2T2R 2.4 GHz
- 5x 10/100 Mbps Ethernet
- 2x external, non-detachable antennas
- UART (J1) header on PCB (115200 8n1)
- TL-WR840N v4: 5x LED (GPIO-controlled), 1x button
- TL-WR841N v13: 8x LED (GPIO-controlled*), 2x button, power input
  switch

* WAN LED in TL-WR841N v13 is a dual-color, dual-leads type which isn't
  (fully) supported by gpio-leds driver. This type of LED requires both
  GPIOs state change at the same time to select color or turn it off.
  For now, we support/use only the green part of the LED.

Factory image notes:

These devices use version 3 of TP-Link header, fortunately without RSA
signature (at least in case of devices sold in Europe). The difference
lays in the requirement for a non-zero value in "Additional Hardware
Version" field. Ideally, it should match the value stored in vendor
firmware header on device ("0x4"/"0x13" for these devices) but it seems
that anything other than "0" is correct.

We are able to prepare factory firwmare file which is accepted and
(almost) correctly flashed from the vendor GUI. As it turned out, it
accepts files without U-Boot image with second header at the beginning
but due to some kind of bug in upgrade routine, flashed image gets
corrupted before it's written to flash.

Tests showed that the GUI upgrade routine copies value of "Additional
Hardware Version" from existing firmware into offset "0x2023c" in
provided file, _before_ storing it in flash. In case of vendor firmware
upgrade files (which all include U-Boot image and two headers), this
offset points to the matching field in kernel+rootfs firmware part
header. Unfortunately, in case of LEDE factory image file which contains
only one header, it points to the offset "0x2023c" in kernel image. This
leads to a corrupted kernel and ends up with a "soft-bricked" device.

The good news is that U-Boot in these devices contains well known tftp
recovery mode, which can be triggered with "reset" button. What's more,
in comparison to some of older MediaTek based TP-Link devices, this
recovery mode doesn't write whole file at offset "0x0" in flash, without
verifying provided file in advance. In case of recovery mode in these
devices, first "0x20000" bytes are always skipped and "0x7a0000" bytes
from rest of the file are stored in flash at offset "0x20000".

Flash instruction:

Until (if at all) TP-Link fixes described problem, the only way to flash
LEDE image in these devices is to use tftp recovery mode in U-Boot:

1. Configure PC with static IP 192.168.0.66/24 and tftp server.
2. Rename "lede-ramips-mt7628-tl-wr84...-squashfs-tftp-recovery.bin"
   to "tp_recovery.bin" and place it in tftp server directory.
3. Connect PC with one of LAN ports, press the reset button, power up
   the router and keep button pressed for around 6-7 seconds, until
   device starts downloading the file.
4. Router will download file from server, write it to flash and reboot.

To access U-Boot CLI, keep pressed "4" key during boot.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
  • Loading branch information...
pepe2k committed Jun 21, 2017
1 parent c55fadc commit 24043a0d2e01b9843c0dc529205b3b0bc7ecbbf9
@@ -336,6 +336,19 @@ tiny-ac)
set_wifi_led "$board:orange:wifi"
set_usb_led "$board:green:usb"
;;
tl-wr840n-v4)
set_wifi_led "$board:green:wlan"
ucidef_set_led_switch "lan" "lan" "$board:green:lan" "switch0" "0x1e"
ucidef_set_led_switch "wan" "wan" "$board:green:wan" "switch0" "0x01"
;;
tl-wr841n-v13)
set_wifi_led "$board:green:wlan"
ucidef_set_led_switch "lan1" "lan1" "$board:green:lan1" "switch0" "0x2"
ucidef_set_led_switch "lan2" "lan2" "$board:green:lan2" "switch0" "0x4"
ucidef_set_led_switch "lan3" "lan3" "$board:green:lan3" "switch0" "0x8"
ucidef_set_led_switch "lan4" "lan4" "$board:green:lan4" "switch0" "0x10"
ucidef_set_led_switch "wan" "wan" "$board:green:wan" "switch0" "0x01"
;;
vocore-8M|\
vocore-16M)
ucidef_set_led_netdev "eth" "ETH" "vocore:orange:eth" "eth0"
@@ -169,6 +169,8 @@ ramips_setup_interfaces()
mzk-wdpr|\
rb750gr3|\
rt-n14u|\
tl-wr840n-v4|\
tl-wr841n-v13|\
ubnt-erx|\
ubnt-erx-sfp|\
ur-326n4g|\
@@ -35,6 +35,8 @@ get_status_led() {
nbg-419n2|\
pwh2004|\
r6220|\
tl-wr840n-v4|\
tl-wr841n-v13|\
vr500|\
wnce2001|\
wndr3700v5|\
@@ -487,6 +487,12 @@ ramips_board_detect() {
*"Timecloud")
name="timecloud"
;;
*"TL-WR840N v4")
name="tl-wr840n-v4"
;;
*"TL-WR841N v13")
name="tl-wr841n-v13"
;;
*"UBNT-ERX")
name="ubnt-erx"
;;
@@ -230,7 +230,9 @@ platform_check_image() {
;;
c20i|\
c50|\
mr200)
mr200|\
tl-wr840n-v4|\
tl-wr841n-v13)
[ "$magic" != "03000000" ] && {
echo "Invalid image type."
return 1
@@ -0,0 +1,62 @@
/dts-v1/;

#include "TL-WR84XN.dtsi"

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>

/ {
compatible = "tplink,tl-wr840n-v4", "mediatek,mt7628an-soc";
model = "TP-Link TL-WR840N v4";

gpio-keys-polled {
compatible = "gpio-keys-polled";
#address-cells = <1>;
#size-cells = <0>;
poll-interval = <20>;

reset {
label = "reset";
gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
};

gpio-leds {
compatible = "gpio-leds";

lan {
label = "tl-wr840n-v4:green:lan";
gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};

power {
label = "tl-wr840n-v4:green:power";
gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
};

wan {
label = "tl-wr840n-v4:green:wan";
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};

wlan {
label = "tl-wr840n-v4:green:wlan";
gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
};

wps {
label = "tl-wr840n-v4:green:wps";
gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
};
};
};

&pinctrl {
state_default: pinctrl0 {
gpio {
ralink,group = "p0led_an", "p2led_an", "perst", "refclk", "wdt", "wled_an";
ralink,function = "gpio";
};
};
};
@@ -0,0 +1,88 @@
/dts-v1/;

#include "TL-WR84XN.dtsi"

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>

/ {
compatible = "tplink,tl-wr841n-v13", "mediatek,mt7628an-soc";
model = "TP-Link TL-WR841N v13";

gpio-keys-polled {
compatible = "gpio-keys-polled";
#address-cells = <1>;
#size-cells = <0>;
poll-interval = <20>;

reset {
label = "reset";
gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};

rfkill {
label = "rfkill";
gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RFKILL>;
};
};

gpio-leds {
compatible = "gpio-leds";

power {
label = "tl-wr841n-v13:green:power";
gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
};

wps {
label = "tl-wr841n-v13:green:wps";
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
};

lan1 {
label = "tl-wr841n-v13:green:lan1";
gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
};

lan2 {
label = "tl-wr841n-v13:green:lan2";
gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};

lan3 {
label = "tl-wr841n-v13:green:lan3";
gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
};

lan4 {
label = "tl-wr841n-v13:green:lan4";
gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
};

wan_green {
label = "tl-wr841n-v13:green:wan";
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};

wan_orange {
label = "tl-wr841n-v13:orange:wan";
gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
};

wlan {
label = "tl-wr841n-v13:green:wlan";
gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
};
};
};

&pinctrl {
state_default: pinctrl0 {
gpio {
ralink,group = "gpio", "p0led_an", "p1led_an", "p2led_an", "p3led_an", "p4led_an", "perst", "refclk", "uart1", "wdt", "wled_an";
ralink,function = "gpio";
};
};
};
@@ -0,0 +1,67 @@
#include "mt7628an.dtsi"

/ {
chosen {
bootargs = "console=ttyS0,115200";
};

memory@0 {
device_type = "memory";
reg = <0x0 0x4000000>;
};
};

&spi0 {
status = "okay";

m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <10000000>;
m25p,chunked-io = <32>;

partition@0 {
label = "boot";
reg = <0x0 0x20000>;
read-only;
};

partition@20000 {
label = "firmware";
reg = <0x20000 0x7a0000>;
};

partition@7c0000 {
label = "config";
reg = <0x7c0000 0x10000>;
read-only;
};

factory: partition@7d0000 {
label = "factory";
reg = <0x7d0000 0x30000>;
read-only;
};
};
};

&ehci {
status = "disabled";
};

&ohci {
status = "disabled";
};

&wmac {
status = "okay";
mtd-mac-address = <&factory 0xf100>;
mediatek,mtd-eeprom = <&factory 0x20000>;
};

&ethernet {
mtd-mac-address = <&factory 0xf100>;
mediatek,portmap = "llllw";
};
@@ -2,6 +2,8 @@
# MT7628 Profiles
#

DEVICE_VARS += TPLINK_BOARD_ID

define Device/mt7628
DTS := MT7628
BLOCKSIZE := 64k
@@ -26,6 +28,28 @@ define Device/miwifi-nano
endef
TARGET_DEVICES += miwifi-nano

define Device/tl-wr840n-v4
DTS := TL-WR840NV4
IMAGE_SIZE := 7808k
DEVICE_TITLE := TP-Link TL-WR840N v4
TPLINK_BOARD_ID := TL-WR840NV4
KERNEL := $(KERNEL_DTB)
IMAGES += tftp-recovery.bin
IMAGE/factory.bin := tplink-v2-image
IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
IMAGE/sysupgrade.bin := tplink-v2-image -s | append-metadata | \
check-size $$$$(IMAGE_SIZE)
endef
TARGET_DEVICES += tl-wr840n-v4

define Device/tl-wr841n-v13
$(Device/tl-wr840n-v4)
DTS := TL-WR841NV13
DEVICE_TITLE := TP-Link TL-WR841N v13
TPLINK_BOARD_ID := TL-WR841NV13
endef
TARGET_DEVICES += tl-wr841n-v13

define Device/gl-mt300n-v2
DTS := GL-MT300N-V2
IMAGE_SIZE := 16064k
@@ -138,6 +138,7 @@ CONFIG_MTD_NAND_MT7620=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_TPLINK_FW=y
CONFIG_MTD_SPLIT_TRX_FW=y
CONFIG_MTD_SPLIT_UIMAGE_FW=y
CONFIG_NEED_DMA_MAP_STATE=y
@@ -191,6 +192,7 @@ CONFIG_SPI_MT7621=y
# CONFIG_SPI_RT2880 is not set
CONFIG_SRCU=y
CONFIG_SWCONFIG=y
CONFIG_SWCONFIG_LEDS=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
@@ -140,6 +140,7 @@ CONFIG_MTD_M25P80=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_TPLINK_FW=y
CONFIG_MTD_SPLIT_TRX_FW=y
CONFIG_MTD_SPLIT_UIMAGE_FW=y
CONFIG_NEED_DMA_MAP_STATE=y
@@ -193,6 +194,7 @@ CONFIG_SPI_MT7621=y
# CONFIG_SPI_RT2880 is not set
CONFIG_SRCU=y
CONFIG_SWCONFIG=y
CONFIG_SWCONFIG_LEDS=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
@@ -207,6 +207,22 @@ static struct board_info boards[] = {
.layout_id = "8MLmtk",
.hdr_ver = 3,
.endian_swap = true,
}, {
.id = "TL-WR840NV4",
.hw_id = 0x08400004,
.hw_rev = 0x1,
.hw_ver_add = 0x4,
.layout_id = "8Mmtk",
.hdr_ver = 3,
.endian_swap = true,
}, {
.id = "TL-WR841NV13",
.hw_id = 0x08410013,
.hw_rev = 0x268,
.hw_ver_add = 0x13,
.layout_id = "8Mmtk",
.hdr_ver = 3,
.endian_swap = true,
}, {
/* terminating entry */
}

8 comments on commit 24043a0

@JamesT42

This comment has been minimized.

Copy link

JamesT42 replied Jun 30, 2017

Basic supports works fine, but it seems that during boot the switch turns dumb and packages from LAN side go to the WAN side.

@pepe2k

This comment has been minimized.

Copy link
Member Author

pepe2k replied Jul 1, 2017

@alangregory

This comment has been minimized.

Copy link

alangregory replied Jul 3, 2017

Some warnings on ssid change:

[ 1075.574558] WARNING: CPU: 0 PID: 36 at /home/alangregory/XXXX:1225 mt7603_mac_work+0xf0/0x288 [mt7603e]()
[ 1075.597413] Modules linked in: iptable_mangle iptable_filter ipt_REJECT ip_tables xt_time xt_tcpudp xt_multiport xt_mark xt_mac xt_limit xt_comment xt_TCPMSS xt_LOG x_tables nf_reject_ipv4 nf_log_ipv4 nf_log_common mt76x2e mt7603e mt76 mac80211 cfg80211 compat tun leds_gpio gpio_button_hotplug
[ 1075.623937] CPU: 0 PID: 36 Comm: kworker/u2:2 Not tainted 4.4.74 #0
[ 1075.630315] Workqueue: phy0 mt7603_mac_work [mt7603e]
[ 1075.635445] Stack : 83803410 838f0218 00000088 8004a804 838eeac4 8034c063 802ed7a4 00000024
[ 1075.635445] 	  80315468 838b3d64 80350000 80048770 00000088 8004a804 802f2cb8 80350000
[ 1075.635445] 	  00000003 838b3d64 80350000 80038780 00000088 838b3d9c 000000aa 00000000
[ 1075.635445] 	  00000001 00000000 83b95268 83b43600 83b43700 30796870 00000000 00000000
[ 1075.635445] 	  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1075.635445] 	  ...
[ 1075.671694] Call Trace:
[ 1075.674209] [<8001426c>] show_stack+0x50/0x84
[ 1075.678669] [<80024dd8>] warn_slowpath_common+0xa0/0xd0
[ 1075.683978] [<80024e90>] warn_slowpath_null+0x18/0x24
[ 1075.689131] [<83b95358>] mt7603_mac_work+0xf0/0x288 [mt7603e]
[ 1075.694978] [<80036698>] process_one_work+0x1f8/0x334
[ 1075.700121] [<800374ac>] worker_thread+0x2b0/0x404
[ 1075.704985] [<8003b864>] kthread+0xd8/0xec
[ 1075.709158] [<80004478>] ret_from_kernel_thread+0x14/0x1c
[ 1075.714630] 

Steps:
wireless.default_radio0.ssid='NEW-SSID'
uci commit
reload_config

@pepe2k

This comment has been minimized.

Copy link
Member Author

pepe2k replied Jul 3, 2017

Hi @alangregory,

AFAIK, mt76 bugs should be reported here: https://github.com/openwrt/mt76. Driver hasn't been yet updated in LEDE (I see some new commits in mt76 repository), you can update it locally.

Cheers,
Piotr

@alangregory

This comment has been minimized.

Copy link

alangregory replied Jul 3, 2017

@pepe2k Thanks, i'll test.

@andersondeoliveiramachado

This comment has been minimized.

Copy link

andersondeoliveiramachado replied Jul 4, 2017

Where to select to generate an image for the TP-Link TL-WR840N v4 ?

image
image

@pepe2k

This comment has been minimized.

Copy link
Member Author

pepe2k replied Jul 4, 2017

Where to select to generate an image for the TP-Link TL-WR840N v4 ?

It's MediaTek MT7628 based, target: ramips (MediaTek Ralink MIPS in make menuconfig).

Cheers,
Piotr

@andersondeoliveiramachado

This comment has been minimized.

Copy link

andersondeoliveiramachado replied Jul 4, 2017

Many thanks for the reply. I'm starting to work with the Lede Project / Open Wrt

Please sign in to comment.
You can’t perform that action at this time.