Add support to "MediaTek MT7621 reference board" (sold by RuxTek)

I am trying to add support to a board referred as "MediaTek MT7621 reference board" (as found in uboot). RuxTek is not the manufacturer but they re-sell it.

Here follows what I have done:



// --------------------- STEP 1: verify u-boot and flash layout -------------------

First of all I opened the case, connected the UART pins (115200 baud rate) and with access to u-boot console I verified the chipset and flash layout:

MT7621AT (SoC)
MT7975DN + MT7905DAN (WiFi)
MT7530 (switch)

Flash Layout

"Bootloader" - from 0x000000000000 to 0x000000040000.

"BootConfig" - from 0x000000040000 to 0x000000050000.

"Factory" - from 0x000000050000 to 0x000000060000.

"permanent_config" - from 0x000000060000 to 0x0000000e0000

"firmware" - from 0x0000000e0000 to 0x000001000000

I wonder what is stored in "factory" and "permanent_config". Perhaps wifi callibration in any of them...

// --------------------- STEP 2: boot menu -------------------

Interrupting the automatic sequence from boot, I reached the u-boot menu:

image

And then u-boot console:

U-Boot SPL 2018.09-g63a3496 (Sep 18 2019 - 17:31:41 +0800)
Trying to boot from NOR


U-Boot 2018.09-svn2945 (Aug 08 2022 - 12:23:33 +0800)

CPU:   MediaTek MT7621AT ver 1, eco 3
Clocks: CPU: 880MHz, DDR: 1200MHz, Bus: 220MHz, XTAL: 40MHz
Model: MediaTek MT7621 reference board
DRAM:  256 MiB
Loading Environment from SPI Flash... SF: Detected w25q128bv with page size 256 Bytes, erase size 64 KiB, total 16 MiB
*** Warning - bad CRC, using default environment

In:    uartlite0@1e000c00
Out:   uartlite0@1e000c00
Err:   uartlite0@1e000c00
Net:
Warning: eth@1e100000 (eth0) using random MAC address - ba:6e:8b:bd:30:cf
eth0: eth@1e100000
Hit any key to stop autoboot:  0
=> [B▒
Unknown command '[B▒▒' - try 'help'
=> help
?       - alias for 'help'
base    - print or set address offset
bdinfo  - print Board Info structure
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootm   - boot application image from memory
bootmenu- ANSI terminal bootmenu
bootp   - boot image via network using BOOTP/TFTP protocol
chpart  - change active partition
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
echo    - echo args to console
editenv - edit environment variable
env     - environment handling commands
fdt     - flattened device tree utility commands
go      - start application at address 'addr'
gpio    - query and control gpio pins
help    - print command description/usage
httpd   - Start failsafe HTTP server
iminfo  - print header information for application image
itest   - return true/false on integer compare
led     - manage LEDs
loadb   - load binary file over serial line (kermit mode)
loads   - load S-Record file over serial line
loadx   - load binary file over serial line (xmodem mode)
loady   - load binary file over serial line (ymodem mode)
loop    - infinite loop on address range
md      - memory display
mm      - memory modify (auto-incrementing address)
mtdparts- define flash/nand partitions
mtkautoboot- Display MediaTek bootmenu
mtkboardboot- Boot MTK firmware
mtkload - MTK image loading utility
mtkupgrade- MTK firmware/bootloader upgrading utility
mw      - memory write (fill)
nm      - memory modify (constant address)
printenv- print environment variables
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv  - set environment variables
setexpr - set environment variable as the result of eval expression
sf      - SPI flash sub-system
sleep   - delay execution for some time
source  - run script from memory
tftpboot- boot image via network using TFTP protocol
version - print monitor, compiler and linker version

// --------------------- STEP 3: failsafe mode, SSH to factory FW -------------------

By pressing "f" then "enter" interrupting the boot sequence, I could boot in failsafe mode, and then change the password (for a user called "mtc" not root but seems to be the same). Now I can access via SSH.

The firmware is based on OpenWRT/LEDE 17.01, with MTK drivers (closed source), I verified the flash layout again from here. Here is the /etc/board.json file:

{
        "model": {
                "id": "mt7621-rfb-ax-nor",
                "name": "MediaTek MT7621 RFB (802.11ax,SNOR)"
        },
        "network": {
                "lan": {
                        "ifname": "eth0",
                        "protocol": "static"
                },
                "wan": {
                        "ifname": "eth1",
                        "protocol": "dhcp"
                }
        },
        "switch": {
                "switch0": {
                        "enable": true,
                        "reset": true,
                        "ports": [
                                {
                                        "num": 0,
                                        "role": "lan"
                                },
                                {
                                        "num": 1,
                                        "role": "lan"
                                },
                                {
                                        "num": 2,
                                        "role": "lan"
                                },
                                {
                                        "num": 4,
                                        "role": "wan"
                                },
                                {
                                        "num": 6,
                                        "device": "eth0",
                                        "need_tag": false,
                                        "want_untag": false
                                },
                                {
                                        "num": 5,
                                        "device": "eth1",
                                        "need_tag": false,
                                        "want_untag": false
                                }
                        ],
                        "roles": [
                                {
                                        "role": "lan",
                                        "ports": "0 1 2 6",
                                        "device": "eth0"
                                },
                                {
                                        "role": "wan",
                                        "ports": "4 5",
                                        "device": "eth1"
                                }
                        ]
                }
        }
}

// --------------------- STEP 4: make a first FW and to test in RAM (failure) -------------------

I used as basis TP-Link Archer AX23 to edit the .mk and create a .dts.

I added to buildroot/target/linux/ramips/image/mt7621.mk

define Device/paicorp_sm-1
  $(Device/dsa-migration)
  $(Device/uimage-lzma-loader)  
  DEVICE_VENDOR := PaiCorp
  DEVICE_MODEL := SM-1
  DEVICE_PACKAGES := kmod-mt7915-firmware -uboot-envtools
  KERNEL := $(KERNEL_DTB) | uImage lzma
  IMAGE_SIZE := 15744k
endef
TARGET_DEVICES += paicorp_sm-1

And I created buildroot/target/linux/ramips/dts/mt7621_paicorp_sm-1.dts , only editing the part related to the flash layout:

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT

#include "mt7621.dtsi"

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

/ {
	compatible = "paicorp,sm-1", "mediatek,mt7621-soc";
	model = "PaiCorp SM-1";

	aliases {
		led-boot = &led_power;
		led-failsafe = &led_power;
		led-running = &led_power;
		led-upgrade = &led_power;
		label-mac-device = &gmac0;
	};

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

	keys {
		compatible = "gpio-keys";

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

		wps {
			label = "rfkill";
			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_RFKILL>;
		};
	};

	leds {
		compatible = "gpio-leds";

		led_power: power {
			label = "green:power";
			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
		};

		wifi2g {
			label = "green:wifi2g";
			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
			linux,default-trigger = "phy0tpt";
		};

		wifi5g {
			label = "green:wifi5g";
			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
			linux,default-trigger = "phy1tpt";
		};

		wan-green {
			label = "green:wan";
			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
		};

		wan-orange {
			label = "orange:wan";
			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
		};

		lan {
			label = "green:lan";
			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
		};

		wps {
			label = "green:wps";
			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
		};
	};
};

&spi0 {
	status = "okay";

	flash@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <25000000>;

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			partition@0 {
				label = "Bootloader";
				reg = <0x000000000000 0x000000040000>;
				read-only;
			};

			partition@40000 {
				label = "BootConfig";
				reg = <0x000000040000 0x000000050000>;
				read-only;
			};

			config: partition@50000 {
				label = "Factory";
				reg = <0x000000050000 0x000000060000>;
				read-only;
			};

			permanent_config: partition@60000 {
				label = "permanent_config";
				reg = <0x000000060000 0x0000000e0000>;
				read-only;
			};

			partition@0e0000 {
				compatible = "denx,uimage";
				label = "firmware";
				reg = <0x0000000e0000 0x000001000000>;

			};
		};
	};
};

&pcie {
	status = "okay";
};

&pcie1 {
	wifi@0,0 {
		compatible = "mediatek,mt76";
		reg = <0x0000 0 0 0 0>;
		mediatek,mtd-eeprom = <&permanent_config 0x0>;
		nvmem-cells = <&macaddr_config_8>;
		nvmem-cell-names = "mac-address";
		mediatek,disable-radar-background;
	};
};

&gmac0 {
	nvmem-cells = <&macaddr_config_8>;
	nvmem-cell-names = "mac-address";
};

&gmac1 {
	status = "okay";
	label = "wan";
	phy-handle = <&ethphy4>;

	nvmem-cells = <&macaddr_config_8>;
	nvmem-cell-names = "mac-address";
	mac-address-increment = <1>;
};

&mdio {
	ethphy4: ethernet-phy@4 {
		reg = <4>;
	};
};

&switch0 {
	ports {
		port@0 {
			status = "okay";
			label = "lan1";
		};

		port@1 {
			status = "okay";
			label = "lan2";
		};

		port@2 {
			status = "okay";
			label = "lan3";
		};

		port@3 {
			status = "okay";
			label = "lan4";
		};
	};
};

&state_default {
	gpio {
		groups = "i2c", "uart3", "jtag", "wdt";
		function = "gpio";
	};
};

&config {
	compatible = "nvmem-cells";
	#address-cells = <1>;
	#size-cells = <1>;

	macaddr_config_8: macaddr@8 {
		reg = <0x8 0x6>;
	};
};

Since at the moment I can not determine a precise board model, I user the names of my project provisionally.

But always when I try to boot the initramfs image in RAM (tftpboot + bootm from u-boot console) the result is the same (with this "custom" firmware, with a firmware for Archer AX23, also tested with Tenbay T-MB5EU V01). Here is an example:

tftpboot tenbay-initramfs-kernel.bin
Using eth@1e100000 device
TFTP from server 192.168.0.43; our IP address is 192.168.0.155
Filename 'tenbay-initramfs-kernel.bin'.
Load address: 0x80010000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ##
         6.5 MiB/s
done
Bytes transferred = 5749604 (57bb64 hex)
=> bootm 0x80010000
## Loading kernel from FIT Image at 80010000 ...
   Using 'config@1' configuration
   Trying 'kernel-1' kernel subimage
     Description:  MIPS OpenWrt Linux-5.15.137
     Type:         Kernel Image
     Compression:  lzma compressed
     Data Start:   0x800100e4
     Data Size:    5735847 Bytes = 5.5 MiB
     Architecture: MIPS
     OS:           Linux
     Load Address: 0x80001000
     Entry Point:  0x80001000
     Hash algo:    crc32
     Hash value:   70aa4d8d
     Hash algo:    sha1
     Hash value:   b89ef9242eeeeb7b5c91138d91b42b423eecd77b
   Verifying Hash Integrity ... crc32+ sha1+ OK
## Loading fdt from FIT Image at 80010000 ...
   Using 'config@1' configuration
   Trying 'fdt-1' fdt subimage
     Description:  MIPS OpenWrt tenbay_t-mb5eu-v01 device tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x805887d0
     Data Size:    11850 Bytes = 11.6 KiB
     Architecture: MIPS
     Hash algo:    crc32
     Hash value:   b9b7ec00
     Hash algo:    sha1
     Hash value:   55e4b8972804a60b5107e63e989387413a2a0917
   Verifying Hash Integrity ... crc32+ sha1+ OK
   Booting using the fdt blob at 0x805887d0
   Uncompressing Kernel Image ... lzma compressed: uncompress error 1
Must RESET board to recover

Web failsafe UI started

Uncompressing Kernel Image ... lzma compressed: uncompress error 1 is the error, so I am stuck here, unavailable to get a firmware which can start to work.

Hope this is enough to start, thank you for your attention

Finally I could build an image (23.05.2) which runs, by using:

define Device/MediaTek_mt7621-RB-1
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
IMAGE_SIZE := 15744k
DEVICE_VENDOR := MediaTek
DEVICE_MODEL := RB-1
DEVICE_PACKAGES := kmod-mt7915-firmware -uboot-envtools
endef
TARGET_DEVICES += MediaTek_mt7621-RB-1

image

But now I am not available to flash in NOR. I have tried via sysupgrade inside OpenWRT and also via uboot console (TFTP) and recovery page. Always fails.

The uboot menu is:

?       - alias for 'help'
base    - print or set address offset
bdinfo  - print Board Info structure
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootm   - boot application image from memory
bootmenu- ANSI terminal bootmenu
bootp   - boot image via network using BOOTP/TFTP protocol
chpart  - change active partition
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
echo    - echo args to console
editenv - edit environment variable
env     - environment handling commands
fdt     - flattened device tree utility commands
go      - start application at address 'addr'
gpio    - query and control gpio pins
help    - print command description/usage
httpd   - Start failsafe HTTP server
iminfo  - print header information for application image
itest   - return true/false on integer compare
led     - manage LEDs
loadb   - load binary file over serial line (kermit mode)
loads   - load S-Record file over serial line
loadx   - load binary file over serial line (xmodem mode)
loady   - load binary file over serial line (ymodem mode)
loop    - infinite loop on address range
md      - memory display
mm      - memory modify (auto-incrementing address)
mtdparts- define flash/nand partitions
mtkautoboot- Display MediaTek bootmenu
mtkboardboot- Boot MTK firmware
mtkload - MTK image loading utility
mtkupgrade- MTK firmware/bootloader upgrading utility
mw      - memory write (fill)
nm      - memory modify (constant address)
printenv- print environment variables
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv  - set environment variables
setexpr - set environment variable as the result of eval expression
sf      - SPI flash sub-system
sleep   - delay execution for some time
source  - run script from memory
tftpboot- boot image via network using TFTP protocol
version - print monitor, compiler and linker version

Via uboot console I only found commands from mediatek to try to flash the firmware, in this case with "mtkupgrade":

 mtkupgrade

Available parts to be upgraded:
    0 - Bootloader
    1 - Bootloader (Advanced)
    2 - Firmware

Select a part: 2

*** Upgrading Firmwa▒YRrR▒[0m

Available load methods:
    0 - TFTP client (Default)
    1 - Xmodem
    2 - Ymodem
    3 - Kermit
    4 - S-Record

Select (enter for default): 0

Input U-Boot's IP address: 192.168.0.125
Input TFTP server's IP address: 192.168.0.43
Input IP netmask: 255.255.255.0
Input file name: caja_negra_fw_original.bin

Using eth@1e100000 device
TFTP from server 192.168.0.43; our IP address is 192.168.0.125
Filename 'caja_negra_fw_original.bin'.
Load address: 0x80010000
Loading: T #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #########################################
         2.3 MiB/s
done
Bytes transferred = 15859712 (f20000 hex)

*** Loaded 15859712 (0xf20000) bytes at 0x80010000 ***

SF: Detected w25q128bv with page size 256 Bytes, erase size 64 KiB, total 16 MiB
mtc header crc32 0x39 0xec 0xa4 0x65
CheckImageHead:crc32 check error in date:0x39eca465 check:0xfeeb5d2d
*** check head error***

From OpenWRT the sysupgrade from stock firmware (or sysupgrade -F) indicates something similar:

mtc@WR1819M:/tmp# sysupgrade caja_negra_fw_original.bin
Image check head failed.
mtc@WR1819M:/tmp# sysupgrade -F caja_negra_fw_original.bin
Image check head failed.

I extracted the stock firmware with "dd" and tried to reflash it... the error is exactly the same in any case.

So at the moment I do not find any other idea to try...

EDIT: just in case, the printenv,

=> printenv
baudrate=115200
bootcmd=mtkautoboot
bootdelay=0
fdtcontroladdr=8fff6da0
ipaddr=192.168.0.125
netmask=255.255.255.0
pressbuttonflag=0
serverip=192.168.0.43
stderr=uartlite0@1e000c00
stdin=uartlite0@1e000c00
stdout=uartlite0@1e000c00

Where mtkautoboot (which is the bootcmd) is just goes to "boot" with no details of firmware upgrade in the previous step.

  *** U-Boot Boot Menu ***

     1. Startup system (Default)
     2. Upgrade firmware
     3. Upgrade bootloader
     4. Upgrade bootloader (advanced mode)
     5. Load image
     0. U-Boot console


  Press UP/DOWN to move, ENTER to select

Apparently by booting directly in RAM with the initramfs and then a sysupgrade to the sysupgrade image worked.

Now I will be checking why the WiFi interfaces are not working, in a quick view the drivers are not finding the EEPROM data.

WiFi working with issues. I moved here because the issue is mt76 specific:

Of minimal interest only, but the firmware name it is looking for "caja_negra" refers to a black box on a plane.

But on a more serious note, could it be that the stock firmware transmits more power due to ignoring country codes and compliance to power limits? (e.g. https://forum.gl-inet.com/t/flint-2-gl-mt6000-bug-reports-collective-thread/35608/1799)

The name "caja_negra" was given by me, to give a short file name that is easy to type during testing. Since the device is literally a "black box", I think it fits well :rofl:

I don't think that it is happening because the max power by confuguration on OpenWRT is 22 dBm while I tested with country codes with 30 dBm allowed and there is no difference.

Hey @Pablomagno,

Good work so far, here are my two cents.

The manufacturer could be Shenzhen Century Xinyang Tech Co., Ltd. according to the MAC OUI. They sell devices under the brand name Wodesys. Their website is not up-to-date, but the PCB marking "WD723M V2.0" is a good indication. They're also the only manufacturer I came across who uses discrete SMD coils instead of ethernet transformers. Maybe look at /etc/hosts from the original firmware for more clues.

On the other hand, the hostname WR1819M leads us to an FCC filing by Shen Zhen MTC Co., Ltd. The username mtc relates to this name. But the photos show a different device.

IMHO you should extract the device tree from the original firmware, where you could verify the correct GPIO assignment. Using ethtool, verify which ports of the MT7530 switch are active (I see 3 RJ45 ports installed, but board.json has 4 enabled).

factory typically contains LAN/WAN MACs, the MT79x5 eeprom (which has both bands' WiFi MAC addresses in the beginning), and precal information.
Your factory partition is too small for precal, so maybe it's indeed in permanent_config, but you need to find the correct offset.
Maybe run hexdump -C /dev/mtd2 to locate all relevant MAC addresses (oftentimes LAN and WAN are at 0xe000 and 0xe006).

Please keep us updated :slight_smile:

A related FCC filing from 2021: https://fcc.report/FCC-ID/ZNPWD-ME5
This one has the PCB marking "WDR207M v2.0" so it's probably an older version. Maybe only the exterior is similar.

To help another colleage here is a template based in the .dts which I am using right now:

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT

#include "mt7621.dtsi"

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

/ {
	compatible = "manufacurer_name,model_name";
	model = "YOUR CUSTOM MODEL NAME"; 
	// EDIT THIS WITH YOUR MODEL/MANUFACTURER AND IN COHERENCE WITH THE .mk

	aliases {
		led-boot = &led_power;
		led-failsafe = &led_power;
		led-running = &led_power;
		led-upgrade = &led_power;
		label-mac-device = &gmac0;
	};

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

	keys {
		compatible = "gpio-keys";

		button-wps {
			label = "wps";
			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
			debounce-interval = <60>;
			linux,code = <KEY_WPS_BUTTON>;
		};

		button-reset {
			label = "reset";
			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
			debounce-interval = <60>;
			linux,code = <KEY_RESTART>;
		};

	};

	leds {
		compatible = "gpio-leds";

		led_power: right-green {
			label = "green:right";
			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
		};

		left-orange {
			label = "orange:left";
			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
		};

	};
	
};

&spi0 {
	status = "okay";

	flash@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <25000000>;

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			partition@0 {
				label = "Bootloader";
				reg = <0x000000000000 0x000000040000>;
				read-only;
			};

			partition@40000 {
				label = "BootConfig";
				reg = <0x000000040000 0x000000050000>;
				read-only;
			};

			config: partition@50000 {
				label = "Factory";
				reg = <0x000000050000 0x000000060000>;
				read-only;
			};

			permanent_config: partition@60000 {
				label = "permanent_config";
				reg = <0x000000060000 0x0000000e0000>;
				read-only;
			};

			partition@0e0000 {
				compatible = "denx,uimage";
				label = "firmware";
				reg = <0x0000000e0000 0x000001000000>;

			};
		};
	};
};

&pcie {
	status = "okay";
};

&pcie1 {
	wifi@0,0 {
		compatible = "mediatek,mt76";
		reg = <0x0000 0 0 0 0>;
		mediatek,mtd-eeprom = <&config 0x0>;
		nvmem-cells = <&macaddr_config_8>;
		nvmem-cell-names = "mac-address";
		mediatek,disable-radar-background;

	};
};

&gmac0 {
	nvmem-cells = <&macaddr_config_8>;
	nvmem-cell-names = "mac-address";
};

&gmac1 {
	status = "okay";
	label = "wan";
	phy-handle = <&ethphy4>;

	nvmem-cells = <&macaddr_config_8>;
	nvmem-cell-names = "mac-address";
	mac-address-increment = <1>;
};

&mdio {
	ethphy4: ethernet-phy@4 {
		reg = <4>;
	};
};

&switch0 {
	ports {
		port@0 {
			status = "okay";
			label = "lan1";
		};

		port@2 {
			status = "okay";
			label = "lan2";
		};
				
		port@1 {
			status = "disabled";
			label = "lan3";
		}; // In my case, this ports have no connector
		
		port@3 {
			status = "disabled";
			label = "lan4";
		}; // In my case, this ports have no connector
		
	};
};

&state_default {
	gpio {
		groups = "i2c", "uart3", "jtag", "wdt";
		function = "gpio";
	};
};

&config {
	compatible = "nvmem-cells";
	#address-cells = <1>;
	#size-cells = <1>;

	macaddr_config_8: macaddr@8 {
		reg = <0x4 0x6>;
		// reg = <0x8 0x6>;
	};
};
1 Like