diff mbox series

[21.02,03/11] ramips: mt7621: Add support for ZyXEL NR7101

Message ID 20210608094512.29956-4-ynezz@true.cz
State Accepted
Delegated to: Petr Štetiar
Headers show
Series ramips: mt7621: backport support for 9 devices | expand

Commit Message

Petr Štetiar June 8, 2021, 9:45 a.m. UTC
From: Bjørn Mork <bjorn@mork.no>

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>
(cherry picked from commit 2449a632084b29632605e5a79ce5d73028eb15dd)
---
 package/boot/uboot-envtools/files/ramips      |   5 +
 .../linux/ramips/dts/mt7621_zyxel_nr7101.dts  | 164 ++++++++++++++++++
 target/linux/ramips/image/mt7621.mk           |  22 +++
 .../mt7621/base-files/etc/board.d/02_network  |   3 +
 .../base-files/etc/board.d/03_gpio_switches   |   3 +
 .../mt7621/base-files/etc/init.d/bootcount    |   5 +
 .../mt7621/base-files/lib/upgrade/platform.sh |   6 +
 7 files changed, 208 insertions(+)
 create mode 100644 target/linux/ramips/dts/mt7621_zyxel_nr7101.dts

Comments

Bjørn Mork June 8, 2021, 11:10 a.m. UTC | #1
Tested-by: Bjørn Mork <bjorn@mork.no>


Unrelated, but confused the hell out of me:

I tested this by sysupgrading from a master based installation using a
5.10 kernel.  And ended up with a tmpfs overlay because of:

[    9.833676] UBIFS (ubi0:1): Mounting in unauthenticated mode
[    9.845003] UBIFS error (ubi0:1 pid 561): ubifs_mount: 'compressor "zstd" is not compiled in
[    9.862780] mount_root: failed to mount -t ubifs /dev/ubi0_1 /tmp/overlay: No error information
[    9.880490] mount_root: overlay filesystem has not been fully initialized yet
[    9.895085] mount_root: switching to ubifs overlay
[    9.904741] mount_root: switching to ubifs failed - fallback to ramoverlay


So I reinstalled the 21.02 build by sysupgrading from the running 21.02,
and everything was fine again - as expected.

I realize that I did this to myself, and that this sort of downgrade
using sysupgrade is a pretty weird usecase.  But maybe there are other
similar situations where we can end up with an unmountable UBIFS due to
the missing compressor?

The problem seems to be as simple as CONFIG_UBIFS_FS_ZSTD being
undefined in target/linux/generic/config-5.4 in 21.02.  It is defined
for a number of targets, though. Just not ralink.

This was fixed in master by commit

  be7b56027899 ("kernel: enable lzo, zlib and zstd in ubifs").

Obvious candidate for backport to 21.02?




Bjørn
Hauke Mehrtens June 8, 2021, 8:33 p.m. UTC | #2
On 6/8/21 1:10 PM, Bjørn Mork wrote:
> Tested-by: Bjørn Mork <bjorn@mork.no>
> 
> 
> Unrelated, but confused the hell out of me:
> 
> I tested this by sysupgrading from a master based installation using a
> 5.10 kernel.  And ended up with a tmpfs overlay because of:
> 
> [    9.833676] UBIFS (ubi0:1): Mounting in unauthenticated mode
> [    9.845003] UBIFS error (ubi0:1 pid 561): ubifs_mount: 'compressor "zstd" is not compiled in
> [    9.862780] mount_root: failed to mount -t ubifs /dev/ubi0_1 /tmp/overlay: No error information
> [    9.880490] mount_root: overlay filesystem has not been fully initialized yet
> [    9.895085] mount_root: switching to ubifs overlay
> [    9.904741] mount_root: switching to ubifs failed - fallback to ramoverlay
> 
> 
> So I reinstalled the 21.02 build by sysupgrading from the running 21.02,
> and everything was fine again - as expected.
> 
> I realize that I did this to myself, and that this sort of downgrade
> using sysupgrade is a pretty weird usecase.  But maybe there are other
> similar situations where we can end up with an unmountable UBIFS due to
> the missing compressor?
> 
> The problem seems to be as simple as CONFIG_UBIFS_FS_ZSTD being
> undefined in target/linux/generic/config-5.4 in 21.02.  It is defined
> for a number of targets, though. Just not ralink.
> 
> This was fixed in master by commit
> 
>    be7b56027899 ("kernel: enable lzo, zlib and zstd in ubifs").
> 
> Obvious candidate for backport to 21.02?

This problem should affect the following targets:
target/linux/apm821xx/nand
target/linux/ath79/mikrotik
target/linux/ath79/nand
target/linux/kirkwood
target/linux/lantiq/xway
target/linux/mediatek/mt7622
target/linux/mvebu
target/linux/oxnas/ox820
target/linux/ramips/mt7621
They all have CONFIG_UBIFS_FS set, but not CONFIG_UBIFS_FS_ZSTD.

OpenWrt 21.02 uses UBIFS_COMPR_LZO by default OpenWrt master uses 
UBIFS_COMPR_ZSTD by default.
Downgrading a OpenWrt 21.02 installation to 19.07 should work.

Did someone check how much bigger the images are getting with 
CONFIG_UBIFS_FS_ZSTD?

If they are not so much bigger I would suggest to add 
CONFIG_UBIFS_FS_ZSTD to OpenWrt 21.02 then the downgrade from master 
should work.

Hauke
Rui Salvaterra June 8, 2021, 9:09 p.m. UTC | #3
Hi, guys,

On Tue, 8 Jun 2021 at 21:33, Hauke Mehrtens <hauke@hauke-m.de> wrote:
>
> On 6/8/21 1:10 PM, Bjørn Mork wrote:
> > Tested-by: Bjørn Mork <bjorn@mork.no>
> >
> >
> > Unrelated, but confused the hell out of me:
> >
> > I tested this by sysupgrading from a master based installation using a
> > 5.10 kernel.  And ended up with a tmpfs overlay because of:
> >
> > [    9.833676] UBIFS (ubi0:1): Mounting in unauthenticated mode
> > [    9.845003] UBIFS error (ubi0:1 pid 561): ubifs_mount: 'compressor "zstd" is not compiled in
> > [    9.862780] mount_root: failed to mount -t ubifs /dev/ubi0_1 /tmp/overlay: No error information
> > [    9.880490] mount_root: overlay filesystem has not been fully initialized yet
> > [    9.895085] mount_root: switching to ubifs overlay
> > [    9.904741] mount_root: switching to ubifs failed - fallback to ramoverlay
> >
> >
> > So I reinstalled the 21.02 build by sysupgrading from the running 21.02,
> > and everything was fine again - as expected.
> >
> > I realize that I did this to myself, and that this sort of downgrade
> > using sysupgrade is a pretty weird usecase.  But maybe there are other
> > similar situations where we can end up with an unmountable UBIFS due to
> > the missing compressor?

As long as we don't disable any previously enabled algorithms (and the
kernels have them enabled), we're fine. Your situation was indeed
unfortunate, but definitely expected. :/

> > The problem seems to be as simple as CONFIG_UBIFS_FS_ZSTD being
> > undefined in target/linux/generic/config-5.4 in 21.02.  It is defined
> > for a number of targets, though. Just not ralink.
> >
> > This was fixed in master by commit
> >
> >    be7b56027899 ("kernel: enable lzo, zlib and zstd in ubifs").
> >
> > Obvious candidate for backport to 21.02?
>
> This problem should affect the following targets:
> target/linux/apm821xx/nand
> target/linux/ath79/mikrotik
> target/linux/ath79/nand
> target/linux/kirkwood
> target/linux/lantiq/xway
> target/linux/mediatek/mt7622
> target/linux/mvebu
> target/linux/oxnas/ox820
> target/linux/ramips/mt7621
> They all have CONFIG_UBIFS_FS set, but not CONFIG_UBIFS_FS_ZSTD.
>
> OpenWrt 21.02 uses UBIFS_COMPR_LZO by default OpenWrt master uses
> UBIFS_COMPR_ZSTD by default.
> Downgrading a OpenWrt 21.02 installation to 19.07 should work.
>
> Did someone check how much bigger the images are getting with
> CONFIG_UBIFS_FS_ZSTD?

I haven't measured specifically (I build as few modules as humanly
feasible), but zstd is a chubby compression algorithm, the kmod
package weighing about 100 kiB. However, the sooner we enable it, the
sooner we'll be able to get rid of the others (zlib, lzo), which will
even things out a bit. Of course, disabling algorithms will require a
complete wipe on sysupgrade…

> If they are not so much bigger I would suggest to add
> CONFIG_UBIFS_FS_ZSTD to OpenWrt 21.02 then the downgrade from master
> should work.

+1, wholeheartedly. However, if enabling zstd by default in 21.02 is
on the menu, I'd really like to see the 5.4 part of c4d39c4d5f
("kernel: default to zstd compression in ubifs") there too. Enabling
support for zstd and not using it by default would be a shame.

Thanks,
Rui
diff mbox series

Patch

diff --git a/package/boot/uboot-envtools/files/ramips b/package/boot/uboot-envtools/files/ramips
index a47e2950d3ae..c153b6a4226b 100644
--- a/package/boot/uboot-envtools/files/ramips
+++ b/package/boot/uboot-envtools/files/ramips
@@ -54,6 +54,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
diff --git a/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts b/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts
new file mode 100644
index 000000000000..f6a42286f10e
--- /dev/null
+++ b/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";
+	};
+};
diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk
index a8f558326d99..a7f6c80f40ff 100644
--- a/target/linux/ramips/image/mt7621.mk
+++ b/target/linux/ramips/image/mt7621.mk
@@ -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
@@ -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
diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
index 89e679be7cd8..f017e4782e0e 100755
--- a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
@@ -64,6 +64,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"
diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches b/target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches
index 82bbdd24f674..8ef815634f08 100755
--- a/target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches
@@ -23,6 +23,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"
 	;;
diff --git a/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount b/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount
index 7ef0053e6790..a155458d3f23 100755
--- a/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount
+++ b/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount
@@ -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
 }
diff --git a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
index c9152c5cf4d6..d30bc3db2edd 100755
--- a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
@@ -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" ] &&\