From d2a75029a5f8e54e1fd2f252f73b9a430a030116 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Wed, 5 Nov 2025 23:41:57 +0100 Subject: [PATCH] ipq806x: add support for Aruba AP-32x This is a dual-radio 802.11a/b/g/n/ac access point with dual Gigabit Ethernet. There are two closely related models: The AP-324, which has external antenna connectors, and the AP-325, which has internal antennas. The board appears to be identical, and the same image works on both. Additionally, the Siemens Scalance W1750D is an OEM variant using the same board, so the image also works on that. Unfortunately the factory APBoot bootloader enforces cryptographic signatures on the firmware before booting, so a modified version must be flashed via the serial port. See [^1] for details. Specifications ============== * Device: Aruba AP-325 / AP-324 * SoC: Qualcomm IPQ8068 2x1.4GHz ARMv7-A * RAM: 512MiB (2x Winbond W632GU6MB-12) * SPI flash: 4MiB Macronix MX25U3235F * NAND flash: 128MiB Winbond W29N01HZBINF * WiFi: 2x Qualcomm QCA9990 (one 2.4G, one 5G) * Ethernet: 2x 1000BASE-T (Marvell 88E1514 PHY), both PoE-capable * Power: PoE 802.3at or 12V DC jack * LEDs: Red/Amber/Green status LED, Amber/Green WiFi LED * Buttons: 1x, behind hole next to DC jack * Console: RJ45 connector, Cisco pinout * USB: 1x USB 2.0 Type A, 1x internal to BLE, SoC has USB 3.0 host but board is only wired for 2.0 * BLE: TI CC2540 SoC, connected to USB and UART, unpopulated debug header on PCB * TPM: Atmel AT97SC3205T How to install ============== The stock bootloader APBoot appears to be vendor fork of U-Boot, which disables much of the usual functionality and comes with its own booting and firmware upgrade logic. Unfortunately, this logic enforces RSA signatures on images, even for the default boot from NAND. Therefore, a patched bootloader is needed, which is built as a package. In addition to the signature check removal, this also changes the serial baudrate to 115200. Luckily, the stock firmware does not disable the `sf` command (it just hides it until you run `diag`), so the patched bootloader can be fetched via TFTP and then flashed via console. Flashing patched APBoot ----------------------- * Build OpenWrt, or download `openwrt-ipq806x-generic-aruba_ap-32x-apboot.mbn` * Connect serial cable and wired ethernet * Access stock APBoot console at Baud 9600 * Flash patched bootloader: ``` setenv serverip setenv autostart n netget 44000000 openwrt-ipq806x-generic-aruba_ap-32x-apboot.mbn sf probe 0 sf erase 220000 100000 sf write 44000000 220000 100000 reset ``` Booting OpenWrt --------------- * Connect serial cable and wired ethernet * Access patched APBoot console at Baud 115200 * Run `setenv serverip ` * Run `tftpboot openwrt-ipq806x-generic-aruba_ap-32x-initramfs.ari` Installing OpenWrt ------------------ * Connect serial cable and wired ethernet * Access patched APBoot console at Baud 115200 * Consider backing up stock firmware(s) (UBI volumes `aos0` and/or `aos1`) by booting into OpenWrt via initramfs (see above) and dumping them * Wipe and repartition NAND flash (see below for explanation): ``` nand device 0 nand erase.chip reset ubi part ubifs ubi remove ubifs ubi create ubifs 1 ubi create rootfs_data ``` * Follow steps above to boot OpenWrt via initramfs * From OpenWrt, persist installation via sysupgrade Reverting to stock FW --------------------- The patched bootloader remains compatible with the original firmware, so you can just wipe the NAND, let APBoot recreate the partitions, and flash back the `aos0`/`aos1` backup from above. Current status ============== Tested and working ------------------ * Console * Wired GbE (both ports) * WiFi (both 2.4G and 5G) * LEDs * Restart Button * USB port * External watchdog * TPM * BLE SoC Future work ----------- * GPIOs for: * power source (8 indicates DC jack, 59 indicates 802.3at) * reset source (64 for warm reset, 65 for watchdog) * USB overcurrent (63) * BLE SoC reflashing * CC2540 comes with Aruba-specific FW out of the box * Debug header is exposed on PCB (pinout GND-VCC-Clock-Data-Reset), but that requires disassembly * Stock BLE FW appears to support reflashing via UART, but protocol would need to be reverse-engineered * ramoops/pstore * It appears that APBoot clears the RAM on boot, might be something we can patch out as well * Porting a modern U-Boot Flash layout ============ SPI flash --------- ``` 0x000000-0x020000 sbl1 0x020000-0x040000 mibib 0x040000-0x080000 sbl2 0x080000-0x100000 sbl3 0x100000-0x110000 ddrconfig 0x110000-0x120000 ssd 0x120000-0x1a0000 tz 0x1a0000-0x220000 rpm 0x220000-0x320000 appsbl 0x320000-0x330000 appsblenv 0x330000-0x370000 art 0x370000-0x380000 panicdump 0x380000-0x390000 certificate 0x390000-0x3a0000 mfginfo 0x3a0000-0x3b0000 flashcache 0x3b0000-0x400000 aosspare ``` Factory NAND flash ------------------ * 32MiB MTD partition `aos0`, formatted as UBI * 32MiB UBI volume `aos0` * contains kernel+initrd of the primary firmware, initrd contains the entire root FS * 32MiB MTD partition `aos1`, formatted as UBI * 32MiB UBI volume `aos1` * contains kernel+initrd of the secondary firmware, initrd contains the entire root FS * 64MiB MTD partition `ubifs`, formatted as UBI * 64MiB UBI volume `ubifs` * Contains UBIFS, overlay-mounted on top of the initrd, shared between firmware slots APBoot understands UBI, and will read the kernel from the `aos0` or `aos1` volume (depending on `os_partition`) with fallback to the other one in case a check fails. Kernels are expected to have a vendor-specific header, the included script will add that header with the correct checksum but no signature. OpenWrt NAND flash ------------------ OpenWrt assumes separate UBI volumes for kernel and rootfs, as well as a volume that must be named `rootfs_data` for the UBIFS. Unfortunately, APBoot actively checks the UBI volumes at boot, and will repartition if it doesn't find the volumes that it expects (listed above). Luckily, it doesn't check their size, only their existence. Therefore, we can use the following layout: * 32MiB MTD partition `aos0`, formatted as UBI * 32MiB UBI volume `aos0` * contains OpenWrt kernel+initrd * 32MiB MTD partition `aos1`, formatted as UBI * 32MiB UBI volume `aos1` * contains OpenWrt root squashfs * 64MiB MTD partition `ubifs`, formatted as UBI * small (single-LEB) UBI volume `ubifs` * Dummy volume, only there to satisfy APBoot * almost 64MiB UBI volume `rootfs_data` * contains UBIFS, overlay-mounted on top of the rootfs [^1]: https://github.com/lukasstockner/ap325-apboot-openwrt Signed-off-by: Lukas Stockner Link: https://github.com/openwrt/openwrt/pull/20738 Signed-off-by: Paul Spooren --- .../uboot-tools/uboot-envtools/files/ipq806x | 11 +- scripts/aruba-header.py | 225 +++++++++++ .../ipq806x/base-files/etc/board.d/02_network | 9 +- .../ipq806x/base-files/etc/init.d/bootcount | 7 +- .../base-files/lib/upgrade/platform.sh | 15 + .../linux/ipq806x/dts/qcom-ipq8068-ap-32x.dts | 377 ++++++++++++++++++ target/linux/ipq806x/image/generic.mk | 31 ++ 7 files changed, 663 insertions(+), 12 deletions(-) create mode 100755 scripts/aruba-header.py create mode 100644 target/linux/ipq806x/dts/qcom-ipq8068-ap-32x.dts diff --git a/package/boot/uboot-tools/uboot-envtools/files/ipq806x b/package/boot/uboot-tools/uboot-envtools/files/ipq806x index 44dae17c1b..a018d0d7e5 100644 --- a/package/boot/uboot-tools/uboot-envtools/files/ipq806x +++ b/package/boot/uboot-tools/uboot-envtools/files/ipq806x @@ -35,6 +35,12 @@ arris,tr4400-v2|\ askey,rt4230w-rev6) ubootenv_add_uci_config "/dev/mtd9" "0x0" "0x40000" "0x20000" ;; +aruba,ap-32x|\ +ignitenet,ss-w2-ac2600|\ +qcom,ipq8064-ap148|\ +qcom,ipq8064-db149) + ubootenv_add_uci_config $(ubootenv_mtdinfo) + ;; edgecore,ecw5410) ubootenv_add_uci_config "/dev/mtd11" "0x0" "0x10000" "0x10000" ;; @@ -42,11 +48,6 @@ extreme,ap3935) ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" ubootenv_add_uci_config "/dev/mtd3" "0x0" "0x10000" "0x10000" ;; -ignitenet,ss-w2-ac2600|\ -qcom,ipq8064-ap148|\ -qcom,ipq8064-db149) - ubootenv_add_uci_config $(ubootenv_mtdinfo) - ;; linksys,ea7500-v1|\ linksys,ea8500) ubootenv_add_uci_config "/dev/mtd10" "0x0" "0x20000" "0x20000" diff --git a/scripts/aruba-header.py b/scripts/aruba-header.py new file mode 100755 index 0000000000..e7dfa62e14 --- /dev/null +++ b/scripts/aruba-header.py @@ -0,0 +1,225 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2025 Lukas Stockner +# +# ./aruba-header.py +# +# Generates a header for use with the APBoot bootloader on (some?) Aruba APs. + +import argparse + +LEN_BUILD = 256 +LEN_VERSION = 24 +LEN_OEM = 32 + +HEADER_MAGIC = b'ARUBA\0\0\0' + + +class ValidFlag: + YES = 1 + + +class FormatVersion: + CURRENT = 2 + + +class ImageType: + ELF = 0 + FPGA_BINARY = 1 + CPBOOT_BINARY = 2 + APBOOT_BINARY = 3 + TPMINFO = 4 + APBOOT_STAGE1_BINARY = 5 + APBOOT_STAGE2_BINARY = 6 + APBOOT_COMBINED_BINARY = 7 + OS_ANCILLARY_IMAGE = 8 + XLOADER_BINARY = 9 + GRUB_BIN = 10 + LSM_PACKAGE = 11 + + +class CompressionType: + NONE = 0 + BZIP2 = 1 + GZIP = 2 + + +MACHINE_TYPES = { + 'MSWITCH': 0, + 'CABERNET': 1, + 'SYRAH': 2, + 'MERLOT': 3, + 'MUSCAT': 4, + 'NEBBIOLO': 5, + 'MALBEC': 6, + 'PALOMINO': 7, + 'GRENACHE': 8, + 'MOSCATO': 9, + 'TALISKER': 10, + 'JURA_R': 11, + 'SCAPA': 12, + 'JURA_O': 13, + 'CORVINA': 14, + 'ARRAN': 15, + 'BLUEBLOOD': 16, + 'MSR2K': 17, + 'PORFIDIO': 18, + 'CAZULO': 19, + 'SCAPA_H': 20, + 'CARDHU': 21, + 'BOWMORE': 22, + 'TAMDHU': 23, + 'ARDBEG': 24, + 'ARDMORE': 25, + 'DALMORE': 26, + 'K2': 27, + 'GRAPPA': 28, + 'SHUMWAY': 29, + 'SPRINGBANK': 30, + 'OUZO': 31, + 'AMARULA': 32, + 'GROZDOVA': 33, + 'PALINKA': 34, + 'HAZELBURN': 35, + 'TOMATIN': 36, + 'HAZELBURN_H': 37, + 'TOMATIN_16': 38, + 'SPRINGBANK_16': 39, + 'OCTOMORE': 40, + 'BALVENIE': 41, + 'OUZO_PLUS': 42, + 'X4': 43, + 'EINAR': 44, + 'GLENFARCLAS': 45, + 'GLENFIDDICH': 46, + 'EIGER': 47, + 'GLENMORANGIE': 48, + 'MILAGRO': 49, + 'OPUSONE': 50, + 'ABERLOUR': 51, + 'MILLSTONE': 52, + 'DEWARS': 53, + 'BUNKER': 54, + 'MASTERSON': 55, + 'SIERRA': 56, + 'KILCHOMAN': 57, + 'SPEYBURN': 58, + 'LAGAVULIN': 59, + 'LAPHROAIG': 60, + 'TOBA': 61, + 'ARRANTA': 62, +} + + +class NextHeader: + NONE = 0x00000000 + SIGN = 0x01111111 + + +class Flags: + C_TEST_BUILD = 0x00000001 + SWATCH = 0x00000002 + # Preserves the image with "clear all" + DONT_CLEAR_ON_PURGE = 0x00000004 + SECURE_BOOTLOADER = 0x00000008 + FACTORY_IMAGE = 0x00000010 + FIPS_CERTIFIED = 0x00000020 + + +def make_header(data: bytes, build: str, version: str, oem: str, imageType: int, machine: int) -> bytes: + buildBytes = build.encode(encoding='ascii') + assert len(buildBytes) < LEN_BUILD + buildBytes += b'\0' * (LEN_BUILD - len(buildBytes)) + + versionBytes = version.encode(encoding='ascii') + assert len(versionBytes) < LEN_VERSION + versionBytes += b'\0' * (LEN_VERSION - len(versionBytes)) + + oemBytes = oem.encode(encoding='ascii') + assert len(oemBytes) < LEN_OEM + oemBytes += b'\0' * (LEN_OEM - len(oemBytes)) + + header = b'' + # Payload size, image plus optional signature (which we don't use) + header += len(data).to_bytes(4, 'big') + # Use what appears to be the current version + header += FormatVersion.CURRENT.to_bytes(4, 'big') + # Checksum is computed later + header += b'\0\0\0\0' + # Vendor magic number + header += HEADER_MAGIC + # Long build information string + header += buildBytes + # Short version information string + header += versionBytes + # Image is valid + header += ValidFlag.YES.to_bytes(1, 'big') + # Image type + header += imageType.to_bytes(1, 'big') + # APBoot doesn't appear to actually support compression + header += CompressionType.NONE.to_bytes(1, 'big') + # Machine type + header += machine.to_bytes(1, 'big') + # Image size + header += len(data).to_bytes(4, 'big') + # Next header (we don't support signing) + header += NextHeader.NONE.to_bytes(4, 'big') + # MD5 checksum plus fudge factor (to ensure non-zero hash), appears unused + header += b'\0' * 16 + header += b'\0' * 4 + # No flags are set + header += int(0).to_bytes(4, 'big') + # No next header is used + header += b'\0' * 12 + # Padding + header += b'\0' * 36 + # OEM string + header += oemBytes + # Padding + header += b'\0' * 96 + + assert len(header) == 512 + assert len(data) % 4 == 0 + + # Compute checksum such that the big-endian sum of all 32-bit integers becomes zero. + curSum = sum(int.from_bytes(header[i : i + 4], 'big') for i in range(0, 512, 4)) + curSum += sum(int.from_bytes(data[i : i + 4], 'big') for i in range(0, len(data), 4)) + + # Set checksum + checksum = 0x100000000 - (curSum % 0x100000000) + header = header[:8] + checksum.to_bytes(4, 'big') + header[12:] + + return header + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Generate Aruba header.') + parser.add_argument('source') + parser.add_argument('dest') + parser.add_argument('build') + parser.add_argument('version') + parser.add_argument('oem') + parser.add_argument('type', choices=['os', 'boot']) + parser.add_argument('machine', choices=MACHINE_TYPES.keys(), type=str.upper) + args = parser.parse_args() + + # Parse image type. + # The OS image must be type "ELF" even though it's not an ELF file... + imageType = {'os': ImageType.ELF, 'boot': ImageType.APBOOT_BINARY}[args.type] + # Parse machine type. + machineType = MACHINE_TYPES[args.machine] + + source = open(args.source, 'rb') + image = source.read() + # Pad image. + if len(image) % 4 != 0: + image += b'\0' * (4 - len(image) % 4) + + # Generate header. + header = make_header(image, args.build, args.version, args.oem, imageType, machineType) + + # Write output. + dest = open(args.dest, 'wb') + dest.write(header) + dest.write(image) diff --git a/target/linux/ipq806x/base-files/etc/board.d/02_network b/target/linux/ipq806x/base-files/etc/board.d/02_network index 6f490cb55d..e034172886 100644 --- a/target/linux/ipq806x/base-files/etc/board.d/02_network +++ b/target/linux/ipq806x/base-files/etc/board.d/02_network @@ -14,6 +14,11 @@ ipq806x_setup_interfaces() arris,tr4400-v2) ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "eth2" ;; + aruba,ap-32x|\ + edgecore,ecw5410|\ + extreme,ap3935) + ucidef_set_interfaces_lan_wan "eth1" "eth0" + ;; askey,rt4230w-rev6|\ asrock,g10|\ buffalo,wxr-2533dhp|\ @@ -47,10 +52,6 @@ ipq806x_setup_interfaces() ucidef_set_network_device_conduit "lan1" "eth1" ucidef_set_network_device_conduit "wan" "eth0" ;; - edgecore,ecw5410|\ - extreme,ap3935) - ucidef_set_interfaces_lan_wan "eth1" "eth0" - ;; fortinet,fap-421e|\ ignitenet,ss-w2-ac2600|\ ubnt,unifi-ac-hd|\ diff --git a/target/linux/ipq806x/base-files/etc/init.d/bootcount b/target/linux/ipq806x/base-files/etc/init.d/bootcount index 669b815e39..1b9ace9f63 100755 --- a/target/linux/ipq806x/base-files/etc/init.d/bootcount +++ b/target/linux/ipq806x/base-files/etc/init.d/bootcount @@ -6,13 +6,14 @@ START=99 boot() { case $(board_name) in - asrock,g10) - asrock_bootconfig_mangle "bootcheck" && reboot - ;; + aruba,ap-32x|\ edgecore,ecw5410|\ ignitenet,ss-w2-ac2600) fw_setenv bootcount 0 ;; + asrock,g10) + asrock_bootconfig_mangle "bootcheck" && reboot + ;; extreme,ap3935) fw_setenv WATCHDOG_COUNT 0x00000000 ;; diff --git a/target/linux/ipq806x/base-files/lib/upgrade/platform.sh b/target/linux/ipq806x/base-files/lib/upgrade/platform.sh index 972aa41a85..e980598a38 100644 --- a/target/linux/ipq806x/base-files/lib/upgrade/platform.sh +++ b/target/linux/ipq806x/base-files/lib/upgrade/platform.sh @@ -26,6 +26,21 @@ platform_do_upgrade() { qcom,ipq8064-ap161) nand_do_upgrade "$1" ;; + aruba,ap-32x) + # The bootloader on this device unfortunately enforces a particular set of UBI volumes, + # and will mess with the partitioning if it doesn't find it. + # Therefore, we have to make do with the stock layout, which is a set of three + # MTD partitions, each containing a single UBI volume with the same name. + # Luckily, it doesn't check size, so we can have a "rootfs_data" volume next to a dummy + # "ubifs" volume on the "ubifs" partition. + CI_KERNPART="aos0" + CI_ROOTPART="aos1" + CI_KERN_UBIPART="aos0" + CI_ROOT_UBIPART="aos1" + CI_DATA_UBIPART="ubifs" + CI_SKIP_KERNEL_MTD=1 + nand_do_upgrade "$1" + ;; asrock,g10) asrock_upgrade_prepare nand_do_upgrade "$1" diff --git a/target/linux/ipq806x/dts/qcom-ipq8068-ap-32x.dts b/target/linux/ipq806x/dts/qcom-ipq8068-ap-32x.dts new file mode 100644 index 0000000000..b6f1b7b110 --- /dev/null +++ b/target/linux/ipq806x/dts/qcom-ipq8068-ap-32x.dts @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qcom-ipq8064-v2.0.dtsi" + +#include +#include +#include + +/ { + model = "Aruba AP-32x"; + compatible = "aruba,ap-32x", "qcom,ipq8064"; + + memory@0 { + reg = <0x41500000 0x1eb00000>; + device_type = "memory"; + }; + + aliases { + serial0 = &gsbi4_serial; + serial1 = &gsbi2_serial; + + ethernet0 = &gmac2; + ethernet1 = &gmac3; + + led-boot = &led_power_amber; + led-failsafe = &led_power_red; + led-running = &led_power_green; + led-upgrade = &led_power_amber; + + label-mac-device = &gmac2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs-append = " ubi.mtd=aos1 ubi.mtd=ubifs ubi.block=0,aos1 root=/dev/ubiblock0_0"; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <&button_pins>; + pinctrl-names = "default"; + + reset { + label = "reset"; + gpios = <&qcom_pinmux 9 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + wakeup-source; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-0 = <&led_pins>; + pinctrl-names = "default"; + + led_power_green: power_green { + function = LED_FUNCTION_POWER; + color = ; + gpios = <&qcom_pinmux 28 GPIO_ACTIVE_HIGH>; + }; + + led_power_amber: power_amber { + function = LED_FUNCTION_POWER; + color = ; + gpios = <&qcom_pinmux 29 GPIO_ACTIVE_HIGH>; + }; + + led_power_red: power_red { + function = LED_FUNCTION_POWER; + color = ; + gpios = <&qcom_pinmux 30 GPIO_ACTIVE_HIGH>; + }; + + led_wlan_green { + function = LED_FUNCTION_WLAN; + color = ; + gpios = <&qcom_pinmux 31 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "phy0tpt"; + }; + + led_wlan_amber { + function = LED_FUNCTION_WLAN; + color = ; + gpios = <&qcom_pinmux 32 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "phy1tpt"; + }; + }; + + watchdog { + compatible = "linux,wdt-gpio"; + gpios = <&qcom_pinmux 61 GPIO_ACTIVE_LOW>; + hw_algo = "toggle"; + hw_margin_ms = <1000>; + always-running; + + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + }; + + i2c { + compatible = "i2c-gpio"; + + sda-gpios = <&qcom_pinmux 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&qcom_pinmux 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + #address-cells = <1>; + #size-cells = <0>; + + tpm@29 { + compatible = "atmel,at97sc3204t"; + reg = <0x29>; + }; + }; +}; + +&qcom_pinmux { + led_pins: led_pins { + mux { + pins = "gpio28", "gpio29", "gpio30", "gpio31", "gpio32"; + function = "gpio"; + drive-strength = <12>; + bias-pull-up; + }; + }; + + button_pins: button_pins { + mux { + pins = "gpio9"; + function = "gpio"; + bias-pull-up; + }; + }; + + uart0_pins: uart0_pins { + mux { + pins = "gpio10", "gpio11"; + function = "gsbi4"; + drive-strength = <10>; + bias-disable; + }; + }; + + uart1_pins: uart1_pins { + mux { + pins = "gpio22", "gpio23"; + function = "gsbi2"; + drive-strength = <10>; + bias-disable; + }; + }; + + watchdog_pins: watchdog_pins { + mux { + pins = "gpio61"; + function = "gpio"; + drive-strength = <10>; + bias-disable; + }; + }; + /* used for USB over-current detection instead */ + /delete-node/ pcie2_pins; +}; + +&gsbi4 { + status = "okay"; + qcom,mode = ; +}; + +&gsbi4_serial { + status = "okay"; + pinctrl-0 = <&uart0_pins>; + pinctrl-names = "default"; +}; + +&gsbi2 { + status = "okay"; + qcom,mode = ; +}; + +&gsbi2_serial { + status = "okay"; + pinctrl-0 = <&uart1_pins>; + pinctrl-names = "default"; +}; + +&gsbi5 { + qcom,mode = ; + status = "okay"; + + spi@1a280000 { + status = "okay"; + spi-max-frequency = <50000000>; + + pinctrl-0 = <&spi_pins>; + pinctrl-names = "default"; + + cs-gpios = <&qcom_pinmux 20 GPIO_ACTIVE_LOW>; + + mx25u3235f@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <50000000>; + reg = <0>; + + partitions { + compatible = "qcom,smem-part"; + + partition-art { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + label = "0:art"; + + precal_art_1000: precal@1000 { + reg = <0x1000 0x2f20>; + }; + + precal_art_5000: precal@5000 { + reg = <0x5000 0x2f20>; + }; + }; + + partition-appsblenv { + label = "0:appsblenv"; + + nvmem-layout { + compatible = "u-boot,env"; + + macaddr_lan: ethaddr { + #nvmem-cell-cells = <1>; + }; + }; + }; + }; + }; + }; +}; + +&pcie0 { + status = "okay"; +}; + +&pcie_bridge0 { + wifi@0,0 { + compatible = "qcom,ath10k"; + status = "okay"; + reg = <0x10000 0 0 0 0>; + + nvmem-cells = <&precal_art_1000>; + nvmem-cell-names = "pre-calibration"; + }; +}; + +&pcie1 { + status = "okay"; +}; + +&pcie_bridge1 { + wifi@0,0 { + compatible = "qcom,ath10k"; + status = "okay"; + reg = <0x10000 0 0 0 0>; + + nvmem-cells = <&precal_art_5000>; + nvmem-cell-names = "pre-calibration"; + }; +}; + +&nand { + status = "okay"; + + nand@0 { + compatible = "qcom,nandcs"; + + reg = <0>; + + nand-ecc-strength = <4>; + nand-bus-width = <8>; + nand-ecc-step-size = <512>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + aos0@0 { + label = "aos0"; + reg = <0x0 0x2000000>; + }; + + aos1@2000000 { + label = "aos1"; + reg = <0x2000000 0x2000000>; + }; + + ubifs@4000000 { + label = "ubifs"; + reg = <0x4000000 0x4000000>; + }; + }; + }; +}; + +&mdio0 { + status = "okay"; + + pinctrl-0 = <&mdio0_pins>; + pinctrl-names = "default"; + + phy0: ethernet-phy@0 { + reg = <0>; + }; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + +&gmac2 { + status = "okay"; + + qcom,id = <2>; + mdiobus = <&mdio0>; + + phy-mode = "sgmii"; + phy-handle = <&phy0>; + + nvmem-cells = <&macaddr_lan 0>; + nvmem-cell-names = "mac-address"; +}; + +&gmac3 { + status = "okay"; + + qcom,id = <3>; + mdiobus = <&mdio0>; + + phy-mode = "sgmii"; + phy-handle = <&phy1>; + + nvmem-cells = <&macaddr_lan 1>; + nvmem-cell-names = "mac-address"; +}; + +&adm_dma { + status = "okay"; +}; + +/* USB Port 0 is connected to the onboard BLE SoC. + * The stock FW on that doesn't implement USB, so to prevent errors from + * being logged when the host fails to initialize it, it's disabled by + * default here. */ +&hs_phy_0 { + status = "disabled"; +}; + +&ss_phy_0 { + status = "disabled"; +}; + +&usb3_0 { + status = "disabled"; +}; + +&hs_phy_1 { + status = "okay"; +}; + +&ss_phy_1 { + status = "okay"; +}; + +&usb3_1 { + status = "okay"; +}; diff --git a/target/linux/ipq806x/image/generic.mk b/target/linux/ipq806x/image/generic.mk index 5fbb3a79e6..9da73c4c03 100644 --- a/target/linux/ipq806x/image/generic.mk +++ b/target/linux/ipq806x/image/generic.mk @@ -48,6 +48,18 @@ define Build/linksys-addfwhdr ;mv "$@.new" "$@" endef +define Build/apboot-addfwhdr + $(SCRIPT_DIR)/aruba-header.py \ + $@ $@.new \ + "$(call toupper,$(LINUX_KARCH)) $(VERSION_DIST) Linux-$(LINUX_VERSION), $(VERSION_NUMBER) $(VERSION_CODE)"\ + "$(VERSION_NUMBER)" \ + "$(VERSION_DIST)" \ + os \ + "$(word 1,$(1))" + + mv "$@.new" "$@" +endef + define Device/DniImage KERNEL_SUFFIX := -uImage KERNEL = kernel-bin | append-dtb | uImage none @@ -102,6 +114,25 @@ define Device/arris_tr4400-v2 endef TARGET_DEVICES += arris_tr4400-v2 +define Device/aruba_ap-32x + $(call Device/LegacyImage) + DEVICE_VENDOR := Aruba + DEVICE_MODEL := AP-325 + DEVICE_ALT0_VENDOR := Aruba + DEVICE_ALT0_MODEL := AP-324 + DEVICE_ALT1_VENDOR := Siemens + DEVICE_ALT1_MODEL := Scalance W1750D + SOC := qcom-ipq8068 + PAGESIZE := 2048 + BLOCKSIZE := 128k + KERNEL_SUFFIX := .ari + KERNEL = kernel-bin | append-dtb | uImage none | apboot-addfwhdr Octomore + KERNEL_LOADADDR = 0x41508000 + KERNEL_SIZE := 30720k + DEVICE_PACKAGES := ath10k-firmware-qca99x0-ct kmod-i2c-gpio kmod-tpm-i2c-atmel +endef +TARGET_DEVICES += aruba_ap-32x + define Device/askey_rt4230w-rev6 $(call Device/LegacyImage) $(Device/dsa-migration)