Adding support for Ubiquiti UniFi AP Outdoor

Hi!

I would like to port OpenWRT on the Ubiquiti UniFi AP Outdoor router. I know that the AP Outdoor Plus is already supported but I have no idea of the differences between the two routers.

It is my first time on porting OpenWRT on a new device so I will need some help.

First, to avoid to corrupt the flash for each attempt, I would prefer to load a ramdisk from tftp but I am not sure how to achieve that. I have read this wiki page but it is for flashing and not just for testing.

My first attempt was to flash the AP Outdoor Plus image via:

fwupdate.real -m openwrt-ar71xx-generic-ubnt-unifi-outdoor-plus-squashfs-factory.bin -d

But I have ended up with a corrupted flash and a device stuck in u-Boot.

I have managed to flash a stock Ubiquiti image BZ.ar7240.v3.7.58.6385.170508.0942.bin using the Ubiquiti recovery procedure (tftp server via RESET press at boot).

So this time I would like to avoid the recovery process after each attempt.

I have added some bits to try to support my router by copying the changes needed by the Outdoor Plus. I have modified to flash layout to match the stock one, the leds need to be tested and I have no idea where the wifi firmware is located.

Patch
From a390cc519b37434c35fe72fd16dfb28c762257a8 Mon Sep 17 00:00:00 2001
From: Romain <romain@todo.com>
Date: Thu, 16 Dec 2021 16:27:53 +0100
Subject: [PATCH] ath79: add support for Ubiquiti UniFi AP Outdoor

---
 .../dts/ar7241_ubnt_unifi-ap-outdoor.dts      | 109 ++++++++++++++++++
 .../generic/base-files/etc/board.d/02_network |   1 +
 .../etc/hotplug.d/firmware/10-ath9k-eeprom    |   3 +
 target/linux/ath79/image/generic-ubnt.mk      |   8 ++
 4 files changed, 121 insertions(+)
 create mode 100644 target/linux/ath79/dts/ar7241_ubnt_unifi-ap-outdoor.dts

diff --git a/target/linux/ath79/dts/ar7241_ubnt_unifi-ap-outdoor.dts b/target/linux/ath79/dts/ar7241_ubnt_unifi-ap-outdoor.dts
new file mode 100644
index 0000000000..b2704df505
--- /dev/null
+++ b/target/linux/ath79/dts/ar7241_ubnt_unifi-ap-outdoor.dts
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar7241_ubnt_unifi.dtsi"
+
+/ {
+       compatible = "ubnt,unifi-ap-outdoor", "qca,ar7241";
+       model = "Ubiquiti UniFi AP Outdoor";
+
+       aliases {
+               led-boot = &led_white;
+               led-failsafe = &led_white;
+               led-running = &led_blue;
+               led-upgrade = &led_blue;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led_blue: blue {
+                       label = "blue";
+                       gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
+               };
+
+               led_white: white {
+                       label = "white";
+                       gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
+               };
+       };
+};
+
+&spi {
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <50000000>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       uboot: partition@0 {
+                               label = "u-boot";
+                               reg = <0x0 0x40000>;
+                               read-only;
+                       };
+
+                       partition@40000 {
+                               label = "u-boot-env";
+                               reg = <0x40000 0x10000>;
+                               read-only;
+                       };
+
+                       partition@50000 {
+                               label = "kernel";
+                               reg = <0x50000 0x100000>;
+                       };
+
+                       partition@150000 {
+                               label = "rootfs";
+                               reg = <0x150000 0x660000>;
+                       };
+
+                       partition@7B0000 {
+                               label = "cfg";
+                               reg = <0x7B0000 0x40000>;
+                               read-only;
+                       };
+
+                       eeprom: partition@7F0000 {
+                               label = "eeprom";
+                               reg = <0x7F0000 0x10000>;
+                               read-only;
+                       };
+               };
+       };
+};
+
+&eth0 {
+       nvmem-cells = <&macaddr_eeprom_0>;
+       nvmem-cell-names = "mac-address";
+};
+
+&eth1 {
+       status = "okay";
+
+       nvmem-cells = <&macaddr_eeprom_6>;
+       nvmem-cell-names = "mac-address";
+};
+
+&wifi {
+       ubnt,hsr;
+};
+
+&eeprom {
+       compatible = "nvmem-cells";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       macaddr_eeprom_0: macaddr@0 {
+               reg = <0x0 0x6>;
+       };
+
+       macaddr_eeprom_6: macaddr@6 {
+               reg = <0x6 0x6>;
+       };
+};
diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network
index edd79b606e..14461b9f4a 100644
--- a/target/linux/ath79/generic/base-files/etc/board.d/02_network
+++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network
@@ -117,6 +117,7 @@ ath79_setup_interfaces()
        engenius,enstationac-v1|\
        engenius,ews511ap|\
        ocedo,ursus|\
+       ubnt,unifi-ap-outdoor|\
        ubnt,unifi-ap-outdoor-plus)
                ucidef_set_interface_lan "eth0 eth1"
                ;;
diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
index 219e618cb9..4b720587a5 100644
--- a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
+++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
@@ -123,6 +123,9 @@ case "$FIRMWARE" in
        ubnt,rocket-m)
                caldata_extract "art" 0x1000 0x1000
                ;;
+       ubnt,unifi-ap-outdoor)
+               caldata_extract "eeprom" 0x1000 0xeb8
+               ;;
        openmesh,mr600-v1|\
        openmesh,mr600-v2)
                caldata_extract "ART" 0x5000 0x440
diff --git a/target/linux/ath79/image/generic-ubnt.mk b/target/linux/ath79/image/generic-ubnt.mk
index 3888e1652b..a537b84fd7 100644
--- a/target/linux/ath79/image/generic-ubnt.mk
+++ b/target/linux/ath79/image/generic-ubnt.mk
@@ -457,6 +457,14 @@ define Device/ubnt_unifiac-pro
 endef
 TARGET_DEVICES += ubnt_unifiac-pro

+define Device/ubnt_unifi-ap-outdoor
+  $(Device/ubnt-bz)
+  $(Device/ubnt-unifi-jffs2)
+  DEVICE_MODEL := UniFi AP Outdoor
+  SUPPORTED_DEVICES += unifi-ap-outdoor
+endef
+TARGET_DEVICES += ubnt_unifi-ap-outdoor
+
 define Device/ubnt_unifi-ap-outdoor-plus
   $(Device/ubnt-bz)
   $(Device/ubnt-unifi-jffs2)
--
2.17.1

I have built a new OpenWRT image but now, how could I test it?

Thank you

You can find an example of booting a ramdisk here. With a bit of luck the bootloader should offer the possibility to copy an image into RAM and boot from that.

There's an option in the buildroot to enable ramdisk images, you should check that (use forward slash as a search function in the buildroot).

They only made the Outdoor in 5 GHz, it was called the Outdoor 5. It should be called that in any patch to avoid confusion.* It really looks like it would be similar enough to the Outdoor Plus to run the same firmware. OpenWrt is good at probing for different radios and setting them up automatically. Most of the differences in a model series were the number and type (gigabit vs FE) of Ethernet ports, and that needs to be supported in the dts and kernel build-- but the Outdoor Plus is also two FE ports like the Outdoor 5. I would try booting the existing ramdisk Outdoor Plus firmware, log in via serial, and find what does and does not work.

  • The Unifi AC Outdoor model, a large square box with internal antennas, has a Broadcom chipset that is not supportable.

Great! I have managed to boot my image!
Cool!
Event the WiFi works on first attempt.
About the Leds, the colors are green and orange instead of blue and white but the GPIO are the good one.
Thank you!

Thanks @mk24
Interesting.
Mine is called UAP Outdoor on the box:


And the Wifi is 2.4 GHz.
This model.

I will try the Outdoor+ ramdisk.

@mk24 Are the ramdisk available for download somewhere?
Or do I have to build it?

As expected, in my build, the firmware is not loaded from the EEPROM

[   11.811145] ath9k 0000:00:00.0: Direct firmware load for ath9k-eeprom-pci-0000:00:00.0.bin failed with error -2
[   11.821359] ath9k 0000:00:00.0: Falling back to sysfs fallback for: ath9k-eeprom-pci-0000:00:00.0.bin

Interesting. There actually was a regular Outdoor (2.4) at one point, but the brochure I first looked at showed only the Plus and the 5. The difference may only be the power supply in the Plus is improved to accept standard af PoE not just 24 volt passive PoE.

The snapshots directory has pre-built initramfs images for all model targets.

Thanks @mk24
It is much quicker!

Bootlog
U-Boot unifi-v1.5.2.206-g44e4c8bc (Aug 29 2014 - 18:01:57)

DRAM:  64 MB
Flash:  8 MB
PCIe WLAN Module found (tries: 1). 
Net:   eth0, eth1
Board: Copyright Ubiquiti Networks Inc. 2014
Hit any key to stop autoboot:  0 
ar7240> tftpboot 0x84f00000 openwrt-ath79-generic-ubnt_unifi-ap-outdoor-plus-initramfs-kernel.bin
Using eth0 device
TFTP from server 192.168.1.254; our IP address is 192.168.1.20
Filename 'openwrt-ath79-generic-ubnt_unifi-ap-outdoor-plus-initramfs-kernel.bin'.
Load address: 0x84f00000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ####################################
done
Bytes transferred = 4842546 (49e432 hex)
ar7240> bootm
## Booting image at 84f00000 ...
   Image Name:   MIPS OpenWrt Linux-5.4.162
   Created:      2021-12-17  14:03:05 UTC
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Data Size:    4842482 Bytes =  4.6 MB
   Load Address: 80060000
   Entry Point:  80060000
   Verifying Checksum at 0x84f00040 ...OK
   Uncompressing Kernel Image ... OK

Starting kernel ...

[    0.000000] Linux version 5.4.162 (builder@buildhost) (gcc version 11.2.0 (OpenWrt GCC 11.2.0 r18356-87def9efd8)) #0 Fri Dec 17 14:03:05 2021
[    0.000000] printk: bootconsole [early0] enabled
[    0.000000] CPU0 revision is: 00019374 (MIPS 24Kc)
[    0.000000] MIPS: machine is Ubiquiti UniFi AP Outdoor+
[    0.000000] SoC: Atheros AR7241 rev 1
[    0.000000] Initrd not found or empty - disabling initrd
[    0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes.
[    0.000000] Primary data cache 32kB, 4-way, VIPT, cache aliases, linesize 32 bytes
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16240
[    0.000000] Kernel command line: console=ttyS0,115200 rootfstype=squashfs,jffs2
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[    0.000000] Writing ErrCtl register=00000000
[    0.000000] Readback ErrCtl register=00000000
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 48764K/65536K available (5340K kernel code, 188K rwdata, 1172K rodata, 9164K init, 205K bss, 16772K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS: 51
[    0.000000] random: get_random_bytes called from start_kernel+0x354/0x548 with crng_init=0
[    0.000000] CPU clock: 390.000 MHz
[    0.000000] clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 9801335621 ns
[    0.000012] sched_clock: 32 bits at 195MHz, resolution 5ns, wraps every 11012737021ns
[    0.007898] Calibrating delay loop... 259.27 BogoMIPS (lpj=1296384)
[    0.084072] pid_max: default: 32768 minimum: 301
[    0.088904] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.096193] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.110530] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.120372] futex hash table entries: 256 (order: -1, 3072 bytes, linear)
[    0.127298] pinctrl core: initialized pinctrl subsystem
[    0.136307] NET: Registered protocol family 16
[    0.186193] clocksource: Switched to clocksource MIPS
[    0.192669] thermal_sys: Registered thermal governor 'step_wise'
[    0.193284] NET: Registered protocol family 2
[    0.203870] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.212274] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes, linear)
[    0.220700] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.228351] TCP bind hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.235380] TCP: Hash tables configured (established 1024 bind 1024)
[    0.241939] UDP hash table entries: 256 (order: 0, 4096 bytes, linear)
[    0.248529] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes, linear)
[    0.255904] NET: Registered protocol family 1
[    0.260332] PCI: CLS 0 bytes, default 32
[    0.492308] workingset: timestamp_bits=14 max_order=14 bucket_order=0
[    0.510062] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.515859] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    0.545631] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
[    0.556771] pinctrl-single 18040028.pinmux: 64 pins, size 8
[    0.563652] Serial: 8250/16550 driver, 16 ports, IRQ sharing enabled
[    0.573667] printk: console [ttyS0] disabled
[    0.578068] 18020000.uart: ttyS0 at MMIO 0x18020000 (irq = 9, base_baud = 12187500) is a 16550A
[    0.586756] printk: console [ttyS0] enabled
[    0.586756] printk: console [ttyS0] enabled
[    0.595137] printk: bootconsole [early0] disabled
[    0.595137] printk: bootconsole [early0] disabled
[    0.619000] spi-nor spi0.0: mx25l6405d (8192 Kbytes)
[    0.624052] 5 fixed-partitions partitions found on MTD device spi0.0
[    0.630510] Creating 5 MTD partitions on "spi0.0":
[    0.635328] 0x000000000000-0x000000040000 : "u-boot"
[    0.641780] 0x000000040000-0x000000050000 : "u-boot-env"
[    0.648591] 0x000000050000-0x000000fb0000 : "firmware"
[    0.653757] mtd: partition "firmware" extends beyond the end of device "spi0.0" -- size truncated to 0x7b0000
[    0.665125] 2 fixed-partitions partitions found on MTD device firmware
[    0.671763] Creating 2 MTD partitions on "firmware":
[    0.676767] 0x000000000000-0x000000300000 : "kernel"
[    0.683076] 0x000000300000-0x000000f60000 : "rootfs"
[    0.688145] mtd: partition "rootfs" extends beyond the end of device "firmware" -- size truncated to 0x4b0000
[    0.699432] mtd: device 4 (rootfs) set to be root filesystem
[    0.712181] mtdsplit: no squashfs found in "rootfs"
[    0.717238] 0x000000fb0000-0x000000ff0000 : "cfg"
[    0.721953] mtd: partition "cfg" is out of reach -- disabled
[    0.729088] 0x000000ff0000-0x000001000000 : "art"
[    0.733820] mtd: partition "art" is out of reach -- disabled
[    0.743844] libphy: Fixed MDIO Bus: probed
[    0.752935] ag71xx 19000000.eth: invalid MAC address, using random address
[    1.097322] ag71xx 19000000.eth: Could not connect to PHY device. Deferring probe.
[    1.105333] ag71xx 1a000000.eth: invalid MAC address, using random address
[    1.786661] libphy: ag71xx_mdio: probed
[    1.791523] libphy: ar8xxx-mdio: probed
[    1.834664] switch0: Atheros AR724X/AR933X built-in rev. 2 switch registered on mdio.0
[    1.918290] ag71xx 1a000000.eth: connected to PHY at fixed-0:00 [uid=00000000, driver=Generic PHY]
[    1.928271] eth0: Atheros AG71xx at 0xba000000, irq 5, mode: gmii
[    1.934813] i2c /dev entries driver
[    1.941474] NET: Registered protocol family 10
[    1.953642] Segment Routing with IPv6
[    1.957584] NET: Registered protocol family 17
[    1.962134] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[    1.975161] 8021q: 802.1Q VLAN Support v1.8
[    1.980761] PCI host bridge /ahb/apb/pcie-controller@180c0000 ranges:
[    1.987352]  MEM 0x0000000010000000..0x0000000013ffffff
[    1.992603]   IO 0x0000000000000000..0x0000000000000000
[    1.998099] PCI host bridge to bus 0000:00
[    2.002229] pci_bus 0000:00: root bus resource [mem 0x10000000-0x13ffffff]
[    2.009158] pci_bus 0000:00: root bus resource [io  0x0000]
[    2.014752] pci_bus 0000:00: root bus resource [??? 0x00000000 flags 0x0]
[    2.021572] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
[    2.029585] pci 0000:00:00.0: [168c:002a] type 00 class 0x028000
[    2.035680] pci 0000:00:00.0: reg 0x10: [mem 0x10000000-0x1000ffff 64bit]
[    2.042708] pci 0000:00:00.0: supports D1
[    2.046758] pci 0000:00:00.0: PME# supported from D0 D1 D3hot
[    2.054094] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 00
[    2.060807] pci 0000:00:00.0: BAR 0: assigned [mem 0x10000000-0x1000ffff 64bit]
[    2.068824] ag71xx 19000000.eth: invalid MAC address, using random address
[    2.407823] ag71xx 19000000.eth: connected to PHY at mdio.0:1f:04 [uid=004dd041, driver=Generic PHY]
[    2.418375] eth1: Atheros AG71xx at 0xb9000000, irq 4, mode: mii
[    2.425671] hctosys: unable to open rtc device (rtc0)
[    2.507733] Freeing unused kernel memory: 9164K
[    2.512289] This architecture does not have kernel memory protection.
[    2.518781] Run /init as init process
[    2.536250] random: fast init done
[    3.173487] init: Console is alive
[    3.177764] init: - watchdog -
[    3.181372] init: Watchdog has previously reset the system
[    3.225044] kmodloader: loading kernel modules from /etc/modules-boot.d/*
[    3.286509] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[    3.304437] init: - preinit -
[    3.774748] random: jshn: uninitialized urandom read (4 bytes read)
[    4.013683] random: jshn: uninitialized urandom read (4 bytes read)
[    4.078853] random: jshn: uninitialized urandom read (4 bytes read)
[    4.425396] eth0: link up (1000Mbps/Full duplex)
[    4.436340] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
Press the [f] key and hit [enter] to enter failsafe mode
Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level
[    8.678344] eth0: link down
[    8.699836] procd: - early -
[    8.703256] procd: - watchdog -
[    8.707051] procd: Watchdog has previously reset the system
[    9.383742] procd: - watchdog -
[    9.387126] procd: Watchdog has previously reset the system
[    9.393216] procd: - ubus -
[    9.410078] urandom_read: 5 callbacks suppressed
[    9.410090] random: ubusd: uninitialized urandom read (4 bytes read)
[    9.447394] random: ubusd: uninitialized urandom read (4 bytes read)
[    9.459508] procd: - init -
Please press Enter to activate this console.
[   10.433274] kmodloader: loading kernel modules from /etc/modules.d/*
[   10.944391] Loading modules backported from Linux version v5.15.8-0-g43e577d7a2cb
[   10.951984] Backport generated by backports.git v5.15.8-1-0-g83f664bb
[   11.055410] xt_time: kernel timezone is -0000
[   11.270584] PPP generic driver version 2.4.2
[   11.297845] NET: Registered protocol family 24
[   11.448932] ath9k 0000:00:00.0: Direct firmware load for ath9k-eeprom-pci-0000:00:00.0.bin failed with error -2
[   11.459137] ath9k 0000:00:00.0: Falling back to sysfs fallback for: ath9k-eeprom-pci-0000:00:00.0.bin
[   11.745628] urngd: v1.0.2 started.
[   11.833014] ath: phy0: Unable to load EEPROM file ath9k-eeprom-pci-0000:00:00.0.bin
[   11.840793] ath9k 0000:00:00.0: Failed to initialize device
[   11.846497] ath9k: probe of 0000:00:00.0 failed with error -22
[   11.897009] kmodloader: done loading kernel modules from /etc/modules.d/*
[   12.284608] random: crng init done



BusyBox v1.34.1 (2021-12-17 14:03:05 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt SNAPSHOT, r18356-87def9efd8
 -----------------------------------------------------
=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@OpenWrt:/# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel state DOWN qlen 1000
    link/ether e6:69:ba:14:8c:0e brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 0a:19:a2:ac:d2:9b brd ff:ff:ff:ff:ff:ff
root@OpenWrt:/# [   77.322118] eth0: link up (1000Mbps/Full duplex)
[   77.337058] br-lan: port 1(eth0) entered blocking state
[   77.342313] br-lan: port 1(eth0) entered disabled state
[   77.348116] device eth0 entered promiscuous mode
[   77.380477] br-lan: port 1(eth0) entered blocking state
[   77.385732] br-lan: port 1(eth0) entered forwarding state
[   77.506990] br-lan: port 2(eth1) entered blocking state
[   77.512243] br-lan: port 2(eth1) entered disabled state
[   77.518042] device eth1 entered promiscuous mode
[   78.336359] IPv6: ADDRCONF(NETDEV_CHANGE): br-lan: link becomes ready
[   79.537895] eth1: link up (100Mbps/Half duplex)
[   79.542497] br-lan: port 2(eth1) entered blocking state
[   79.547791] br-lan: port 2(eth1) entered forwarding state

Oh and from this it seems the Plus had a 16 MB flash.

This means DO NOT use sysugrade or mtd here because the partition table is wrong and you are likely to clobber the ART data. I suggest booting the Ubiquiti stock and using it to make a backup of ART before doing anything further.

1 Like

My issue that from Ubiquiti, there is no art partition but an EEPROM one.
Is it the same thing?

BZ.v3.7.58# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00040000 00010000 "u-boot"
mtd1: 00010000 00010000 "u-boot-env"
mtd2: 00100000 00010000 "kernel"
mtd3: 00660000 00010000 "rootfs"
mtd4: 00040000 00010000 "cfg"
mtd5: 00010000 00010000 "EEPROM"

Yes it's the same thing. It's only a name.

In very early times the calibration data was stored in a dedicated EEPROM chip attached to the radio chip. This was soon changed to storing it in a partition of the flash chip instead, saving the cost of a separate chip.

Ok, I see.
As reference, with my dts with a flash layout closer to stock OS, I did not have this error:

Bootlog
U-Boot unifi-v1.5.2.206-g44e4c8bc (Aug 29 2014 - 18:01:57)

DRAM:  64 MB
Flash:  8 MB
PCIe WLAN Module found (tries: 1). 
Net:   eth0, eth1
Board: Copyright Ubiquiti Networks Inc. 2014
Hit any key to stop autoboot:  0 
ar7240> tftpboot 0x84f00000 openwrt-snapshot-r18354+1-cc3e390a74-ath79-generic-ubnt_unifi-ap-outdoor-initramfs-kernel.bin
Using eth0 device
TFTP from server 192.168.1.254; our IP address is 192.168.1.20
Filename 'openwrt-snapshot-r18354+1-cc3e390a74-ath79-generic-ubnt_unifi-ap-outdoor-initramfs-kernel.bin'.
Load address: 0x84f00000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################
done
Bytes transferred = 5159885 (4ebbcd hex)
ar7240> bootm
## Booting image at 84f00000 ...
   Image Name:   MIPS OpenWrt Linux-5.4.162
   Created:      2021-12-16  15:27:53 UTC
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Data Size:    5159821 Bytes =  4.9 MB
   Load Address: 80060000
   Entry Point:  80060000
   Verifying Checksum at 0x84f00040 ...OK
   Uncompressing Kernel Image ... OK

Starting kernel ...

[    0.000000] Linux version 5.4.162 (builder@buildhost) (gcc version 11.2.0 (OpenWrt GCC 11.2.0 r18354+1-cc3e390a74)) #0 Thu Dec 16 15:27:53 2021
[    0.000000] printk: bootconsole [early0] enabled
[    0.000000] CPU0 revision is: 00019374 (MIPS 24Kc)
[    0.000000] MIPS: machine is Ubiquiti UniFi AP Outdoor
[    0.000000] SoC: Atheros AR7241 rev 1
[    0.000000] Initrd not found or empty - disabling initrd
[    0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes.
[    0.000000] Primary data cache 32kB, 4-way, VIPT, cache aliases, linesize 32 bytes
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16240
[    0.000000] Kernel command line: console=ttyS0,115200 rootfstype=squashfs,jffs2
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[    0.000000] Writing ErrCtl register=00000000
[    0.000000] Readback ErrCtl register=00000000
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 47484K/65536K available (5306K kernel code, 193K rwdata, 672K rodata, 10972K init, 205K bss, 18052K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS: 51
[    0.000000] random: get_random_bytes called from 0x80669a0c with crng_init=0
[    0.000000] CPU clock: 390.000 MHz
[    0.000000] clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 9801335621 ns
[    0.000013] sched_clock: 32 bits at 195MHz, resolution 5ns, wraps every 11012737021ns
[    0.007904] Calibrating delay loop... 259.27 BogoMIPS (lpj=1296384)
[    0.084070] pid_max: default: 32768 minimum: 301
[    0.088909] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.096200] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.110497] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.120344] futex hash table entries: 256 (order: -1, 3072 bytes, linear)
[    0.127268] pinctrl core: initialized pinctrl subsystem
[    0.136254] NET: Registered protocol family 16
[    0.178932] clocksource: Switched to clocksource MIPS
[    0.185502] thermal_sys: Registered thermal governor 'step_wise'
[    0.186022] NET: Registered protocol family 2
[    0.196630] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.205038] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes, linear)
[    0.213467] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.221125] TCP bind hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.228150] TCP: Hash tables configured (established 1024 bind 1024)
[    0.234716] UDP hash table entries: 256 (order: 0, 4096 bytes, linear)
[    0.241309] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes, linear)
[    0.248710] NET: Registered protocol family 1
[    0.253152] PCI: CLS 0 bytes, default 32
[    0.560647] workingset: timestamp_bits=14 max_order=14 bucket_order=0
[    0.578502] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.584373] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    0.613555] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
[    0.624582] pinctrl-single 18040028.pinmux: 64 pins, size 8
[    0.631513] Serial: 8250/16550 driver, 16 ports, IRQ sharing enabled
[    0.641544] printk: console [ttyS0] disabled
[    0.645866] 18020000.uart: ttyS0 at MMIO 0x18020000 (irq = 9, base_baud = 12187500) is a 16550A
[    0.654621] printk: console [ttyS0] enabled
[    0.654621] printk: console [ttyS0] enabled
[    0.663021] printk: bootconsole [early0] disabled
[    0.663021] printk: bootconsole [early0] disabled
[    0.686659] spi-nor spi0.0: mx25l6405d (8192 Kbytes)
[    0.691797] 6 fixed-partitions partitions found on MTD device spi0.0
[    0.698163] Creating 6 MTD partitions on "spi0.0":
[    0.703019] 0x000000000000-0x000000040000 : "u-boot"
[    0.709563] 0x000000040000-0x000000050000 : "u-boot-env"
[    0.716281] 0x000000050000-0x000000150000 : "kernel"
[    0.722698] 0x000000150000-0x0000007b0000 : "rootfs"
[    0.729072] mtd: device 3 (rootfs) set to be root filesystem
[    0.740631] 1 squashfs-split partitions found on MTD device rootfs
[    0.746859] 0x000000710000-0x0000007b0000 : "rootfs_data"
[    0.753758] 0x0000007b0000-0x0000007f0000 : "cfg"
[    0.759923] 0x0000007f0000-0x000000800000 : "eeprom"
[    0.769312] libphy: Fixed MDIO Bus: probed
[    1.140055] ag71xx 19000000.eth: Could not connect to PHY device. Deferring probe.
[    1.819403] libphy: ag71xx_mdio: probed
[    1.824275] libphy: ar8xxx-mdio: probed
[    1.870311] switch0: Atheros AR724X/AR933X built-in rev. 2 switch registered on mdio.0
[    1.963840] ag71xx 1a000000.eth: connected to PHY at fixed-0:00 [uid=00000000, driver=Generic PHY]
[    1.973809] eth0: Atheros AG71xx at 0xba000000, irq 5, mode: gmii
[    1.980249] i2c /dev entries driver
[    1.986830] NET: Registered protocol family 10
[    1.998373] Segment Routing with IPv6
[    2.002308] NET: Registered protocol family 17
[    2.006867] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[    2.019898] 8021q: 802.1Q VLAN Support v1.8
[    2.025510] PCI host bridge /ahb/apb/pcie-controller@180c0000 ranges:
[    2.032103]  MEM 0x0000000010000000..0x0000000013ffffff
[    2.037357]   IO 0x0000000000000000..0x0000000000000000
[    2.042862] PCI host bridge to bus 0000:00
[    2.046992] pci_bus 0000:00: root bus resource [mem 0x10000000-0x13ffffff]
[    2.053938] pci_bus 0000:00: root bus resource [io  0x0000]
[    2.059552] pci_bus 0000:00: root bus resource [??? 0x00000000 flags 0x0]
[    2.066365] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
[    2.074382] pci 0000:00:00.0: [168c:002a] type 00 class 0x028000
[    2.080502] pci 0000:00:00.0: reg 0x10: [mem 0x10000000-0x1000ffff 64bit]
[    2.087484] pci 0000:00:00.0: supports D1
[    2.091533] pci 0000:00:00.0: PME# supported from D0 D1 D3hot
[    2.098842] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 00
[    2.105567] pci 0000:00:00.0: BAR 0: assigned [mem 0x10000000-0x1000ffff 64bit]
[    2.450562] ag71xx 19000000.eth: connected to PHY at mdio.0:1f:04 [uid=004dd041, driver=Generic PHY]
[    2.461125] eth1: Atheros AG71xx at 0xb9000000, irq 4, mode: mii
[    2.548949] random: fast init done
[    2.563775] Freeing unused kernel memory: 10972K
[    2.568408] This architecture does not have kernel memory protection.
[    2.574901] Run /init as init process
[    3.477211] init: Console is alive
[    3.481468] init: - watchdog -
[    3.485131] init: Watchdog has previously reset the system
[    3.531849] kmodloader: loading kernel modules from /etc/modules-boot.d/*
[    3.609481] usbcore: registered new interface driver usbfs
[    3.615118] usbcore: registered new interface driver hub
[    3.620643] usbcore: registered new device driver usb
[    3.635784] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    3.645453] ehci-fsl: Freescale EHCI Host controller driver
[    3.654051] ehci-platform: EHCI generic platform driver
[    3.663823] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[    3.673704] init: - preinit -
[    4.144726] random: jshn: uninitialized urandom read (4 bytes read)
[    4.382312] random: jshn: uninitialized urandom read (4 bytes read)
[    4.446774] random: jshn: uninitialized urandom read (4 bytes read)
[    4.794400] eth0: link up (1000Mbps/Full duplex)
[    4.809092] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
Press the [f] key and hit [enter] to enter failsafe mode
Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level
[    9.043301] eth0: link down
[    9.065526] procd: - early -
[    9.069027] procd: - watchdog -
[    9.072722] procd: Watchdog has previously reset the system
[    9.748022] procd: - watchdog -
[    9.751426] procd: Watchdog has previously reset the system
[    9.757529] procd: - ubus -
[    9.774414] urandom_read: 5 callbacks suppressed
[    9.774426] random: ubusd: uninitialized urandom read (4 bytes read)
[    9.811712] random: ubusd: uninitialized urandom read (4 bytes read)
[    9.823570] procd: - init -
Please press Enter to activate this console.
[   10.869212] kmodloader: loading kernel modules from /etc/modules.d/*
[   11.328457] Loading modules backported from Linux version v5.15.8-0-g43e577d7a2cb
[   11.336050] Backport generated by backports.git v5.15.8-1-0-g83f664bb
[   11.425788] xt_time: kernel timezone is -0000
[   11.648684] PPP generic driver version 2.4.2
[   11.670533] NET: Registered protocol family 24
[   11.811145] ath9k 0000:00:00.0: Direct firmware load for ath9k-eeprom-pci-0000:00:00.0.bin failed with error -2
[   11.821359] ath9k 0000:00:00.0: Falling back to sysfs fallback for: ath9k-eeprom-pci-0000:00:00.0.bin
[   12.043020] urngd: v1.0.2 started.
[   12.214210] ath: phy0: Ignoring endianness difference in EEPROM magic bytes.
[   12.242905] ieee80211 phy0: Atheros AR9280 Rev:2 mem=0xb0000000, irq=13
[   12.346681] kmodloader: done loading kernel modules from /etc/modules.d/*
[   12.929166] random: crng init done
[   74.274667] eth0: link up (1000Mbps/Full duplex)
[   74.281065] br-lan: port 1(eth0) entered blocking state
[   74.286327] br-lan: port 1(eth0) entered disabled state
[   74.292128] device eth0 entered promiscuous mode
[   74.322938] br-lan: port 1(eth0) entered blocking state
[   74.328197] br-lan: port 1(eth0) entered forwarding state
[   74.461992] br-lan: port 2(eth1) entered blocking state
[   74.467251] br-lan: port 2(eth1) entered disabled state
[   74.473051] device eth1 entered promiscuous mode
[   75.299111] IPv6: ADDRCONF(NETDEV_CHANGE): br-lan: link becomes ready
[   77.540633] eth1: link up (100Mbps/Half duplex)
[   77.545233] br-lan: port 2(eth1) entered blocking state
[   77.550526] br-lan: port 2(eth1) entered forwarding state



BusyBox v1.34.1 (2021-12-16 15:27:53 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt SNAPSHOT, r18354+1-cc3e390a74
 -----------------------------------------------------
=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@OpenWrt:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br-lan state UP qlen 1000
    link/ether de:9f:db:6e:60:82 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br-lan state UP qlen 1000
    link/ether dc:9f:db:6e:60:82 brd ff:ff:ff:ff:ff:ff
4: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether dc:9f:db:6f:60:82 brd ff:ff:ff:ff:ff:ff
5: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether de:9f:db:6e:60:82 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global br-lan
       valid_lft forever preferred_lft forever
    inet6 fd34:fc4e:411c::1/60 scope global noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 fe80::dc9f:dbff:fe6e:6082/64 scope link 
       valid_lft forever preferred_lft forever

What I am not sure to understand is that I have defined 6 partitions in the dts.
But the kernel creates 7 of them:

[    0.691797] 6 fixed-partitions partitions found on MTD device spi0.0
[    0.698163] Creating 6 MTD partitions on "spi0.0":
[    0.703019] 0x000000000000-0x000000040000 : "u-boot"
[    0.709563] 0x000000040000-0x000000050000 : "u-boot-env"
[    0.716281] 0x000000050000-0x000000150000 : "kernel"
[    0.722698] 0x000000150000-0x0000007b0000 : "rootfs"
[    0.729072] mtd: device 3 (rootfs) set to be root filesystem
[    0.740631] 1 squashfs-split partitions found on MTD device rootfs
[    0.746859] 0x000000710000-0x0000007b0000 : "rootfs_data"
[    0.753758] 0x0000007b0000-0x0000007f0000 : "cfg"
[    0.759923] 0x0000007f0000-0x000000800000 : "eeprom"

And

root@OpenWrt:/# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00040000 00010000 "u-boot"
mtd1: 00010000 00010000 "u-boot-env"
mtd2: 00100000 00010000 "kernel"
mtd3: 00660000 00010000 "rootfs"
mtd4: 000a0000 00010000 "rootfs_data"
mtd5: 00040000 00010000 "cfg"
mtd6: 00010000 00010000 "eeprom"

rootfs_data is created at boot time by scanning rootfs to locate the free space after the end of the squashfs ROM. That space is allocated rootfs_data will be used for jffs2 overlay.

It looks like the wifi driver initialized OK. You need to enable the radio in /etc/config/wireless to have it go on the air.

Indeed, on my custom image, I have managed to use LuCi, enable the Wifi and connect my laptop to it.

On the Outdoor Plus snapshot, it seemed that luci was not running.

I have to stop the tests for today.

Thanks a lot for the help.

The snapshot builds (both initram and installable) don't include LuCI.

Ok I see. That's explained why I could not connect.

These first steps are very encouraging!

About my patch, is it OK for you that I create a separate dts like I did? I will rename the EEPROM partition art in order to stay closer to the Outdoor Plus.
In the Outdoor Plus dts, there are sub-partitions in the flash layout. Do you know why?

One thing missing is the WiFi firmware that is loaded from sysfs and not the EEPROM. I am not sure if this is an issue.

I have checked the mtd6 content at offset 4096 and the first bytes look similar than the firmware file located in /lib/firmware.

Then, when my initramfs image is functional, how do I flash my image into the flash to stay persistent?

I have loaded the Outdoor Plus ramdisk image and the Wifi failed to initialize (from the previous bootlog shared) and still the same with my new attempt today:

[   11.840793] ath9k 0000:00:00.0: Failed to initialize device
[   11.846497] ath9k: probe of 0000:00:00.0 failed with error -22

So my custom build with the patch posted in the first post seems a good start.

In the DTS, for the flash partition, do I have to match the stock partition scheme or create a new, ideal partition scheme for OpenWRT?

I have tried to use sysupgrade to install OpenWRT but it does not work. It seems I need a partition called firmware:

root@OpenWrt:/# sysupgrade /tmp/openwrt-snapshot-r18371\+1-5a4685cfa2-ath79-gene
ric-ubnt_unifi-ap-outdoor-squashfs-sysupgrade.bin
Cannot save config while running from ramdisk.
Sun Dec 19 13:42:15 UTC 2021 upgrade: Commencing upgrade. Closing all shell sessions.
Watchdog handover: fd=3
- watchdog -
Watchdog has previously reset the system
Sun Dec 19 13:42:16 UTC 2021 upgrade: Sending TERM to remaining processes ...
Sun Dec 19 13:42:21 UTC 2021 upgrade: Sending KILL to remaining processes ...
[  103.925294] sh (2900): drop_caches: 3
Sun Dec 19 13:42:27 UTC 2021 upgrade: Switching to ramdisk...
Sun Dec 19 13:42:31 UTC 2021 upgrade: Performing system upgrade...
[  107.746872] sh (2900): drop_caches: 3
Could not open mtd device: firmware
Can't open device for writing!
cat: write error: Broken pipe
sysupgrade aborted with return code: 256
[  107.800998] reboot: Restarting system