--- /dev/null
+#!/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
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ */
+
+/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@1 {
+ port_id = <1>;
+ phy_address = <1>;
+ };
+
+ port@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@1 {
+ compatible = "ethernet-phy-id004d.074";
+ reg = <1>;
+ };
+
+ qca8081: ethernet-phy@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@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@0 {
+ label = "0:sbl1";
+ reg = <0x0 0x50000>;
+ read-only;
+ };
+
+ partition@50000 {
+ label = "0:mibib";
+ reg = <0x50000 0x10000>;
+ read-only;
+ };
+
+ partition@60000 {
+ label = "0:bootconfig";
+ reg = <0x60000 0x20000>;
+ };
+
+ partition@80000 {
+ label = "0:bootconfig1";
+ reg = <0x80000 0x20000>;
+ };
+
+ partition@a0000 {
+ label = "0:qsee";
+ reg = <0xa0000 0x180000>;
+ read-only;
+ };
+
+ partition@220000 {
+ label = "0:qsee_1";
+ reg = <0x220000 0x180000>;
+ read-only;
+ };
+
+ partition@3a0000 {
+ label = "0:devcfg";
+ reg = <0x3a0000 0x10000>;
+ read-only;
+ };
+
+ partition@3b0000 {
+ label = "0:devcfg_1";
+ reg = <0x3b0000 0x10000>;
+ read-only;
+ };
+
+ partition@3c0000 {
+ label = "0:apdp";
+ reg = <0x3c0000 0x10000>;
+ read-only;
+ };
+
+ partition@3d0000 {
+ label = "0:apdp_1";
+ reg = <0x3d0000 0x10000>;
+ read-only;
+ };
+
+ partition@3e0000 {
+ label = "0:rpm";
+ reg = <0x3e0000 0x40000>;
+ read-only;
+ };
+
+ partition@420000 {
+ label = "0:rpm_1";
+ reg = <0x420000 0x40000>;
+ read-only;
+ };
+
+ partition@460000 {
+ label = "0:cdt";
+ reg = <0x460000 0x10000>;
+ read-only;
+ };
+
+ partition@470000 {
+ label = "0:cdt_1";
+ reg = <0x470000 0x10000>;
+ read-only;
+ };
+
+ partition@480000 {
+ label = "0:appsblenv";
+ reg = <0x480000 0x10000>;
+ read-only;
+ };
+
+ partition@490000 {
+ label = "0:appsbl";
+ reg = <0x490000 0xa0000>;
+ read-only;
+ };
+
+ partition@530000 {
+ label = "0:appsbl_1";
+ reg = <0x530000 0xa0000>;
+ read-only;
+ };
+
+ partition@5d0000 {
+ label = "0:art";
+ reg = <0x5d0000 0x40000>;
+ read-only;
+ };
+
+ partition@610000 {
+ label = "mrd";
+ reg = <0x610000 0x10000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ label_mac: macaddr@fff8 {
+ compatible = "mac-base";
+ reg = <0xfff8 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ partition@620000 {
+ label = "mrd_1";
+ reg = <0x620000 0x10000>;
+ read-only;
+ };
+
+ partition@630000 {
+ label = "conf";
+ reg = <0x630000 0x1d0000>;
+ read-only;
+ };
+ };
+ };
+};
+
+&qpic_bam {
+ status = "okay";
+};
+
+&qpic_nand {
+ status = "okay";
+
+ nand@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@0 {
+ reg = <0x00 0x3c00000>;
+ label = "rootfs";
+ };
+
+ partition@3c00000 {
+ reg = <0x3c00000 0x800000>;
+ label = "0:wififw";
+ read-only;
+ };
+
+ partition@4400000 {
+ reg = <0x4400000 0x3c00000>;
+ label = "rootfs_1";
+ };
+
+ partition@8000000 {
+ reg = <0x8000000 0x800000>;
+ label = "0:wififw_1";
+ read-only;
+ };
+
+ partition@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@30 {
+ compatible = "ti,lp5562";
+ reg = <0x30>;
+ clock-mode = [02];
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ lp5562_red: led@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@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@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@3 {
+ chan-name = "lp5562_white";
+ led-cur = [20];
+ max-cur = [60];
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_STATUS;
+ reg = <3>;
+ };
+ };
+};