aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--package/utils/zyxel-bootconfig/Makefile38
-rw-r--r--package/utils/zyxel-bootconfig/files/95_apply_bootconfig16
-rw-r--r--package/utils/zyxel-bootconfig/src/Makefile7
-rw-r--r--package/utils/zyxel-bootconfig/src/zyxel-bootconfig.c331
-rwxr-xr-xscripts/mkits-zyxel-fit.sh38
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_nwa-ax.dtsi151
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts45
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts6
-rw-r--r--target/linux/ramips/image/mt7621.mk34
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/board.d/02_network4
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac6
-rwxr-xr-xtarget/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh4
12 files changed, 678 insertions, 2 deletions
diff --git a/package/utils/zyxel-bootconfig/Makefile b/package/utils/zyxel-bootconfig/Makefile
new file mode 100644
index 0000000000..eb2dd79b82
--- /dev/null
+++ b/package/utils/zyxel-bootconfig/Makefile
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2022 David Bauer <mail@david-bauer.net>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=zyxel-bootconfig
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/zyxel-bootconfig
+ SECTION:=utils
+ CATEGORY:=Base system
+ TITLE:=Utility for handling ZyXEL Bootconfig settings
+ MAINTAINER:=David Bauer <mail@david-bauer.net>
+endef
+
+define Package/zyxel-bootconfig/description
+ This package contains an utility that allows handling ZyXEL Bootconfig settings.
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS) -Wall"
+endef
+
+define Package/zyxel-bootconfig/install
+ $(INSTALL_DIR) $(1)/usr/bin $(1)/lib/preinit
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/zyxel-bootconfig $(1)/usr/bin/
+ $(CP) ./files/95_apply_bootconfig $(1)/lib/preinit/95_apply_bootconfig
+endef
+
+$(eval $(call BuildPackage,zyxel-bootconfig))
diff --git a/package/utils/zyxel-bootconfig/files/95_apply_bootconfig b/package/utils/zyxel-bootconfig/files/95_apply_bootconfig
new file mode 100644
index 0000000000..c47857b082
--- /dev/null
+++ b/package/utils/zyxel-bootconfig/files/95_apply_bootconfig
@@ -0,0 +1,16 @@
+apply_bootconfig() {
+ . /lib/functions.sh
+
+ local part
+
+ case $(board_name) in
+ zyxel,nwa50ax|\
+ zyxel,nwa55axe)
+ mtd_idx=$(find_mtd_index "bootconfig")
+ zyxel-bootconfig "/dev/mtd$mtd_idx" set-image-status 0 valid
+ zyxel-bootconfig "/dev/mtd$mtd_idx" set-active-image 0
+ ;;
+ esac
+}
+
+[ "$INITRAMFS" = "1" ] || boot_hook_add preinit_main apply_bootconfig
diff --git a/package/utils/zyxel-bootconfig/src/Makefile b/package/utils/zyxel-bootconfig/src/Makefile
new file mode 100644
index 0000000000..66741c8acf
--- /dev/null
+++ b/package/utils/zyxel-bootconfig/src/Makefile
@@ -0,0 +1,7 @@
+all: zyxel-bootconfig
+
+zyxel-bootconfig:
+ $(CC) $(CFLAGS) -Wall zyxel-bootconfig.c -o zyxel-bootconfig
+
+clean:
+ rm -f zyxel-bootconfig
diff --git a/package/utils/zyxel-bootconfig/src/zyxel-bootconfig.c b/package/utils/zyxel-bootconfig/src/zyxel-bootconfig.c
new file mode 100644
index 0000000000..6dd2f8969f
--- /dev/null
+++ b/package/utils/zyxel-bootconfig/src/zyxel-bootconfig.c
@@ -0,0 +1,331 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* Copyright (C) 2022 David Bauer <mail@david-bauer.net> */
+
+/*
+ * First byte: Image status
+ *
+ * Possible status-codes:
+ * 0x0: none
+ * 0x1: new
+ * 0x2: valid
+ * 0x3: invalid
+ *
+ * Example: Image 0 valid; Image 1 invalid
+ * 11001000
+ * || ||
+ * img1||
+ * img0
+ *
+ * Second byte: Active Image
+ * Possible values:
+ * 0x0: Image0 active
+ * 0x1: Image1 active
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <mtd/mtd-user.h>
+
+#define BOOTCONFIG_SIZE 0x20
+#define BOOTCONFIG_IMAGE_STATUS 0x0
+#define BOOTCONFIG_ACTIVE_IMAGE 0x1
+
+#define IMAGE_0_SHIFT 2
+#define IMAGE_0_MASK 0x0c
+#define IMAGE_1_SHIFT 6
+#define IMAGE_1_MASK 0xc0
+
+#define IMAGE_STATUS(img0, img1) (((img0 << IMAGE_0_SHIFT) & IMAGE_0_MASK) | ((img1 << IMAGE_1_SHIFT) & IMAGE_1_MASK))
+
+#define ACTIVE_IMAGE_MASK 0x1
+#define ACTIVE_IMAGE(img) (img & ACTIVE_IMAGE_MASK)
+
+enum zyxel_bootconfig_image_status {
+ IMAGE_STATUS_NONE = 0x0,
+ IMAGE_STATUS_NEW = 0x1,
+ IMAGE_STATUS_VALID = 0x2,
+ IMAGE_STATUS_INVALID = 0x3,
+ __IMAGE_STATUS_EINVAL,
+};
+
+struct zyxel_bootconfig {
+ enum zyxel_bootconfig_image_status image0_status;
+ enum zyxel_bootconfig_image_status image1_status;
+ unsigned int active_image;
+};
+
+struct zyxel_bootconfig_mtd {
+ struct mtd_info_user mtd_info;
+ int fd;
+};
+
+struct zyxel_image_status {
+ enum zyxel_bootconfig_image_status code;
+ const char *name;
+};
+
+struct zyxel_image_status image_status_codes[] = {
+ { .code = IMAGE_STATUS_NONE, .name = "none" },
+ { .code = IMAGE_STATUS_NEW, .name = "new" },
+ { .code = IMAGE_STATUS_VALID, .name = "valid" },
+ { .code = IMAGE_STATUS_INVALID, .name = "invalid" },
+ {},
+};
+
+
+static enum zyxel_bootconfig_image_status zyxel_bootconfig_image_status_parse(const char *status) {
+ struct zyxel_image_status* s;
+
+ for (s = image_status_codes; s->name; s++) {
+ if (!strcmp(status, s->name)) {
+ return s->code;
+ }
+ }
+
+ return __IMAGE_STATUS_EINVAL;
+}
+
+const char *zyxel_bootconfig_image_status_name(const enum zyxel_bootconfig_image_status bootconfig) {
+ struct zyxel_image_status* s;
+
+ for (s = image_status_codes; s->name; s++) {
+ if (bootconfig == s->code) {
+ return s->name;
+ }
+ }
+
+ return "N/A";
+}
+
+static void zyxel_bootconfig_mtd_close(struct zyxel_bootconfig_mtd *mtd) {
+ close(mtd->fd);
+}
+
+
+static int zyxel_bootconfig_mtd_open(struct zyxel_bootconfig_mtd *mtd, const char *mtd_name) {
+ int ret = 0;
+
+ mtd->fd = open(mtd_name, O_RDWR | O_SYNC);
+ if (mtd->fd < 0) {
+ fprintf(stderr, "Could not open mtd device: %s\n", mtd_name);
+ ret = -1;
+ goto out;
+ }
+
+ if (ioctl(mtd->fd, MEMGETINFO, &mtd->mtd_info)) {
+ fprintf(stderr, "Could not get MTD device info from %s\n", mtd_name);
+ ret = -1;
+ zyxel_bootconfig_mtd_close(mtd);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+
+static int zyxel_bootconfig_read(struct zyxel_bootconfig *config, struct zyxel_bootconfig_mtd *mtd) {
+ char *args = NULL;
+ int ret = 0;
+
+ /* Allocate memory for reading boot-config partition */
+ args = calloc(1, mtd->mtd_info.erasesize);
+ if (!args) {
+ fprintf(stderr, "Could not allocate memory!\n");
+ ret = -1;
+ goto out;
+ }
+
+ /* Read bootconfig partition */
+ pread(mtd->fd, args, mtd->mtd_info.erasesize, 0);
+
+ /* Parse config */
+ memset(config, 0, sizeof(*config));
+
+ config->image0_status = (args[BOOTCONFIG_IMAGE_STATUS] & IMAGE_0_MASK) >> IMAGE_0_SHIFT;
+ config->image1_status = (args[BOOTCONFIG_IMAGE_STATUS] & IMAGE_1_MASK) >> IMAGE_1_SHIFT;
+ config->active_image = (args[BOOTCONFIG_ACTIVE_IMAGE] & ACTIVE_IMAGE_MASK);
+
+out:
+ if (args)
+ free(args);
+ return ret;
+}
+
+
+static int zyxel_bootconfig_write(struct zyxel_bootconfig *config, struct zyxel_bootconfig_mtd *mtd)
+{
+ struct erase_info_user erase_info;
+ char img_status, img_active;
+ char *args = NULL;
+ int ret = 0;
+
+ /* Allocate memory for reading boot-config partition */
+ args = calloc(1, mtd->mtd_info.erasesize);
+ if (!args) {
+ fprintf(stderr, "Could not allocate memory!\n");
+ ret = -1;
+ goto out;
+ }
+
+ /* Read bootconfig partition */
+ pread(mtd->fd, args, mtd->mtd_info.erasesize, 0);
+
+ img_status = IMAGE_STATUS(config->image0_status, config->image1_status);
+ img_active = ACTIVE_IMAGE(config->active_image);
+
+ /* Check if bootconfig has to be written */
+ if (args[BOOTCONFIG_IMAGE_STATUS] == img_status && args[BOOTCONFIG_ACTIVE_IMAGE] == img_active) {
+ ret = 0;
+ goto out;
+ }
+
+ /* Erase first block (containing the magic) */
+ erase_info.start = 0;
+ erase_info.length = mtd->mtd_info.erasesize;
+ ret = ioctl(mtd->fd, MEMERASE, &erase_info);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to erase block: %i\n", ret);
+ goto out;
+ }
+
+
+ /* Write bootconfig */
+ args[BOOTCONFIG_IMAGE_STATUS] = img_status;
+ args[BOOTCONFIG_ACTIVE_IMAGE] = img_active;
+
+ if (pwrite(mtd->fd, args, mtd->mtd_info.erasesize, 0) != mtd->mtd_info.erasesize) {
+ fprintf(stderr, "Error writing bootconfig!\n");
+ ret = -1;
+ goto out;
+ }
+
+out:
+ if (args)
+ free(args);
+ return ret;
+}
+
+
+static void zyxel_bootconfig_print_usage(char *programm)
+{
+ struct zyxel_image_status* s = image_status_codes;
+
+ printf("Usage: %s <mtd-device> <command> [args]\n", programm);
+ printf("Available commands:\n");
+ printf(" get-status\n");
+ printf(" set-image-status [0/1] [");
+
+ while (s->name) {
+ printf("%s", s->name);
+ s++;
+
+ if (s->name)
+ printf(",");
+ }
+
+ printf("]\n");
+ printf(" set-active-image [0/1]\n");
+}
+
+int main(int argc, char *argv[])
+{
+ enum zyxel_bootconfig_image_status image_status;
+ struct zyxel_bootconfig_mtd mtd;
+ struct zyxel_bootconfig config;
+ const char *mtd_name, *command;
+ bool writeback = false;
+ int image_idx;
+
+ if (argc < 3) {
+ zyxel_bootconfig_print_usage(argv[0]);
+ return 1;
+ }
+
+ mtd_name = argv[1];
+ command = argv[2];
+
+ if (zyxel_bootconfig_mtd_open(&mtd, mtd_name)) {
+ fprintf(stderr, "Error opening %s!\n", mtd_name);
+ return 1;
+ }
+
+ if (zyxel_bootconfig_read(&config, &mtd)) {
+ fprintf(stderr, "Error reading bootconfig!\n");
+ zyxel_bootconfig_mtd_close(&mtd);
+ return 1;
+ }
+
+ if (!strcmp(command, "set-image-status")) {
+ if (argc < 5) {
+ zyxel_bootconfig_print_usage(argv[0]);
+ zyxel_bootconfig_mtd_close(&mtd);
+ return 1;
+ }
+
+ image_idx = atoi(argv[3]);
+ if (image_idx > 1 || image_idx < 0) {
+ fprintf(stderr, "Invalid image-slot set!\n");
+ zyxel_bootconfig_mtd_close(&mtd);
+ return 1;
+ }
+
+ image_status = zyxel_bootconfig_image_status_parse(argv[4]);
+ if (image_status == __IMAGE_STATUS_EINVAL) {
+ fprintf(stderr, "Invalid image-status!\n");
+ zyxel_bootconfig_mtd_close(&mtd);
+ return 1;
+ }
+
+ if (image_idx == 0) {
+ config.image0_status = image_status;
+ } else {
+ config.image1_status = image_status;
+ }
+
+ writeback = true;
+ } else if (!strcmp(command, "set-active-image")) {
+ if (argc < 4) {
+ zyxel_bootconfig_print_usage(argv[0]);
+ zyxel_bootconfig_mtd_close(&mtd);
+ return 1;
+ }
+
+ image_idx = atoi(argv[3]);
+ if (image_idx > 1 || image_idx < 0) {
+ fprintf(stderr, "Invalid image-slot set!\n");
+ zyxel_bootconfig_mtd_close(&mtd);
+ return 1;
+ }
+
+ config.active_image = image_idx;
+
+ writeback = true;
+ } else if (!strcmp(command, "get-status")) {
+ printf("Active Image: %d\n", config.active_image);
+ printf("Image 0 Status: %s\n", zyxel_bootconfig_image_status_name(config.image0_status));
+ printf("Image 1 Status: %s\n", zyxel_bootconfig_image_status_name(config.image1_status));
+
+ writeback = false;
+ }
+
+ if (writeback) {
+ if (zyxel_bootconfig_write(&config, &mtd)) {
+ fprintf(stderr, "Error writing bootconfig!\n");
+ zyxel_bootconfig_mtd_close(&mtd);
+ return 1;
+ }
+
+ zyxel_bootconfig_mtd_close(&mtd);
+ }
+
+ return 0;
+}
diff --git a/scripts/mkits-zyxel-fit.sh b/scripts/mkits-zyxel-fit.sh
new file mode 100755
index 0000000000..8ace1941eb
--- /dev/null
+++ b/scripts/mkits-zyxel-fit.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+#
+# Licensed under the terms of the GNU GPL License version 2 or later.
+# Author: David Bauer <mail@david-bauer.net>, based on mkits-zyxel-factory.sh.
+
+usage() {
+ echo "Usage: `basename $0` output file compat-models"
+ exit 1
+}
+
+# We need at least 3 arguments
+[ "$#" -lt 3 ] && usage
+
+# Target output file
+OUTPUT="$1"; shift
+FILE="$1"; shift
+MODELS="$1"; shift
+
+# Create a default, fully populated DTS file
+echo "\
+/dts-v1/;
+
+/ {
+ description = \"Zyxel FIT (Flattened Image Tree)\";
+ compat-models = [${MODELS}];
+ #address-cells = <1>;
+
+ images {
+ firmware {
+ data = /incbin/(\"${FILE}\");
+ type = \"firmware\";
+ compression = \"none\";
+ hash@1 {
+ algo = \"sha1\";
+ };
+ };
+ };
+};" > ${OUTPUT}
diff --git a/target/linux/ramips/dts/mt7621_zyxel_nwa-ax.dtsi b/target/linux/ramips/dts/mt7621_zyxel_nwa-ax.dtsi
new file mode 100644
index 0000000000..e1353346a8
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zyxel_nwa-ax.dtsi
@@ -0,0 +1,151 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ aliases {
+ label-mac-device = &gmac0;
+ };
+};
+
+&nand {
+ status = "okay";
+
+ mediatek,nmbm;
+ mediatek,bmt-max-ratio = <15>;
+ mediatek,bmt-max-reserved-blocks = <64>;
+ mediatek,bmt-remap-range =
+ <0x0 0x980000>,
+ <0x2980000 0x7800000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "u-boot-env";
+ reg = <0x80000 0x80000>;
+ read-only;
+ };
+
+ factory: partition@100000 {
+ label = "factory";
+ reg = <0x100000 0x80000>;
+ read-only;
+ };
+
+ partition@180000 {
+ label = "firmware";
+ reg = <0x180000 0x2800000>;
+
+ /* This concatenates kernel1 & kernel2 & rootfs */
+
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "kernel";
+ reg = <0x0 0x800000>;
+ };
+
+ partition@400000 {
+ label = "ubi";
+ reg = <0x800000 0x2000000>;
+ };
+ };
+
+ partition@2980000 {
+ label = "zy_firmware_1";
+ reg = <0x2980000 0x2800000>;
+ read-only;
+ };
+
+ partition@5180000 {
+ label = "zy_rootfs_data";
+ reg = <0x5180000 0x1400000>;
+ read-only;
+ };
+
+ partition@6580000 {
+ label = "zy_logs";
+ reg = <0x6580000 0xd00000>;
+ read-only;
+ };
+
+ partition@7280000 {
+ label = "myzyxel";
+ reg = <0x7280000 0x480000>;
+ read-only;
+ };
+
+ partition@7700000 {
+ label = "bootconfig";
+ reg = <0x7700000 0x80000>;
+ };
+
+ mrd: partition@7780000 {
+ label = "mrd";
+ reg = <0x7780000 0x80000>;
+ read-only;
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wlan_5g: wifi@0,0 {
+ reg = <0x0 0 0 0 0>;
+ compatible = "mediatek,mt76";
+
+ mediatek,mtd-eeprom = <&factory 0x0>;
+
+ /* MAC-Address set in userspace */
+ };
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_mrd_1fff8>;
+ nvmem-cell-names = "mac-address";
+};
+
+&switch0 {
+ ports {
+ port@4 {
+ status = "okay";
+ label = "lan";
+ };
+ };
+};
+
+&mrd {
+ compatible = "nvmem-cells";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_mrd_1fff8: macaddr@1fff8 {
+ reg = <0x1fff8 0x6>;
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "uart3", "rgmii2";
+ function = "gpio";
+ };
+};
+
+&ethernet {
+ pinctrl-0 = <&mdio_pins>, <&rgmii1_pins>;
+};
diff --git a/target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts b/target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts
new file mode 100644
index 0000000000..70323f2422
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts
@@ -0,0 +1,45 @@
+#include "mt7621_zyxel_nwa-ax.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ compatible = "zyxel,nwa50ax", "mediatek,mt7621-soc";
+ model = "ZyXEL NWA50AX";
+
+ aliases {
+ led-boot = &led_system_green;
+ led-failsafe = &led_system_red;
+ led-running = &led_system_green;
+ led-upgrade = &led_system_red;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_system_red: system_red {
+ label = "red:system";
+ gpios = <&gpio 6 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_system_green: system_green {
+ label = "green:system";
+ gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ system_blue {
+ label = "blue:system";
+ gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 30 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+};
diff --git a/target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts b/target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts
new file mode 100644
index 0000000000..04bbe340f2
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts
@@ -0,0 +1,6 @@
+#include "mt7621_zyxel_nwa-ax.dtsi"
+
+/ {
+ compatible = "zyxel,nwa55axe", "mediatek,mt7621-soc";
+ model = "ZyXEL NWA55AX";
+};
diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk
index c07ab39afd..a3bdacb32a 100644
--- a/target/linux/ramips/image/mt7621.mk
+++ b/target/linux/ramips/image/mt7621.mk
@@ -90,6 +90,13 @@ define Build/zytrx-header
mv $@.new $@
endef
+define Build/zyxel-nwa-fit
+ $(TOPDIR)/scripts/mkits-zyxel-fit.sh \
+ $@.its $@ "6b e1 6f e1 ff ff ff ff ff ff"
+ PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new
+ @mv $@.new $@
+endef
+
define Device/dsa-migration
DEVICE_COMPAT_VERSION := 1.1
DEVICE_COMPAT_MESSAGE := Config cannot be migrated from swconfig to DSA
@@ -2193,6 +2200,33 @@ define Device/zyxel_nr7101
endef
TARGET_DEVICES += zyxel_nr7101
+define Device/zyxel_nwa-ax
+ $(Device/dsa-migration)
+ DEVICE_VENDOR := ZyXEL
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ KERNEL_SIZE := 8192k
+ UBINIZE_OPTS := -E 5
+ DEVICE_PACKAGES := kmod-mt7915e uboot-envtools zyxel-bootconfig
+ KERNEL := kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
+ IMAGES += factory.bin ramboot-factory.bin
+ IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | zyxel-nwa-fit
+ IMAGE/ramboot-factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi
+ IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+endef
+
+define Device/zyxel_nwa50ax
+ $(Device/zyxel_nwa-ax)
+ DEVICE_MODEL := NWA50AX
+endef
+TARGET_DEVICES += zyxel_nwa50ax
+
+define Device/zyxel_nwa55axe
+ $(Device/zyxel_nwa-ax)
+ DEVICE_MODEL := NWA55AXE
+endef
+TARGET_DEVICES += zyxel_nwa55axe
+
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 4b273e5a15..c285227080 100644
--- a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
@@ -21,7 +21,9 @@ ramips_setup_interfaces()
tplink,re650-v2|\
ubnt,unifi-6-lite|\
ubnt,unifi-flexhd|\
- ubnt,unifi-nanohd)
+ ubnt,unifi-nanohd|\
+ zyxel,nwa50ax|\
+ zyxel,nwa55axe)
ucidef_set_interface_lan "lan"
;;
ampedwireless,ally-r1900k|\
diff --git a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
index 0e08fb6df3..b92a4dcda6 100644
--- a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
+++ b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
@@ -106,4 +106,10 @@ case "$board" in
[ "$PHYNBR" = "1" ] && \
macaddr_setbit_la "$(mtd_get_mac_binary Factory 0xe000)" > /sys${DEVPATH}/macaddress
;;
+ zyxel,nwa50ax|\
+ zyxel,nwa55axe)
+ hw_mac_addr="$(mtd_get_mac_binary mrd 0x1fff8)"
+ [ "$PHYNBR" = "0" ] && macaddr_add $hw_mac_addr 1 > /sys${DEVPATH}/macaddress
+ [ "$PHYNBR" = "1" ] && macaddr_add $hw_mac_addr 2 > /sys${DEVPATH}/macaddress
+ ;;
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 cf3caff702..6cfc852c11 100755
--- a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
@@ -95,7 +95,9 @@ platform_do_upgrade() {
xiaomi,mi-router-cr6606|\
xiaomi,mi-router-cr6608|\
xiaomi,mi-router-cr6609|\
- xiaomi,redmi-router-ac2100)
+ xiaomi,redmi-router-ac2100|\
+ zyxel,nwa50ax|\
+ zyxel,nwa55axe)
nand_do_upgrade "$1"
;;
iodata,wn-ax1167gr2|\