Skip to content

Commit

Permalink
ramips: mt7621: Add support for ZyXEL NR7101
Browse files Browse the repository at this point in the history
The ZyXEL NR7101 is an 802.3at PoE powered 5G outdoor (IP68) CPE
with integrated directional 5G/LTE antennas.

Specifications:

 - SoC: MediaTek MT7621AT
 - RAM: 256 MB
 - Flash: 128 MB MB NAND (MX30LF1G18AC)
 - WiFi: MediaTek MT7603E
 - Switch: 1 LAN port (Gigabiti)
 - 5G/LTE: Quectel RG502Q-EA connected by USB3 to SoC
 - SIM: 2 micro-SIM slots under transparent cover
 - Buttons: Reset, WLAN under same cover
 - LEDs: Multicolour green/red/yellow under same cover (visible)
 - Power: 802.3at PoE via LAN port

The device is built as an outdoor ethernet to 5G/LTE bridge or
router. The Wifi interface is intended for installation and/or
temporary management purposes only.

UART Serial:

57600N1
Located on populated 5 pin header J5:

 [o] GND
 [ ] key - no pin
 [o] RX
 [o] TX
 [o] 3.3V Vcc

Remove the SIM/button/LED cover, the WLAN button and 12 screws
holding the back plate and antenna cover together. The GPS antenna
is fixed to the cover, so be careful with the cable.  Remove 4
screws fixing the antenna board to the main board, again being
careful with the cables.

A bluetooth TTL adapter is recommended for permanent console
access, to keep the router water and dustproof. The 3.3V pin is
able to power such an adapter.

MAC addresses:

OpenWrt OEM   Address          Found as
lan     eth2  08:26:97:*:*:BC  Factory 0xe000 (hex), label
wlan0   ra0   08:26:97:*:*:BD  Factory 0x4 (hex)
wwan0   usb0  random

WARNING!!

ISP managed firmware might at any time update itself to a version
where all known workarounds have been disabled.  Never boot an ISP
managed firmware with a SIM in any of the slots if you intend to use
the router with OpenWrt. The bootloader lock can only be disabled with
root access to running firmware. The flash chip is physically
inaccessible without soldering.

Installation from OEM web GUI:

- Log in as "supervisor" on https://172.17.1.1/
- Upload OpenWrt initramfs-recovery.bin image on the
  Maintenance -> Firmware page
- Wait for OpenWrt to boot and ssh to root@192.168.1.1
- (optional) Copy OpenWrt to the recovery partition. See below
- Sysupgrade to the OpenWrt sysupgrade image and reboot

Installation from OEM ssh:

- Log in as "root" on 172.17.1.1 port 22022
- scp OpenWrt initramfs-recovery.bin image to 172.17.1.1:/tmp
- Prepare bootloader config by running:
    nvram setro uboot DebugFlag 0x1
    nvram setro uboot CheckBypass 0
    nvram commit
- Run "mtd_write -w write initramfs-recovery.bin Kernel" and reboot
- Wait for OpenWrt to boot and ssh to root@192.168.1.1
- (optional) Copy OpenWrt to the recovery partition. See below
- Sysupgrade to the OpenWrt sysupgrade image and reboot

Copying OpenWrt to the recovery partition:

- Verify that you are running a working OpenWrt recovery image
  from flash
- ssh to root@192.168.1.1 and run:
    fw_setenv CheckBypass 0
    mtd -r erase Kernel2
- Wait while the bootloader mirrors Image1 to Image2

NOTE: This should only be done after successfully booting the OpenWrt
  recovery image from the primary partition during installation.  Do
  not do this after having sysupgraded OpenWrt!  Reinstalling the
  recovery image on normal upgrades is not required or recommended.

Installation from Z-Loader:

- Halt boot by pressing Escape on console
- Set up a tftp server to serve the OpenWrt initramfs-recovery.bin
  image at 10.10.10.3
- Type "ATNR 1,initramfs-recovery.bin" at the "ZLB>" prompt
- Wait for OpenWrt to boot and ssh to root@192.168.1.1
- Sysupgrade to the OpenWrt sysupgrade image

NOTE: ATNR will write the recovery image to both primary and recovery
  partitions in one go.

Booting from RAM:

- Halt boot by pressing Escape on console
- Type "ATGU" at the "ZLB>" prompt to enter the U-Boot menu
- Press "4" to select "4: Entr boot command line interface."
- Set up a tftp server to serve the OpenWrt initramfs-recovery.bin
  image at 10.10.10.3
- Load it using "tftpboot 0x88000000 initramfs-recovery.bin"
- Boot with "bootm  0x8800017C" to skip the 380 (0x17C) bytes ZyXEL
  header

This method can also be used to RAM boot OEM firmware. The warning
regarding OEM applies!  Never boot an unknown OEM firmware, or any OEM
firmware with a SIM in any slot.

NOTE: U-Boot configuration is incomplete (on some devices?). You may
  have to configure a working mac address before running tftp using
   "setenv eth0addr <mac>"

Unlocking the bootloader:

If you are unebale to halt boot, then the bootloader is locked.

The OEM firmware locks the bootloader on every boot by setting
DebugFlag to 0.  Setting it to 1 is therefore only temporary
when OEM firmware is installed.

- Run "nvram setro uboot DebugFlag 0x1; nvram commit" in OEM firmware
- Run "fw_setenv DebugFlag 0x1" in OpenWrt

  NOTE:
    OpenWrt does this automatically on first boot if necessary

  NOTE2:
    Setting the flag to 0x1 avoids the reset to 0 in known OEM
    versions, but this might change.

  WARNING:
    Writing anything to flash while the bootloader is locked is
    considered extremely risky. Errors might cause a permanent
    brick!

Enabling management access from LAN:

Temporary workaround to allow installing OpenWrt if OEM firmware
has disabled LAN management:

- Connect to console
- Log in as "root"
- Run "iptables -I INPUT -i br0 -j ACCEPT"

Notes on the OEM/bootloader dual partition scheme

The dual partition scheme on this device uses Image2 as a recovery
image only. The device will always boot from Image1, but the
bootloader might copy Image2 to Image1 under specific conditions. This
scheme prevents repurposing of the space occupied by Image2 in any
useful way.

Validation of primary and recovery images is controlled by the
variables CheckBypass, Image1Stable, and Image1Try.

The bootloader sets CheckBypass to 0 and reboots if Image1 fails
validation.

If CheckBypass is 0 and Image1 is invalid then Image2 is copied to
Image1.

If CheckBypass is 0 and Image2 is invalid, then Image1 is copied to
Image2.

If CheckBypass is 1 then all tests are skipped and Image1 is booted
unconditionally.  CheckBypass is set to 1 after each successful
validation of Image1.

Image1Try is incremented if Image1Stable is 0, and Image2 is copied to
Image1 if Image1Try is 3 or larger.  But the bootloader only tests
Image1Try if CheckBypass is 0, which is impossible unless the booted
image sets it to 0 before failing.

The system is therefore not resilient against runtime errors like
failure to mount the rootfs, unless the kernel image sets CheckBypass
to 0 before failing. This is not yet implemented in OpenWrt.

Setting Image1Stable to 1 prevents the bootloader from updating
Image1Try on every boot, saving unnecessary writes to the environment
partition.

Keeping an OpenWrt initramfs recovery as Image2 is recommended
primarily to avoid unwanted OEM firmware boots on failure. Ref the
warning above. It enables console-less recovery in case of some
failures to boot from Image1.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
  • Loading branch information
bmork authored and ynezz committed May 9, 2021
1 parent 48cad07 commit 2449a63
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 0 deletions.
5 changes: 5 additions & 0 deletions package/boot/uboot-envtools/files/ramips
Expand Up @@ -53,6 +53,11 @@ xiaomi,mi-router-ac2100|\
xiaomi,redmi-router-ac2100)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x1000" "0x20000"
;;
zyxel,nr7101)
idx="$(find_mtd_index Config)"
[ -n "$idx" ] && \
ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x1000" "0x80000"
;;
esac

config_load ubootenv
Expand Down
164 changes: 164 additions & 0 deletions target/linux/ramips/dts/mt7621_zyxel_nr7101.dts
@@ -0,0 +1,164 @@
// 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 = "zyxel,nr7101", "mediatek,mt7621-soc";
model = "ZyXEL NR7101";

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

leds {
compatible = "gpio-leds";

led@13 {
label = "yellow:system";
gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
};

power: led@14 {
label = "green:system";
gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
};

led@15 {
label = "red:system";
gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
};
};

keys {
compatible = "gpio-keys";

wps {
label = "wlan";
gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
linux,code = <KEY_WLAN>;
};

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

&gpio {
lte_pwrkey {
gpio-hog;
gpios = <4 GPIO_ACTIVE_HIGH>;
output-high;
line-name = "lte-pwrkey";
};

lte_power {
gpio-hog;
gpios = <18 GPIO_ACTIVE_HIGH>;
output-high;
line-name = "lte-power";
};
};

&nand {
status = "okay";

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

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

partition@80000 {
label = "Config";
reg = <0x80000 0x80000>;
};

factory: partition@100000 {
label = "Factory";
reg = <0x100000 0x40000>;
read-only;
};

partition@140000 {
label = "Kernel";
reg = <0x140000 0x1ec0000>;
};

partition@540000 {
label = "ubi";
reg = <0x540000 0x1ac0000>;
};

partition@2140000 {
label = "Kernel2";
reg = <0x2140000 0x1ec0000>;
};

partition@4000000 {
label = "wwan";
reg = <0x4000000 0x100000>;
};

partition@4100000 {
label = "data";
reg = <0x4100000 0x1000000>;
};

partition@5100000 {
label = "rom-d";
reg = <0x5100000 0x100000>;
read-only;
};

partition@5200000 {
label = "reserve";
reg = <0x5200000 0x80000>;
};
};
};

&pcie {
status = "okay";
};

&pcie0 {
mt76@0,0 {
reg = <0x0000 0 0 0 0>;
mediatek,mtd-eeprom = <&factory 0x0>;
};
};

&gmac0 {
mtd-mac-address = <&factory 0xe000>;
};

&switch0 {
ports {
port@2 {
status = "okay";
label = "lan";
};
};
};

&state_default {
gpio {
groups = "i2c", "rgmii2", "uart3", "jtag", "wdt";
function = "gpio";
};
};
22 changes: 22 additions & 0 deletions target/linux/ramips/image/mt7621.mk
Expand Up @@ -79,6 +79,13 @@ define Build/ubnt-erx-factory-image
fi
endef

define Build/zytrx-header
$(eval board=$(word 1,$(1)))
$(eval version=$(word 2,$(1)))
$(STAGING_DIR_HOST)/bin/zytrx -B '$(board)' -v '$(version)' -i $@ -o $@.new
mv $@.new $@
endef

define Device/dsa-migration
DEVICE_COMPAT_VERSION := 1.1
DEVICE_COMPAT_MESSAGE := Config cannot be migrated from swconfig to DSA
Expand Down Expand Up @@ -1504,6 +1511,21 @@ define Device/zio_freezio
endef
TARGET_DEVICES += zio_freezio

define Device/zyxel_nr7101
$(Device/dsa-migration)
BLOCKSIZE := 128k
PAGESIZE := 2048
UBINIZE_OPTS := -E 5
DEVICE_VENDOR := ZyXEL
DEVICE_MODEL := NR7101
DEVICE_PACKAGES := kmod-mt7603 kmod-usb3 uboot-envtools kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi
KERNEL := $(KERNEL_DTB) | uImage lzma | zytrx-header $$(DEVICE_MODEL) $$(VERSION_DIST)-$$(REVISION)
KERNEL_INITRAMFS := $(KERNEL_DTB) | uImage lzma | zytrx-header $$(DEVICE_MODEL) 9.99(ABUV.9)$$(VERSION_DIST)-recovery
KERNEL_INITRAMFS_SUFFIX := -recovery.bin
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
endef
TARGET_DEVICES += zyxel_nr7101

define Device/zyxel_wap6805
$(Device/dsa-migration)
BLOCKSIZE := 128k
Expand Down
3 changes: 3 additions & 0 deletions target/linux/ramips/mt7621/base-files/etc/board.d/02_network
Expand Up @@ -63,6 +63,9 @@ ramips_setup_interfaces()
ubnt,edgerouter-x-sfp)
ucidef_set_interfaces_lan_wan "eth1 eth2 eth3 eth4 eth5" "eth0"
;;
zyxel,nr7101)
ucidef_set_interfaces_lan_wan "lan" "wan"
;;
zyxel,wap6805)
ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
ucidef_set_interface "qtn" ifname "eth1" protocol "static" ipaddr "1.1.1.1" netmask "255.255.255.0"
Expand Down
Expand Up @@ -22,6 +22,9 @@ ubnt,edgerouter-x-sfp)
ucidef_add_gpio_switch "poe_power_port3" "PoE Power Port3" "403"
ucidef_add_gpio_switch "poe_power_port4" "PoE Power Port4" "404"
;;
zyxel,nr7101)
ucidef_add_gpio_switch "lte_reset" "Reset LTE/5G modem" "483"
;;
zyxel,wap6805)
ucidef_add_gpio_switch "qtn_power" "Quantenna Module Power" "496" "1"
;;
Expand Down
5 changes: 5 additions & 0 deletions target/linux/ramips/mt7621/base-files/etc/init.d/bootcount
Expand Up @@ -16,5 +16,10 @@ boot() {
samknows,whitebox-v8)
fw_setenv bootcount 0
;;
zyxel,nr7101)
[ $(printf %d $(fw_printenv -n DebugFlag)) -gt 0 ] || fw_setenv DebugFlag 0x1
[ $(printf %d $(fw_printenv -n Image1Stable)) -gt 0 ] || fw_setenv Image1Stable 1
[ $(printf %d $(fw_printenv -n Image1Try)) -gt 0 ] && fw_setenv Image1Try 0
;;
esac
}
6 changes: 6 additions & 0 deletions target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
Expand Up @@ -82,6 +82,12 @@ platform_do_upgrade() {
ubnt,edgerouter-x-sfp)
platform_upgrade_ubnt_erx "$1"
;;
zyxel,nr7101)
fw_setenv CheckBypass 0
fw_setenv Image1Stable 0
CI_KERNPART="Kernel"
nand_do_upgrade "$1"
;;
zyxel,wap6805)
local kernel2_mtd="$(find_mtd_part Kernel2)"
[ "$(hexdump -n 4 -e '"%x"' $kernel2_mtd)" = "56190527" ] &&\
Expand Down

0 comments on commit 2449a63

Please sign in to comment.