ipq60xx: add support for ALFA Network AP120C-AX

ALFA Network AP120C-AX is a dual-band ceiling AP, based on Qualcomm
IPQ6000 + QCN5021 + QCN5052 + QCA8072 chipsets bundle.

Specifications:

- SOC:      Qualcomm IPQ6000 (quad-core Cortex-A53 1.2 GHz)
- DRAM:     DDR3 512 MB (Micron MT41K256M16TW-107)
- Flash:    16 MB SPI NOR (Macronix MX25U12832F, boot device)
            128 MB NAND (Macronix MX30UF1G18AC, dual-firmware)
- Ethernet: 2x 10/100/1000 Mbps Ethernet (QCA8072)
            802.3at/af PoE input in WAN port
- Wi-Fi:    2x2 2.4 GHz Wi-Fi 6 (QCN5021 + RFFM8227 FEM)
            2x2   5 GHz Wi-Fi 6 (QCN5152 + QPF4568 FEM)
- Antenna:  for indoor version: dual-band, internal
            2x (or 4x) U.FL antenna connectors on the PCB
- LED:      for indoor/outdoor versions: 5x on external module (status,
            2x Wi-Fi, 2x Ethernet), PoE LED on-board
            8-pin on-board header for LED module (1.27 mm pitch, J14)
- Button:   1x button (reset)
- USB:      1x 4-pin on-board header for USB 2.0 (2.54 mm pitch, J22)
- UART:     1x micro USB Type-B for system console (Holtek HT42B534)
            1x 4-pin on-board header (2.54 mm pitch, J11)
- Power:    802.3at/af PoE or 12 V DC/2 A (DC jack)
- Other:    8-pin and 4-pin on-board headers for external Bluetooth
            module (1.27 mm pitch, J15, J16, unavailable, thus untested)

MAC addresses:

- WAN:               00:c0:ca:xx:xx:6c (art 0x0, device's label -2)
- LAN:               00:c0:ca:xx:xx:6d (art 0x6, device's label -1)
- 2.4 GHz (IPQ6000): 00:c0:ca:xx:xx:6e (art 0xc, device's label)
-   5 GHz (IPQ6000): 00:c0:ca:xx:xx:6f (device's label + 1)

Flash instructions:

Due to the lack of direct GUI based update capability and dual-firmware
partition configuration, it is recommended to use TFTP + serial console
based approach (console is available in micro USB connector):

1. Set a static IP 192.168.1.1/24 on PC and start TFTP server with the
   '...-factory.ubi' image renamed to 'firmware.bin'.
2. Make sure you can access board's serial console over micro USB.
3. Power up the device, hit any key to enter U-Boot CLI and issue below
   commands.

3.1 Restore U-Boot's environment to default values (double check first
    the '0:APPSBLENV' partition offset using 'smem' command):

    sf probe
    sf erase 0x510000 0x10000
    saveenv

3.2 Download and install OpenWrt in both partitions and reset the board:

    tftpb 0x44000000 firmware.bin
    flash rootfs
    flash rootfs_1
    reset

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
This commit is contained in:
Piotr Dymacz 2025-04-04 22:42:57 +02:00
parent 658aaf192b
commit 35c828c168
7 changed files with 468 additions and 0 deletions

View file

@ -28,6 +28,7 @@ endef
ALLWIFIBOARDS:= \
8devices_mango \
alfa-network_ap120c-ax \
aliyun_ap8220 \
arcadyan_aw1000 \
asus_rt-ax89x \
@ -181,6 +182,7 @@ endef
# board-<devicename>.<qca4019|qca9888|qca9889|qca9984|qca99x0|ipq6018|ipq8074>
$(eval $(call generate-ipq-wifi-package,8devices_mango,8devices Mango))
$(eval $(call generate-ipq-wifi-package,alfa-network_ap120c-ax,ALFA Network AP120C-AX))
$(eval $(call generate-ipq-wifi-package,aliyun_ap8220,Aliyun AP8220))
$(eval $(call generate-ipq-wifi-package,arcadyan_aw1000,Arcadyan AW1000))
$(eval $(call generate-ipq-wifi-package,asus_rt-ax89x,Asus RT-AX89X))

View file

@ -0,0 +1,402 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/dts-v1/;
#include "ipq6018-512m.dtsi"
#include "ipq6018-ess.dtsi"
#include "ipq6018-cp-cpu.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>
/ {
model = "ALFA Network AP120C-AX";
compatible = "alfa-network,ap120c-ax", "qcom,ipq6018";
aliases {
serial0 = &blsp1_uart3;
serial1 = &blsp1_uart2;
led-boot = &led_status_green;
led-failsafe = &led_status_green;
led-running = &led_status_green;
led-upgrade = &led_status_green;
};
chosen {
stdout-path = "serial0:115200n8";
bootargs-append = " root=/dev/ubiblock0_1";
};
keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
reset {
label = "reset";
linux,code = <KEY_RESTART>;
gpios = <&tlmm 9 GPIO_ACTIVE_LOW>;
};
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&led_pins>;
pinctrl-names = "default";
led_status_green: status {
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_STATUS;
gpios = <&tlmm 55 GPIO_ACTIVE_LOW>;
};
wlan2g {
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_WLAN_2GHZ;
gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
linux,default-trigger = "phy1radio";
};
wlan5g {
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_WLAN_5GHZ;
gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
linux,default-trigger = "phy0radio";
};
};
};
&tlmm {
btcoex_pins: btcoex_pinmux {
mux_0 {
pins = "gpio51";
function = "pta1_1";
drive-strength = <6>;
bias-pull-down;
};
mux_1 {
pins = "gpio52";
function = "pta1_2";
drive-strength = <6>;
bias-pull-down;
};
mux_2 {
pins = "gpio53";
function = "pta1_0";
drive-strength = <6>;
bias-pull-down;
};
};
btrstint_pins: btrstint_pinmux {
pins = "gpio78", "gpio79";
function = "gpio";
drive-strength = <8>;
bias-disable;
};
button_pins: button_pinmux {
pins = "gpio9";
function = "gpio";
drive-strength = <8>;
bias-disable;
};
hsuart_pins: hsuart_pinmux {
pins = "gpio71", "gpio72", "gpio69", "gpio70";
function = "blsp1_uart";
drive-strength = <8>;
bias-disable;
};
led_pins: led_pinmux {
pins = "gpio35", "gpio37", "gpio55";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
mdio_pins: mdio_pinmux {
mdc {
pins = "gpio64";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mdio {
pins = "gpio65";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
};
spi_pins: spi_pinmux {
pins = "gpio38", "gpio39", "gpio40", "gpio41";
function = "blsp0_spi";
drive-strength = <8>;
bias-pull-down;
};
};
&blsp1_uart3 {
status = "okay";
pinctrl-0 = <&serial_3_pins>;
pinctrl-names = "default";
};
&blsp1_uart2 {
status = "okay";
pinctrl-0 = <&hsuart_pins &btcoex_pins &btrstint_pins>;
pinctrl-names = "default";
dmas = <&blsp_dma 2>, <&blsp_dma 3>;
dma-names = "tx", "rx";
};
&blsp1_spi1 {
status = "okay";
pinctrl-0 = <&spi_pins>;
pinctrl-names = "default";
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "jedec,spi-nor";
spi-max-frequency = <25000000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "0:SBL1";
reg = <0x00000000 0x000c0000>;
read-only;
};
partition@c0000 {
label = "0:MIBIB";
reg = <0x000c0000 0x00010000>;
read-only;
};
partition@d0000 {
label = "0:BOOTCONFIG";
reg = <0x000d0000 0x00020000>;
};
partition@f0000 {
label = "0:BOOTCONFIG1";
reg = <0x000f0000 0x00020000>;
};
partition@110000 {
label = "0:QSEE";
reg = <0x00110000 0x001a0000>;
read-only;
};
partition@2b0000 {
label = "0:QSEE_1";
reg = <0x002b0000 0x001a0000>;
read-only;
};
partition@450000 {
label = "0:DEVCFG";
reg = <0x00450000 0x00010000>;
read-only;
};
partition@460000 {
label = "0:DEVCFG_1";
reg = <0x00460000 0x00010000>;
read-only;
};
partition@470000 {
label = "0:RPM";
reg = <0x00470000 0x00040000>;
read-only;
};
partition@4b0000 {
label = "0:RPM_1";
reg = <0x004b0000 0x00040000>;
read-only;
};
partition@4f0000 {
label = "0:CDT";
reg = <0x004f0000 0x00010000>;
read-only;
};
partition@500000 {
label = "0:CDT_1";
reg = <0x00500000 0x00010000>;
read-only;
};
partition@510000 {
label = "0:APPSBLENV";
reg = <0x00510000 0x00010000>;
};
partition@520000 {
label = "0:APPSBL";
reg = <0x00520000 0x000a0000>;
read-only;
};
partition@5c0000 {
label = "0:APPSBL_1";
reg = <0x005c0000 0x000a0000>;
read-only;
};
partition@660000 {
label = "0:ART";
reg = <0x00660000 0x00040000>;
nvmem-layout {
compatible = "fixed-layout";
#address-cells = <1>;
#size-cells = <1>;
macaddr_lan: macaddr@6 {
reg = <0x6 0x6>;
};
macaddr_wan: macaddr@0 {
reg = <0x0 0x6>;
};
};
};
};
};
};
&qpic_bam {
status = "okay";
};
&qpic_nand {
status = "okay";
/*
* This board uses NOR+NAND configuration which is currently not
* supported by 'qcomsmem' MTD parser. Let U-Boot find the NAND
* dt node and populate MTD partitions from SMEM partition table.
*
* This makes it possible to use QCA 'runtime failsafe' and rotate
* 'rootfs'/'rootfs_1' partitions between subsequent updates.
*/
compatible = "qcom,ipq6018-nand", "qcom,ebi2-nandc-bam-v1.5.0";
nand@0 {
reg = <0>;
nand-bus-width = <8>;
};
};
&qusb_phy_0 {
status = "okay";
};
&ssphy_0 {
status = "okay";
};
&usb3 {
status = "okay";
};
&mdio {
status = "okay";
pinctrl-0 = <&mdio_pins>;
pinctrl-names = "default";
reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>;
reset-delay-us = <10000>;
reset-post-delay-us = <50000>;
ethernet-phy-package@0 {
compatible = "qcom,qca8075-package";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
qcom,package-mode = "psgmii";
qca8072_3: ethernet-phy@3 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <3>;
};
qca8072_4: ethernet-phy@4 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <4>;
};
};
};
&switch {
status = "okay";
switch_lan_bmp = <ESS_PORT4>;
switch_wan_bmp = <ESS_PORT5>;
switch_mac_mode = <MAC_MODE_PSGMII>;
qcom,port_phyinfo {
port@4 {
port_id = <4>;
phy_address = <3>;
};
port@5 {
port_id = <5>;
phy_address = <4>;
};
};
};
&edma {
status = "okay";
};
&dp4 {
status = "okay";
phy-handle = <&qca8072_3>;
label = "lan";
nvmem-cells = <&macaddr_lan>;
nvmem-cell-names = "mac-address";
};
&dp5 {
status = "okay";
phy-handle = <&qca8072_4>;
label = "wan";
nvmem-cells = <&macaddr_wan>;
nvmem-cell-names = "mac-address";
};
&wifi {
status = "okay";
qcom,ath11k-fw-memory-mode = <1>;
qcom,ath11k-calibration-variant = "ALFA-Network-AP120C-AX";
};

View file

@ -23,6 +23,18 @@ define Device/8devices_mango-dvk
endef
TARGET_DEVICES += 8devices_mango-dvk
define Device/alfa-network_ap120c-ax
$(call Device/FitImage)
$(call Device/UbiFit)
DEVICE_VENDOR := ALFA Network
DEVICE_MODEL := AP120C-AX
BLOCKSIZE := 128k
PAGESIZE := 2048
SOC := ipq6000
DEVICE_PACKAGES := ipq-wifi-alfa-network_ap120c-ax
endef
TARGET_DEVICES += alfa-network_ap120c-ax
define Device/cambiumnetworks_xe3-4
$(call Device/FitImage)
$(call Device/UbiFit)

View file

@ -15,6 +15,9 @@ ipq60xx_setup_interfaces()
glinet,gl-axt1800)
ucidef_set_interfaces_lan_wan "lan1 lan2" "wan"
;;
alfa-network,ap120c-ax)
ucidef_set_interfaces_lan_wan "lan" "wan"
;;
cambiumnetworks,xe3-4)
ucidef_set_interface_lan "lan1 lan2" "dhcp"
;;
@ -51,6 +54,9 @@ ipq60xx_setup_macs()
local label_mac=""
case $board in
alfa-network,ap120c-ax)
label_mac=$(mtd_get_mac_binary 0:ART 12)
;;
qihoo,360v6)
lan_mac=$(mtd_get_mac_ascii factory lanMac)
wan_mac=$(macaddr_add "$lan_mac" 1)

View file

@ -12,6 +12,13 @@ case "$FIRMWARE" in
8devices,mango-dvk)
caldata_extract "0:ART" 0x1000 0x20000
;;
alfa-network,ap120c-ax)
caldata_extract "0:ART" 0x1000 0x20000
label_mac=$(mtd_get_mac_binary 0:ART 12)
ath11k_patch_mac $label_mac 1
ath11k_patch_mac $(macaddr_add $label_mac 1) 0
ath11k_set_macflag
;;
cambiumnetworks,xe3-4)
caldata_extract "0:ART" 0x1000 0x10000
;;

View file

@ -0,0 +1,34 @@
. /lib/functions.sh
# Flip active 'rootfs' partition in selected 'bootconfig' mtd partition
# $1 target 'bootconfig' mtd partition name
# $2 'offset' of the active rootfs flag byte
alfa_bootconfig_rootfs_rotate() {
local part="$1"
local offs="$2"
local mtdnum=$(find_mtd_index "$part")
[ -c "/dev/mtd${mtdnum}" ] || return 1
dd if=/dev/mtd${mtdnum} of=/tmp/mtd${mtdnum} bs=1k > /dev/null 2>&1
local active="$(dd if=/tmp/mtd${mtdnum} bs=1 skip=${offs} count=1 2>/dev/null)"
active=$(printf "%d\n" "\"$active")
if [ "$active" = "1" ]; then
printf '\x00' | dd of=/tmp/mtd${mtdnum} \
conv=notrunc bs=1 seek=${offs} > /dev/null 2>&1
else
printf '\x01' | dd of=/tmp/mtd${mtdnum} \
conv=notrunc bs=1 seek=${offs} > /dev/null 2>&1
fi
mtd -qq write /tmp/mtd${mtdnum} /dev/mtd${mtdnum} 2>/dev/null
local mtdnum_sec=$(find_mtd_index "${part}1")
[ -c "/dev/mtd${mtdnum_sec}" ] && \
mtd -qq write \
/tmp/mtd${mtdnum} /dev/mtd${mtdnum_sec} 2>/dev/null
return 0
}

View file

@ -106,6 +106,11 @@ EOF
platform_do_upgrade() {
case "$(board_name)" in
alfa-network,ap120c-ax)
CI_UBIPART="rootfs_1"
alfa_bootconfig_rootfs_rotate "0:BOOTCONFIG" "148"
nand_do_upgrade "$1"
;;
cambiumnetworks,xe3-4)
fw_setenv bootcount 0
nand_do_upgrade "$1"