mediatek: add support for Mercusys MR90X v1
authorMikhail Zhilkin <csharper2005@gmail.com>
Sat, 13 May 2023 13:51:45 +0000 (13:51 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 25 Jun 2023 10:25:22 +0000 (12:25 +0200)
This commit adds support for Mercusys MR90X(EU) v1 router.

Device specification
--------------------
SoC Type:   MediaTek MT7986BLA, Cortex-A53, 64-bit
RAM:        MediaTek MT7986BLA (512MB)
Flash:      SPI NAND GigaDevice GD5F1GQ5UEYIGY (128 MB)
Ethernet:   MediaTek MT7531AE + 2.5GbE MaxLinear GPY211C0VC (SLNW8)
Ethernet:   1x2.5Gbe (WAN/LAN 2.5Gbps), 3xGbE (WAN/LAN 1Gbps, LAN1, LAN2)
WLAN 2g:    MediaTek MT7975N, b/g/n/ax, MIMO 4x4
WLAN 5g:    MediaTek MT7975P(N), a/n/ac/ax, MIMO 4x4
LEDs:       1 orange and 1 green status LEDs, 4 green gpio-controlled
            LEDs on ethernet ports
Button:     1 (Reset)
USB ports:  No
Power:      12 VDC, 2 A
Connector:  Barrel
Bootloader: Main U-Boot - U-Boot 2022.01-rc4. Additionally, both UBI
            slots contain "seconduboot" (also U-Boot 2022.01-rc4)

Serial console (UART)
---------------------
                            V
+-------+-------+-------+-------+
| +3.3V |  GND  |  TX   |  RX   |
+---+---+-------+-------+-------+
    |
    +--- Don't connect

The R3 (TX line) and R6 (RX line) are absent on the PCB. You should
solder them or solder the jumpers.

Installation (UART)
-------------------
1. Place OpenWrt initramfs image on tftp server with IP 192.168.1.2
2. Attach UART, switch on the router and interrupt the boot process by
   pressing 'Ctrl-C'
3. Load and run OpenWrt initramfs image:
      tftpboot initramfs-kernel.bin
      bootm
4. Once inside OpenWrt, set / update env variables:
      fw_setenv baudrate 115200
      fw_setenv bootargs "ubi.mtd=ubi0 console=ttyS0,115200n1 loglevel=8 earlycon=uart8250,mmio32,0x11002000 init=/etc/preinit"
      fw_setenv fdtcontroladdr 5ffc0e70
      fw_setenv ipaddr 192.168.1.1
      fw_setenv loadaddr 0x46000000
      fw_setenv mtdids "spi-nand0=spi-nand0"
      fw_setenv mtdparts "spi-nand0:2M(boot),1M(u-boot-env),50M(ubi0),50M(ubi1),8M(userconfig),4M(tp_data)"
      fw_setenv netmask 255.255.255.0
      fw_setenv serverip 192.168.1.2
      fw_setenv stderr serial@11002000
      fw_setenv stdin serial@11002000
      fw_setenv stdout serial@11002000
      fw_setenv tp_boot_idx 0
5. Run 'sysupgrade -n' with the sysupgrade OpenWrt image

Installation (without UART)
---------------------------
1.  Login as root via SSH (router IP, port 20001, password - your web
    interface password)
2.  Open for editing /etc/hotplug.d/iface/65-iptv (e.g., using WinSCP and
    SSH settings from the p.1)
3.  Add a newline after "#!/bin/sh":
       telnetd -l /bin/login.sh
4.  Save "65-iptv" file
5.  Toggle "IPTV/VLAN Enable" checkbox in the router web interface and
    save
6.  Make sure that telnetd is running:
       netstat -ltunp | grep 23
7.  Login via telnet to router IP, port 23 (no username and password are
    required)
8  Upload OpenWrt "initramfs-kernel.bin" to the "/tmp" folder of the
    router (e.g., using WinSCP and SSH settings from the p.1)
9.  Stock busybox doesn't contain ubiupdatevol command. Hence, we need to
    download and upload the full version of busybox to the router. For
    example, from here:
    https://github.com/xerta555/Busybox-Binaries/raw/master/busybox-arm64
    Upload busybox-arm64 to the /tmp dir of the router and run:
    in the telnet shell:
       cd /tmp
       chmod a+x busybox-arm64
10. Check "initramfs-kernel.bin" size:
       du -h initramfs-kernel.bin
11. Delete old and create new "kernel" volume with appropriate size
    (greater than "initramfs-kernel.bin" size):
       ubirmvol /dev/ubi0 -N kernel
       ubimkvol /dev/ubi0 -n 1 -N kernel -s 9MiB
12. Write OpenWrt "initramfs-kernel.bin" to the flash:
       ./busybox-arm64 ubiupdatevol /dev/ubi0_1 /tmp/initramfs-kernel.bin
13. u-boot-env can be empty so lets create it (or overwrite it if it
    already exists) with the necessary values:
       fw_setenv baudrate 115200
       fw_setenv bootargs "ubi.mtd=ubi0 console=ttyS0,115200n1 loglevel=8 earlycon=uart8250,mmio32,0x11002000 init=/etc/preinit"
       fw_setenv fdtcontroladdr 5ffc0e70
       fw_setenv ipaddr 192.168.1.1
       fw_setenv loadaddr 0x46000000
       fw_setenv mtdids "spi-nand0=spi-nand0"
       fw_setenv mtdparts "spi-nand0:2M(boot),1M(u-boot-env),50M(ubi0),50M(ubi1),8M(userconfig),4M(tp_data)"
       fw_setenv netmask 255.255.255.0
       fw_setenv serverip 192.168.1.2
       fw_setenv stderr serial@11002000
       fw_setenv stdin serial@11002000
       fw_setenv stdout serial@11002000
       fw_setenv tp_boot_idx 0
14. Reboot to OpenWrt initramfs:
       reboot
15. Login as root via SSH (IP 192.168.1.1, port 22)
16. Upload OpenWrt sysupgrade.bin image to the /tmp dir of the router
17. Run sysupgrade:
       sysupgrade -n /tmp/sysupgrade.bin

Recovery
--------
1. Press Reset button and power on the router
2. Navigate to U-Boot recovery web server (http://192.168.1.1/) and
   upload the OEM firmware

Recovery (UART)
---------------
1. Place OpenWrt initramfs image on tftp server with IP 192.168.1.2
2. Attach UART, switch on the router and interrupt the boot process by
   pressing 'Ctrl-C'
3. Load and run OpenWrt initramfs image:
      tftpboot initramfs-kernel.bin
      bootm
4. Do what you need (restore partitions from a backup, install OpenWrt
   etc.)

Stock layout
------------
0x000000000000-0x000000200000 : "boot"
0x000000200000-0x000000300000 : "u-boot-env"
0x000000300000-0x000003500000 : "ubi0"
0x000003500000-0x000006700000 : "ubi1"
0x000006700000-0x000006f00000 : "userconfig"
0x000006f00000-0x000007300000 : "tp_data"

ubi0/ubi1 format
----------------
U-Boot at boot checks that all volumes are in place:
+-------------------------------+
| Volume Name: uboot   Vol ID: 0|
| Volume Name: kernel  Vol ID: 1|
| Volume Name: rootfs  Vol ID: 2|
+-------------------------------+

MAC addresses
-------------
+---------+-------------------+-----------+
|         | MAC               | Algorithm |
+---------+-------------------+-----------+
| label   | 00:eb:xx:xx:xx:be | label     |
| LAN     | 00:eb:xx:xx:xx:be | label     |
| WAN     | 00:eb:xx:xx:xx:bf | label+1   |
| WLAN 2g | 00:eb:xx:xx:xx:be | label     |
| WLAN 5g | 00:eb:xx:xx:xx:bd | label-1   |
+---------+-------------------+-----------+
label MAC address was found in UBI partition "tp_data", file
"default-mac". OEM wireless eeprom is also there (file
"MT7986_EEPROM.bin").

Signed-off-by: Mikhail Zhilkin <csharper2005@gmail.com>
package/boot/uboot-envtools/files/mediatek_filogic
target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1.dts [new file with mode: 0644]
target/linux/mediatek/filogic/base-files/etc/board.d/01_leds
target/linux/mediatek/filogic/base-files/etc/board.d/02_network
target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac
target/linux/mediatek/filogic/base-files/lib/preinit/09_mount_cfg_part [new file with mode: 0644]
target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh
target/linux/mediatek/filogic/base-files/lib/preinit/81_fix_eeprom [new file with mode: 0644]
target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh
target/linux/mediatek/image/filogic.mk

index 881d0c45011a97f57c00edcda919b42d78633a36..7918bdacfcdb76624e803963e8199b5f9d3a5e6c 100644 (file)
@@ -40,6 +40,10 @@ bananapi,bpi-r3)
 glinet,gl-mt3000)
        ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x80000" "0x20000"
        ;;
+mercusys,mr90x-v1)
+       local envdev=/dev/mtd$(find_mtd_index "u-boot-env")
+       ubootenv_add_uci_config "$envdev" "0x0" "0x20000" "0x20000" "1"
+       ;;
 netgear,wax220)
        ubootenv_add_uci_config "/dev/mtd5" "0x0" "0x20000" "0x20000"
        ;;
diff --git a/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1.dts b/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1.dts
new file mode 100644 (file)
index 0000000..8b8858c
--- /dev/null
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: (GL-2.0 OR MIT)
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#include "mt7986b.dtsi"
+
+/ {
+       compatible = "mercusys,mr90x-v1", "mediatek,mt7986b";
+       model = "Mercusys MR90X v1";
+
+       aliases {
+               serial0 = &uart0;
+
+               led-boot = &led_status_green;
+               led-failsafe = &led_status_green;
+               led-running = &led_status_green;
+               led-upgrade = &led_status_green;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory {
+               reg = <0 0x40000000 0 0x20000000>;
+       };
+
+       keys {
+               compatible = "gpio-keys";
+
+               reset {
+                       label = "reset";
+                       gpios = <&pio 10 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_RESTART>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led-0 {
+                       label = "green:lan2";
+                       gpios = <&pio 7 GPIO_ACTIVE_LOW>;
+               };
+
+               led-1 {
+                       label = "green:lan1";
+                       gpios = <&pio 9 GPIO_ACTIVE_LOW>;
+               };
+
+               led-2 {
+                       label = "green:lan0";
+                       gpios = <&pio 12 GPIO_ACTIVE_LOW>;
+               };
+
+               led-3 {
+                       label = "green:wan";
+                       gpios = <&pio 13 GPIO_ACTIVE_LOW>;
+               };
+
+               led-4 {
+                       label = "orange:status";
+                       gpios = <&pio 16 GPIO_ACTIVE_HIGH>;
+               };
+
+               led_status_green: led-5 {
+                       label = "green:status";
+                       gpios = <&pio 17 GPIO_ACTIVE_HIGH>;
+                       panic-indicator;
+               };
+       };
+};
+
+&crypto {
+       status = "okay";
+};
+
+&eth {
+       status = "okay";
+
+       gmac0: mac@0 {
+               compatible = "mediatek,eth-mac";
+               reg = <0>;
+               phy-mode = "2500base-x";
+
+               fixed-link {
+                       speed = <2500>;
+                       full-duplex;
+                       pause;
+               };
+       };
+
+       gmac1: mac@1 {
+               compatible = "mediatek,eth-mac";
+               reg = <1>;
+               phy-handle = <&phy6>;
+               phy-mode = "2500base-x";
+       };
+
+       mdio: mdio-bus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
+
+&mdio {
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>;
+       reset-delay-us = <1500000>;
+       reset-post-delay-us = <1000000>;
+
+       /* WAN/LAN 2.5Gbps phy
+          MaxLinear GPY211C0VC (SLNW8) */
+       phy6: phy@6 {
+               compatible = "ethernet-phy-ieee802.3-c45";
+               reg = <6>;
+       };
+
+       switch: switch@0 {
+               compatible = "mediatek,mt7531";
+               reg = <31>;
+               reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+&switch {
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               /* WAN/LAN 1Gbps port */
+               port@0 {
+                       reg = <0>;
+                       label = "lan0";
+               };
+
+               /* LAN1 port */
+               port@1 {
+                       reg = <1>;
+                       label = "lan1";
+               };
+
+               /* LAN2 port */
+               port@2 {
+                       reg = <2>;
+                       label = "lan2";
+               };
+
+               port@6 {
+                       reg = <6>;
+                       ethernet = <&gmac0>;
+                       phy-mode = "2500base-x";
+
+                       fixed-link {
+                               speed = <2500>;
+                               full-duplex;
+                               pause;
+                       };
+               };
+       };
+};
+
+&pio {
+       spi_flash_pins: spi-flash-pins-33-to-38 {
+               mux {
+                       function = "spi";
+                       groups = "spi0", "spi0_wp_hold";
+               };
+               conf-pu {
+                       pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+                       drive-strength = <8>;
+                       mediatek,pull-up-adv = <0>; /* bias-disable */
+               };
+               conf-pd {
+                       pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+                       drive-strength = <8>;
+                       mediatek,pull-down-adv = <0>; /* bias-disable */
+               };
+       };
+
+       wf_2g_5g_pins: wf_2g_5g-pins {
+               mux {
+                       function = "wifi";
+                       groups = "wf_2g", "wf_5g";
+               };
+               conf {
+                       pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+                              "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+                              "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+                              "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+                              "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+                              "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+                              "WF1_TOP_CLK", "WF1_TOP_DATA";
+                       drive-strength = <4>;
+               };
+       };
+};
+
+&spi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi_flash_pins>;
+       status = "okay";
+
+       spi_nand_flash: flash@0 {
+               compatible = "spi-nand";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0>;
+
+               spi-max-frequency = <20000000>;
+               spi-tx-buswidth = <4>;
+               spi-rx-buswidth = <4>;
+
+               partitions: partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "boot";
+                               reg = <0x0 0x200000>;
+                               read-only;
+                       };
+
+                       partition@200000 {
+                               label = "u-boot-env";
+                               reg = <0x200000 0x100000>;
+                       };
+
+                       partition@300000 {
+                               label = "ubi0";
+                               reg = <0x300000 0x3200000>;
+                       };
+
+                       partition@3500000 {
+                               label = "ubi1";
+                               reg = <0x3500000 0x3200000>;
+                               read-only;
+                       };
+
+                       partition@6700000 {
+                               label = "userconfig";
+                               reg = <0x6700000 0x800000>;
+                               read-only;
+                       };
+
+                       partition@6f00000 {
+                               label = "tp_data";
+                               reg = <0x6f00000 0x400000>;
+                               read-only;
+                       };
+               };
+       };
+};
+
+&trng {
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&watchdog {
+       status = "okay";
+};
+
+&wifi {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&wf_2g_5g_pins>;
+};
index 0ba825fd2b933efd9b372a5a605f7420cb320f79..c81bd2cd97519898d3701dcc2ff412afa6b02b47 100644 (file)
@@ -9,6 +9,12 @@ case $board in
 cudy,wr3000-v1)
        ucidef_set_led_netdev "wan" "wan" "blue:wan" "wan"
        ;;
+mercusys,mr90x-v1)
+       ucidef_set_led_netdev "lan0" "lan0" "green:lan0" "lan0" "link tx rx"
+       ucidef_set_led_netdev "lan1" "lan2" "green:lan1" "lan1" "link tx rx"
+       ucidef_set_led_netdev "lan2" "lan2" "green:lan2" "lan2" "link tx rx"
+       ucidef_set_led_netdev "wan" "wan" "green:wan" "eth1" "link tx rx"
+       ;;
 netgear,wax220)
        ucidef_set_led_netdev "eth0" "LAN" "green:lan" "eth0"
        ucidef_set_led_netdev "wlan2g" "WLAN2G" "blue:wlan2g" "phy0-ap0"
index 8803326b2791e26197bc04acce0bb44d10033fd0..c05c5d25e46218312117862f17f40fe970474266 100644 (file)
@@ -32,6 +32,9 @@ mediatek_setup_interfaces()
        mediatek,mt7988a-dsa-10g-spim-snand)
                ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3" "eth1 eth2"
                ;;
+       mercusys,mr90x-v1)
+               ucidef_set_interfaces_lan_wan "lan0 lan1 lan2" eth1
+               ;;
        qihoo,360t7)
                ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" wan
                ;;
@@ -69,6 +72,10 @@ mediatek_setup_macs()
        bananapi,bpi-r3)
                wan_mac=$(macaddr_add $(cat /sys/class/net/eth0/address) 1)
                ;;
+       mercusys,mr90x-v1)
+               label_mac=$(get_mac_binary "/tmp/tp_data/default-mac" 0)
+               lan_mac=$label_mac
+               ;;
        netgear,wax220)
                lan_mac=$(mtd_get_mac_ascii u-boot-env mac)
                label_mac=$lan_mac
index 3969a7bfe47d9c1ff067e6e84ce5b5f57466207d..4b7047eec5e5abab71e31bbe9ec78c83d345954a 100644 (file)
@@ -32,6 +32,11 @@ case "$board" in
                [ "$PHYNBR" = "0" ] && echo "$addr" > /sys${DEVPATH}/macaddress
                [ "$PHYNBR" = "1" ] && macaddr_setbit_la $(macaddr_add $addr 1) > /sys${DEVPATH}/macaddress
                ;;
+       mercusys,mr90x-v1)
+               addr=$(get_mac_binary "/tmp/tp_data/default-mac" 0)
+               [ "$PHYNBR" = "0" ] && echo "$addr" > /sys${DEVPATH}/macaddress
+               [ "$PHYNBR" = "1" ] && macaddr_add $addr -1 > /sys${DEVPATH}/macaddress
+               ;;
        netgear,wax220)
                hw_mac_addr=$(mtd_get_mac_ascii u-boot-env mac)
                [ "$PHYNBR" = "0" ] && macaddr_add $hw_mac_addr 2 > /sys${DEVPATH}/macaddress
diff --git a/target/linux/mediatek/filogic/base-files/lib/preinit/09_mount_cfg_part b/target/linux/mediatek/filogic/base-files/lib/preinit/09_mount_cfg_part
new file mode 100644 (file)
index 0000000..819df40
--- /dev/null
@@ -0,0 +1,23 @@
+. /lib/functions/system.sh
+
+mount_ubi_part() {
+       local part_name="$1"
+       local mtd_num=$(grep $part_name /proc/mtd | cut -c4)
+       local ubi_num=$(ubiattach -m $mtd_num | \
+               awk -F',' '/UBI device number [0-9]{1,}/{print $1}' | \
+               awk '{print $4}')
+       mkdir /tmp/$part_name
+       mount -r -t ubifs ubi$ubi_num:$part_name /tmp/$part_name
+}
+
+preinit_mount_cfg_part() {
+       case $(board_name) in
+       mercusys,mr90x-v1)
+               mount_ubi_part "tp_data"
+               ;;
+       *)
+               ;;
+       esac
+}
+
+boot_hook_add preinit_main preinit_mount_cfg_part
index ec078741c986efd00bcc7cf79de1bc97f8f971b8..cfddd9cedcccc53128b359d13c49ff98030e9355 100644 (file)
@@ -8,6 +8,12 @@ preinit_set_mac_address() {
                ip link set dev eth0 address "$addr"
                ip link set dev eth1 address "$addr"
                ;;
+       mercusys,mr90x-v1)
+               addr=$(get_mac_binary "/tmp/tp_data/default-mac" 0)
+               ip link set dev eth1 address "$(macaddr_add $addr 1)"
+               ;;
+       *)
+               ;;
        esac
 }
 
diff --git a/target/linux/mediatek/filogic/base-files/lib/preinit/81_fix_eeprom b/target/linux/mediatek/filogic/base-files/lib/preinit/81_fix_eeprom
new file mode 100644 (file)
index 0000000..0a842fa
--- /dev/null
@@ -0,0 +1,16 @@
+. /lib/functions/system.sh
+
+preinit_fix_eeprom() {
+       case $(board_name) in
+       mercusys,mr90x-v1)
+               eeprom="/lib/firmware/mediatek/mt7986_eeprom_mt7975_dual.bin"
+               oem="/tmp/tp_data/MT7986_EEPROM.bin"
+               [ ! -L $eeprom -a -e $oem ] && \
+                       mv -f $eeprom $eeprom.bak && ln -s $oem $eeprom
+               ;;
+       *)
+               ;;
+       esac
+}
+
+boot_hook_add preinit_main preinit_fix_eeprom
index 5b624bc5517146573efe65e2c8b37e4dc8df8566..11c2c5c66439de82be5e5b3fe9a13d82b3a6e3e9 100755 (executable)
@@ -70,6 +70,10 @@ platform_do_upgrade() {
        cudy,wr3000-v1)
                default_do_upgrade "$1"
                ;;
+       mercusys,mr90x-v1)
+               CI_UBIPART="ubi0"
+               nand_do_upgrade "$1"
+               ;;
        qihoo,360t7|\
        tplink,tl-xdr4288|\
        tplink,tl-xdr6086|\
index ae25aee2ed8e312a99cf8b558ca98dc2072807c8..fd83b9d4416f99408dcc128451a9ddce50128b6d 100644 (file)
@@ -250,6 +250,20 @@ define Device/mediatek_mt7988a-rfb-nand
 endef
 TARGET_DEVICES += mediatek_mt7988a-rfb-nand
 
+define Device/mercusys_mr90x-v1
+  DEVICE_VENDOR := Mercusys
+  DEVICE_MODEL := MR90X v1
+  DEVICE_DTS := mt7986b-mercusys-mr90x-v1
+  DEVICE_DTS_DIR := ../dts
+  DEVICE_PACKAGES := kmod-mt7986-firmware mt7986-wo-firmware
+  UBINIZE_OPTS := -E 5
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  IMAGE_SIZE := 51200k
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+endef
+TARGET_DEVICES += mercusys_mr90x-v1
+
 define Device/qihoo_360t7
   DEVICE_VENDOR := Qihoo
   DEVICE_MODEL := 360T7