[openwrt/openwrt] qualcommax: ipq807x: add support for Zyxel NWA210AX

LEDE Commits lede-commits at lists.infradead.org
Mon Dec 1 05:30:31 PST 2025


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/401c0a03f13de816e1a5998e69bff82057b489d6

commit 401c0a03f13de816e1a5998e69bff82057b489d6
Author: Eric Schäfer <eric at es86.de>
AuthorDate: Tue Aug 12 18:47:28 2025 +0000

    qualcommax: ipq807x: add support for Zyxel NWA210AX
    
    The Zyxel NWA210AX is a wall- and ceiling-mountable access point (AP).
    
    Hardware specifications:
    - SoC: Qualcomm IPQ8071A
    - RAM: 1 GB (Samsung K4A8G165WC-BCTD)
    - Flash: 8 MB (Winbond W25Q64DW), 256 MB (Winbond W29N02GZ)
    - Ethernet: 1x 2.5 Gbps RJ45 port (QCA8081), 1x 1 Gbps RJ45 port (AR8033)
    - WiFi: 2.4 GHz 802.11ax/b/g/n (QCN5024), 5 GHz 802.11 ac/ax/n (QCN5054)
    - Power: DC 12V/PoE 802.3at
    - Button: Reset
    - LEDs: Multicolour red/green/blue/white via LP5562
    
    Installation/flashing instructions:
    1. In OEM web interface navigate to gear icon → System → SSH and enable SSH.
    2. Log in via SSH (username/password are the same as for the web interface).
    3. Run "debug dual-image show".
    4. Verify that output is "Current Image num: 1".
    5. If this is not the case (i.e. if the output is "Current Image num: 0"):
       a. Either flash a fresh version of factory firmware, or
       b. run "debug dual-image set boot-image image1" and then run "reboot".
    6. Log in via SSH again and verify that output is "Current Image num: 1".
    7. Rename "openwrt-qualcommax-ipq807x-zyxel_nwa210ax-squashfs-factory.bin" to
       "openwrt.bin" to avoid upload errors in the OEM web interface.
    8. Reopen OEM web interface, navigate to wrench icon → File Manager →
       Firmware Package and upload the bin file. Once the upgrade process is
       finished and OpenWrt has booted, the LED will light up green.
    
    Switching between OpenWrt and OEM firmware:
    - OpenWrt → Zyxel via ssh command "zyxel-bootconfig-ipq807x set image1".
    - Zyxel → OpenWrt via ssh command "debug dual-image set boot-image image0".
    
    This commit is based on the work of Pascal Beleiu  <pascal at beleiu.de>:
    93ca21f3 (qualcommax: ipq807x: add support for Zyxel NWA210AX, 2025-03-17)
    
    Signed-off-by: Eric Schäfer <eric at es86.de>
    Link: https://github.com/openwrt/openwrt/pull/19828
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../uboot-envtools/files/qualcommax_ipq807x        |   3 +-
 package/firmware/ipq-wifi/Makefile                 |   4 +-
 package/utils/zyxel-bootconfig-ipq807x/Makefile    |  44 +++
 .../files/95_apply_bootconfig                      |  12 +
 .../files/zyxel-bootconfig-ipq807x                 | 145 +++++++
 target/linux/qualcommax/config-6.12                |   2 +
 .../arch/arm64/boot/dts/qcom/ipq8071-nwa210ax.dts  | 437 +++++++++++++++++++++
 target/linux/qualcommax/image/ipq807x.mk           |  23 ++
 .../ipq807x/base-files/etc/board.d/02_network      |   7 +
 .../etc/hotplug.d/firmware/11-ath11k-caldata       |   7 +
 .../ipq807x/base-files/lib/upgrade/platform.sh     |   3 +-
 11 files changed, 684 insertions(+), 3 deletions(-)

diff --git a/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq807x b/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq807x
index 3b4ae59fc6..c022531a06 100644
--- a/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq807x
+++ b/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq807x
@@ -11,7 +11,8 @@ case "$board" in
 aliyun,ap8220|\
 compex,wpq873|\
 edgecore,eap102|\
-zyxel,nbg7815)
+zyxel,nbg7815|\
+zyxel,nwa210ax)
 	ubootenv_add_mtd "0:appsblenv" "0x0" "0x10000" "0x10000"
 	;;
 dynalink,dl-wrx36|\
diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile
index 8268970c4f..47b2f8788b 100644
--- a/package/firmware/ipq-wifi/Makefile
+++ b/package/firmware/ipq-wifi/Makefile
@@ -102,7 +102,8 @@ ALLWIFIBOARDS:= \
 	zte_mf286c \
 	zte_mf287 \
 	zte_mf287plus \
-	zyxel_nbg7815
+	zyxel_nbg7815 \
+	zyxel_nwa210ax
 
 ALLWIFIPACKAGES:=$(foreach BOARD,$(ALLWIFIBOARDS),ipq-wifi-$(BOARD))
 
@@ -281,5 +282,6 @@ $(eval $(call generate-ipq-wifi-package,zte_mf286c,ZTE MF286C))
 $(eval $(call generate-ipq-wifi-package,zte_mf287,ZTE MF287))
 $(eval $(call generate-ipq-wifi-package,zte_mf287plus,ZTE MF287Plus))
 $(eval $(call generate-ipq-wifi-package,zyxel_nbg7815,Zyxel NBG7815))
+$(eval $(call generate-ipq-wifi-package,zyxel_nwa210ax,Zyxel NWA210AX))
 
 $(foreach PACKAGE,$(ALLWIFIPACKAGES),$(eval $(call BuildPackage,$(PACKAGE))))
diff --git a/package/utils/zyxel-bootconfig-ipq807x/Makefile b/package/utils/zyxel-bootconfig-ipq807x/Makefile
new file mode 100644
index 0000000000..b624a13b09
--- /dev/null
+++ b/package/utils/zyxel-bootconfig-ipq807x/Makefile
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2025 Pascal Beleiu <pascal at beleiu.de>
+# Copyright (c) 2025 Eric Schäfer <eric at es86.de>
+#
+# 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-ipq807x
+PKG_RELEASE:=1
+PKG_FLAGS:=nonshared
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/zyxel-bootconfig-ipq807x
+	SECTION:=utils
+	CATEGORY:=Base system
+	TITLE:=Utility for handling Zyxel bootconfig settings on ipq807x devices
+	MAINTAINER:=Pascal Beleiu <pascal at beleiu.de>
+	DEPENDS:=@TARGET_qualcommax_ipq807x
+endef
+
+define Package/zyxel-bootconfig-ipq807x/description
+	This package contains an utility for handling Zyxel bootconfig settings on ipq807x devices.
+endef
+
+define Build/Prepare
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/zyxel-bootconfig-ipq807x/install
+	$(INSTALL_DIR) $(1)/usr/bin $(1)/lib/preinit
+	$(INSTALL_BIN) ./files/zyxel-bootconfig-ipq807x $(1)/usr/bin/
+	$(CP) ./files/95_apply_bootconfig $(1)/lib/preinit/95_apply_bootconfig
+endef
+
+$(eval $(call BuildPackage,zyxel-bootconfig-ipq807x))
diff --git a/package/utils/zyxel-bootconfig-ipq807x/files/95_apply_bootconfig b/package/utils/zyxel-bootconfig-ipq807x/files/95_apply_bootconfig
new file mode 100644
index 0000000000..03c833b951
--- /dev/null
+++ b/package/utils/zyxel-bootconfig-ipq807x/files/95_apply_bootconfig
@@ -0,0 +1,12 @@
+apply_bootconfig() {
+	. /lib/functions.sh
+
+	case $(board_name) in
+	zyxel,nwa210ax)
+		status="$(zyxel-bootconfig-ipq807x show | awk '/image0:/ {print $2}')"
+		[ "$status" != "selected" ] && zyxel-bootconfig-ipq807x --force set image0
+		;;
+	esac
+}
+
+[ "$INITRAMFS" = "1" ] || boot_hook_add preinit_main apply_bootconfig
diff --git a/package/utils/zyxel-bootconfig-ipq807x/files/zyxel-bootconfig-ipq807x b/package/utils/zyxel-bootconfig-ipq807x/files/zyxel-bootconfig-ipq807x
new file mode 100755
index 0000000000..2e23a1a312
--- /dev/null
+++ b/package/utils/zyxel-bootconfig-ipq807x/files/zyxel-bootconfig-ipq807x
@@ -0,0 +1,145 @@
+#!/bin/sh
+
+. /lib/functions.sh
+
+BOOTCONFIG_MTD="$(find_mtd_part 0:bootconfig || true)"
+BOOTCONFIG1_MTD="$(find_mtd_part 0:bootconfig1 || true)"
+OFFSET=4
+
+FORCE=0
+
+usage() {
+	cat <<-EOF
+	Usage: $0 [--force] {show | set image0 | set image1}
+
+	Options:
+	  --force   Skip all confirmation prompts (non-interactive mode)
+
+	Commands:
+	  show           Display current and next boot image status
+	  set image0     Set image0 as active for next boot
+	  set image1     Set image1 as active for next boot
+	EOF
+	exit 1
+}
+
+if [ "${1:-}" = "--force" ]; then
+	FORCE=1
+	shift
+fi
+
+require_mtd() {
+	if [ -z "$BOOTCONFIG_MTD" ] || [ -z "$BOOTCONFIG1_MTD" ]; then
+		printf "ERROR: bootconfig MTD partitions not found.\n" >&2
+		exit 1
+	fi
+}
+
+read_status() {
+	local dev="$1"
+	hexdump -v -e '1/1 "%01x"' -n 1 -s "$OFFSET" "$dev" 2>/dev/null
+}
+
+write_status() {
+	local dev="$1" val="$2"
+	printf "\\x$val" | dd of="$dev" bs=1 seek=$OFFSET count=1 conv=notrunc 2>/dev/null
+}
+
+status_string() {
+	case "$1" in
+		0) printf "none" ;;
+		1) printf "backup" ;;
+		2) printf "selected" ;;
+		*) printf "unknown" ;;
+	esac
+}
+
+show_status() {
+	printf "Currently booted:\n  image%s\n" \
+		"$(awk -F 'bootImage=' '{print $2}' /proc/cmdline | awk '{print $1}')"
+
+	STATUS0="$(read_status "$BOOTCONFIG_MTD")"
+	STATUS1="$(read_status "$BOOTCONFIG1_MTD")"
+
+	printf "At next reboot:\n"
+	printf "  image0: %s\n" "$(status_string "$STATUS0")"
+	printf "  image1: %s\n" "$(status_string "$STATUS1")"
+}
+
+check_selected() {
+	local old="$1"
+	local img="$2"
+
+	if [ "$old" = "0" ]; then
+		printf "\nWARNING: image%s is currently 'none'. Booting might fail.\n" "$img" >&2
+		if [ "$FORCE" -ne 1 ]; then
+			read -rp "Proceed anyway? (yes/no) " confirm >&2
+			[ "$confirm" != "yes" ] && return 1
+		fi
+	fi
+	printf "02"
+}
+
+check_backup() {
+	local old="$1"
+	local img="$2"
+
+	if [ "$old" = "0" ]; then
+		printf "\nINFO: Kept image%s as 'none'.\n" "$img" >&2
+		printf "00"
+	else
+		printf "01"
+	fi
+}
+
+set_image() {
+	local img="$1"
+	local new0 new1
+
+	printf "OLD CONFIGURATION\n"
+	show_status
+
+	if [ "$STATUS0" = "1" ] && [ "$STATUS1" = "1" ] && [ "$FORCE" -ne 1 ]; then
+		printf "WARNING: Both images are marked as selected!\n" >&2
+		read -rp "Proceed anyway? (yes/no) " confirm >&2
+		[ "$confirm" != "yes" ] && exit 1
+	fi
+
+	case "$img" in
+		0)
+			new0="$(check_selected "$STATUS0" "0")" || exit 1
+			new1="$(check_backup "$STATUS1" "1")"
+			;;
+		1)
+			new0="$(check_backup "$STATUS0" "0")"
+			new1="$(check_selected "$STATUS1" "1")" || exit 1
+			;;
+		*)
+			printf "ERROR: Invalid image selection.\n" >&2
+			exit 1
+			;;
+	esac
+	
+	printf "\nUpdating image selection...\n"
+	write_status "$BOOTCONFIG_MTD" "$new0"
+	write_status "$BOOTCONFIG1_MTD" "$new1"
+	printf "Done.\n"
+
+	printf "\nNEW CONFIGURATION\n"
+	show_status
+}
+
+require_mtd
+
+case "${1:-}" in
+	show)
+		show_status
+		;;
+	set)
+		[ -z "${2:-}" ] && usage
+		set_image "${2#image}"
+		;;
+	*)
+		usage
+		;;
+esac
diff --git a/target/linux/qualcommax/config-6.12 b/target/linux/qualcommax/config-6.12
index cc9079707b..d0dd32a0aa 100644
--- a/target/linux/qualcommax/config-6.12
+++ b/target/linux/qualcommax/config-6.12
@@ -191,6 +191,8 @@ CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GLOB=y
 CONFIG_GPIOLIB_IRQCHIP=y
 CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_WATCHDOG=y
+# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_HAS_DMA=y
 CONFIG_HAS_IOMEM=y
diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-nwa210ax.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-nwa210ax.dts
new file mode 100644
index 0000000000..fb440d1e96
--- /dev/null
+++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-nwa210ax.dts
@@ -0,0 +1,437 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2025 Pascal Beleiu <pascal at beleiu.de>
+ * Copyright (c) 2025 Eric Schäfer <eric at es86.de>
+ */
+
+/dts-v1/;
+
+#include "ipq8074.dtsi"
+#include "ipq8074-ac-cpu.dtsi"
+#include "ipq8074-ess.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	model = "Zyxel NWA210AX";
+	compatible = "zyxel,nwa210ax", "qcom,ipq8074";
+
+	aliases {
+		led-boot = &lp5562_blue;
+		led-failsafe = &lp5562_white;
+		led-running = &lp5562_green;
+		led-upgrade = &lp5562_red;
+		serial0 = &blsp1_uart5;
+		ethernet0 = &dp5;
+		ethernet1 = &dp1;
+		label-mac-device = &dp5;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+		bootargs-append = " root=/dev/ubiblock0_1";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&tlmm 31 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		gpio_green {
+			gpios = <&tlmm 50 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_STATUS;
+		};
+
+		gpio_red {
+			gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			color = <LED_COLOR_ID_RED>;
+			function = LED_FUNCTION_STATUS;
+		};
+	};
+
+	watchdog {
+		compatible = "linux,wdt-gpio";
+		gpios = <&tlmm 43 GPIO_ACTIVE_HIGH>;
+		hw_algo = "toggle";
+		hw_margin_ms = <10000>;
+		always-running;
+	};
+};
+
+&blsp1_uart5 {
+	status = "okay";
+};
+
+&crypto {
+	status = "okay";
+};
+
+&edma {
+	status = "okay";
+};
+
+&tlmm {
+	mdio_pins: mdio-pins {
+		mdc {
+			pins = "gpio68";
+			function = "mdc";
+			drive-strength = <8>;
+			bias-pull-up;
+		};
+
+		mdio {
+			pins = "gpio69";
+			function = "mdio";
+			drive-strength = <8>;
+			bias-pull-up;
+		};
+	};
+
+	mdio_gpio_pins: mdio-gpio-pins {
+		pins = "gpio37", "gpio44";
+		function = "gpio";
+		bias-pull-up;
+	};
+
+	button_pins: button-pins {
+		pins = "gpio30";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-pull-up;
+	};
+
+	i2c_6_pins: i2c-6-state {
+		pins = "gpio0", "gpio2";
+		drive-strength = <8>;
+		function = "blsp5_i2c";
+		bias-disable;
+	};
+};
+
+&switch {
+	status = "okay";
+
+	switch_lan_bmp = <(ESS_PORT1 | ESS_PORT5)>;
+	switch_mac_mode = <MAC_MODE_SGMII_CHANNEL0>;
+	switch_mac_mode1 = <MAC_MODE_SGMII_PLUS>;
+
+	qcom,port_phyinfo {
+		port at 1 {
+			port_id = <1>;
+			phy_address = <1>;
+		};
+
+		port at 5 {
+			port_id = <5>;
+			phy_address = <16>;
+			port_mac_sel = "QGMAC_PORT";
+		};
+	};
+};
+
+&mdio {
+	status = "okay";
+	pinctrl-0 = <&mdio_pins>;
+	pinctrl-names = "default";
+	reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
+
+	ar8033: ethernet-phy at 1 {
+		compatible = "ethernet-phy-id004d.074";
+		reg = <1>;
+	};
+
+	qca8081: ethernet-phy at 16 {
+		compatible = "ethernet-phy-id004d.d101";
+		reg = <16>;
+		reset-deassert-us = <10000>;
+		reset-gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&dp1 {
+	status = "okay";
+	phy-handle = <&ar8033>;
+	phy-mode = "sgmii";
+	label = "lan1";
+	nvmem-cell-names = "mac-address";
+	nvmem-cells = <&label_mac 1>;
+};
+
+&dp5 {
+	status = "okay";
+	phy-handle = <&qca8081>;
+	phy-mode = "sgmii";
+	label = "uplink";
+	nvmem-cell-names = "mac-address";
+	nvmem-cells = <&label_mac 0>;
+};
+
+&blsp1_spi1 {
+	pinctrl-0 = <&spi_0_pins>;
+	pinctrl-names = "default";
+	cs-select = <0>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0>;
+		linux,modalias = "m25p80", "n25q128a11";
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "0:sbl1";
+				reg = <0x0 0x50000>;
+				read-only;
+			};
+
+			partition at 50000 {
+				label = "0:mibib";
+				reg = <0x50000 0x10000>;
+				read-only;
+			};
+
+			partition at 60000 {
+				label = "0:bootconfig";
+				reg = <0x60000 0x20000>;
+			};
+
+			partition at 80000 {
+				label = "0:bootconfig1";
+				reg = <0x80000 0x20000>;
+			};
+
+			partition at a0000 {
+				label = "0:qsee";
+				reg = <0xa0000 0x180000>;
+				read-only;
+			};
+
+			partition at 220000 {
+				label = "0:qsee_1";
+				reg = <0x220000 0x180000>;
+				read-only;
+			};
+
+			partition at 3a0000 {
+				label = "0:devcfg";
+				reg = <0x3a0000 0x10000>;
+				read-only;
+			};
+
+			partition at 3b0000 {
+				label = "0:devcfg_1";
+				reg = <0x3b0000 0x10000>;
+				read-only;
+			};
+
+			partition at 3c0000 {
+				label = "0:apdp";
+				reg = <0x3c0000 0x10000>;
+				read-only;
+			};
+
+			partition at 3d0000 {
+				label = "0:apdp_1";
+				reg = <0x3d0000 0x10000>;
+				read-only;
+			};
+
+			partition at 3e0000 {
+				label = "0:rpm";
+				reg = <0x3e0000 0x40000>;
+				read-only;
+			};
+
+			partition at 420000 {
+				label = "0:rpm_1";
+				reg = <0x420000 0x40000>;
+				read-only;
+			};
+
+			partition at 460000 {
+				label = "0:cdt";
+				reg = <0x460000 0x10000>;
+				read-only;
+			};
+
+			partition at 470000 {
+				label = "0:cdt_1";
+				reg = <0x470000 0x10000>;
+				read-only;
+			};
+
+			partition at 480000 {
+				label = "0:appsblenv";
+				reg = <0x480000 0x10000>;
+				read-only;
+			};
+
+			partition at 490000 {
+				label = "0:appsbl";
+				reg = <0x490000 0xa0000>;
+				read-only;
+			};
+
+			partition at 530000 {
+				label = "0:appsbl_1";
+				reg = <0x530000 0xa0000>;
+				read-only;
+			};
+
+			partition at 5d0000 {
+				label = "0:art";
+				reg = <0x5d0000 0x40000>;
+				read-only;
+			};
+
+			partition at 610000 {
+				label = "mrd";
+				reg = <0x610000 0x10000>;
+				read-only;
+
+				nvmem-layout {
+					compatible = "fixed-layout";
+					#address-cells = <1>;
+					#size-cells = <1>;
+
+					label_mac: macaddr at fff8 {
+						compatible = "mac-base";
+						reg = <0xfff8 0x6>;
+						#nvmem-cell-cells = <1>;
+					};
+				};
+			};
+
+			partition at 620000 {
+				label = "mrd_1";
+				reg = <0x620000 0x10000>;
+				read-only;
+			};
+
+			partition at 630000 {
+				label = "conf";
+				reg = <0x630000 0x1d0000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&qpic_bam {
+	status = "okay";
+};
+
+&qpic_nand {
+	status = "okay";
+
+	nand at 0 {
+		reg = <0>;
+		nand-ecc-step-size = <512>;
+		nand-bus-width = <8>;
+		nand-ecc-strength = <4>;
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition at 0 {
+			reg = <0x00 0x3c00000>;
+			label = "rootfs";
+		};
+
+		partition at 3c00000 {
+			reg = <0x3c00000 0x800000>;
+			label = "0:wififw";
+			read-only;
+		};
+
+		partition at 4400000 {
+			reg = <0x4400000 0x3c00000>;
+			label = "rootfs_1";
+		};
+
+		partition at 8000000 {
+			reg = <0x8000000 0x800000>;
+			label = "0:wififw_1";
+			read-only;
+		};
+
+		partition at 8800000 {
+			reg = <0x8800000 0x7800000>;
+			label = "logs";
+		};
+	};
+};
+
+&wifi {
+	status = "okay";
+	qcom,ath11k-calibration-variant = "Zyxel-NWA210AX";
+};
+
+&blsp1_i2c6 {
+	pinctrl-0 = <&i2c_6_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	lp5562 at 30 {
+		compatible = "ti,lp5562";
+		reg = <0x30>;
+		clock-mode = [02];
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		lp5562_red: led at 0 {
+			chan-name = "lp5562_red";
+			led-cur = [20];
+			max-cur = [60];
+			color = <LED_COLOR_ID_RED>;
+			function = LED_FUNCTION_STATUS;
+			reg = <0>;
+		};
+
+		lp5562_green: led at 1 {
+			chan-name = "lp5562_green";
+			led-cur = [20];
+			max-cur = [60];
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_STATUS;
+			reg = <1>;
+		};
+
+		lp5562_blue: led at 2 {
+			chan-name = "lp5562_blue";
+			led-cur = [20];
+			max-cur = [60];
+			color = <LED_COLOR_ID_BLUE>;
+			function = LED_FUNCTION_STATUS;
+			reg = <2>;
+		};
+
+		lp5562_white: led at 3 {
+			chan-name = "lp5562_white";
+			led-cur = [20];
+			max-cur = [60];
+			color = <LED_COLOR_ID_WHITE>;
+			function = LED_FUNCTION_STATUS;
+			reg = <3>;
+		};
+	};
+};
diff --git a/target/linux/qualcommax/image/ipq807x.mk b/target/linux/qualcommax/image/ipq807x.mk
index 1a356b0261..f356bbbca5 100644
--- a/target/linux/qualcommax/image/ipq807x.mk
+++ b/target/linux/qualcommax/image/ipq807x.mk
@@ -33,6 +33,13 @@ define Build/wax6xx-netgear-tar
 	rm -rf $@.tmp
 endef
 
+define Build/zyxel-nwa210ax-fit
+	$(TOPDIR)/scripts/mkits-zyxel-fit-filogic.sh \
+		$@.its $@ "5c e1 ff ff ff ff ff ff ff ff"
+	PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new
+	@mv $@.new $@
+endef
+
 define Device/aliyun_ap8220
 	$(call Device/FitImage)
 	$(call Device/UbiFit)
@@ -541,3 +548,19 @@ define Device/zyxel_nbg7815
 		kmod-hci-uart kmod-hwmon-tmp103
 endef
 TARGET_DEVICES += zyxel_nbg7815
+
+define Device/zyxel_nwa210ax
+	$(call Device/FitImage)
+	$(call Device/UbiFit)
+	DEVICE_VENDOR := ZYXEL
+	DEVICE_MODEL := NWA210AX
+	DEVICE_DTS_CONFIG := config at ac02
+	SOC := ipq8071
+	DEVICE_PACKAGES := ipq-wifi-zyxel_nwa210ax zyxel-bootconfig-ipq807x kmod-leds-lp5562
+	BLOCKSIZE := 128k
+	PAGESIZE := 2048
+	IMAGE_SIZE := 61440k
+	IMAGES += factory.bin
+	IMAGE/factory.bin := append-ubi | check-size $$$$(IMAGE_SIZE) | zyxel-nwa210ax-fit
+endef
+TARGET_DEVICES += zyxel_nwa210ax
diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network
index 70f8a3134b..3c0e123141 100644
--- a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network
+++ b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network
@@ -71,6 +71,9 @@ ipq807x_setup_interfaces()
 	zyxel,nbg7815)
 		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 10g" "wan"
 		;;
+	zyxel,nwa210ax)
+		ucidef_set_interface_lan "uplink lan1" "dhcp"
+		;;
 	*)
 		echo "Unsupported hardware. Network interfaces not initialized"
 		;;
@@ -100,6 +103,10 @@ ipq807x_setup_macs()
 		label_mac=$(get_mac_binary /tmp/factory_data/default-mac 0)
 		lan_mac=$label_mac
 		;;
+	zyxel,nwa210ax)
+		label_mac=$(get_mac_label_dt)
+		lan_mac=$label_mac
+		;;
 	esac
 
 	[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata b/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
index 6a9d5afb98..df4907c517 100644
--- a/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
+++ b/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
@@ -126,6 +126,13 @@ case "$FIRMWARE" in
 		ath11k_patch_mac $(macaddr_add $label_mac 4) 2
 		ath11k_set_macflag
 		;;
+	zyxel,nwa210ax)
+		caldata_extract "0:art" 0x1000 0x20000
+		label_mac=$(get_mac_label)
+		ath11k_patch_mac $(macaddr_add $label_mac 3) 0
+		ath11k_patch_mac $(macaddr_add $label_mac 2) 1
+		ath11k_set_macflag
+		;;
 	esac
 	;;
 "ath11k/QCN9074/hw1.0/cal-pci-0000:01:00.0.bin"|\
diff --git a/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh b/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh
index 0a38cfa8d8..1ddc73f09e 100644
--- a/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh
+++ b/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh
@@ -184,7 +184,8 @@ platform_do_upgrade() {
 	netgear,sxs80|\
 	netgear,wax218|\
 	netgear,wax620|\
-	netgear,wax630)
+	netgear,wax630|\
+	zyxel,nwa210ax)
 		nand_do_upgrade "$1"
 		;;
 	asus,rt-ax89x)




More information about the lede-commits mailing list