Debian: AIC8800 USB driver warnings, trace_printk, regulatory DB, and recommended driver version?

Started by user_2

user_2

Hello,

I am running Photonicat2 with Debian on kernel 6.12.45 / aarch64.

The device is generally working. The built-in USB Wi-Fi based on AIC8800D80 is able to connect successfully and keep network access. I am not reporting a completely broken Wi-Fi issue. I am trying to understand whether the current vendor driver/firmware stack is expected, or whether I should update to a newer driver package.

Current environment:

Device: Photonicat2
OS: Debian
Kernel: 6.12.45
Architecture: aarch64
Wi-Fi device: AIC8800D80 USB
USB ID: a69c:8d81 AICSemi AIC 8800D80
Driver package: aic8800-usb-dkms 3.0+git20240327.3561b08f-7
Firmware package: aic8800-firmware 3.0+git20240327.3561b08f-7
Wi-Fi interface: wlxb841d9ebe0c5
Connection status: working

The AIC driver initially produced a lot of kernel log output. I reduced the noise by setting:

options aic_load_fw_usb aicwf_dbg_level=1
options aic8800_fdrv_usb aicwf_dbg_level=1

This works after rebuilding initramfs and rebooting. LOGINFO, LOGDEBUG, LOGTRACE, and LOGDATA messages are now suppressed, while LOGERROR is still visible.

However, several warnings remain during boot.

  1. Kernel FORTIFY warning:
memcpy: detected field-spanning write (size 32) of single field
"&patch_info->adid_addrinf"
at .../aicbluetooth.c:1230 (size 4)

WARNING: CPU ... at aicbt_patch_info_unpack+0x8c/0xa0 [aic_load_fw]
Tainted: G O

The device still works after this warning, but the kernel reports an out-of-tree tainted module and a field-spanning write. Is this known and expected with the current AIC8800 USB driver, or is there a newer fixed driver/firmware package?

  1. trace_printk() warning:
trace_printk() being used. Allocating extra memory.
This means that this is a DEBUG kernel and it is unsafe for production use.
If you see this message and you are not debugging the kernel, report this immediately to your vendor!

I found trace_printk usage in the AIC driver source:

.../aic8800_fdrv/rwnx_tx.c

Is this intentional in the production driver package, or should I update to a newer build without debug tracing?

  1. Firmware/userconfig messages:
AICWFDBG(LOGERROR) invalid cmd: lvl_adj_5g_chan_42
AICWFDBG(LOGERROR) invalid cmd: lvl_adj_5g_chan_58
AICWFDBG(LOGERROR) invalid cmd: lvl_adj_5g_chan_106
AICWFDBG(LOGERROR) invalid cmd: lvl_adj_5g_chan_122
AICWFDBG(LOGERROR) invalid cmd: lvl_adj_5g_chan_138
AICWFDBG(LOGERROR) invalid cmd: lvl_adj_5g_chan_155

Wi-Fi still works. Are these messages harmless, or do they indicate a mismatch between firmware/userconfig and the driver parser?

  1. Regulatory warning:
cfg80211: loaded regulatory.db is malformed or signature is missing/invalid

ieee80211 phy0:
CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES

The AIC interface is self-managed. Is there a recommended regulatory configuration for Photonicat2 on Debian? Should I use a specific wireless-regdb package, firmware file, or country setting?

  1. Probe return code:
aic_load_fw 1-1.3:1.0: probe with driver aic_load_fw failed with error -1
aic_load_fw 1-1.3:1.1: probe with driver aic_load_fw failed with error -1
aic_load_fw 1-1.3:1.2: probe with driver aic_load_fw failed with error -1

This happens after firmware loading and USB re-enumeration. The final Wi-Fi interface still appears and works. Is this expected behavior, or should the driver return a different code for these interfaces?

My main questions:

  1. What is the currently recommended AIC8800 USB driver/firmware version for Photonicat2 on Debian kernel 6.12.45?
  2. Is there an official Radxa/Photonicat package newer than 3.0+git20240327.3561b08f-7 that should be used?
  3. Are the FORTIFY warning and trace_printk() warning known issues?
  4. Is it safe to continue using this driver if the Wi-Fi connection is stable?
  5. Is there a recommended fix for the regulatory DB warning and permissive custom regulatory rules?

I can provide full boot logs and exact package versions if needed.

Thank you.

user_2

Hello,

We tested the recommended stack on Photonicat2:

Kernel:
6.18.35 #2 SMP PREEMPT Thu Jun 18 18:12:26 JST 2026

Packages:
aic8800-firmware 5.0+git20260123.5f7be68d-4
aic8800-usb-dkms 5.0+git20260123.5f7be68d-4

Result:
Wi-Fi works.
DKMS modules are installed for 6.18.35.
aic_load_fw and aic8800fdrv debug level is 1.
LOGINFO/LOGDEBUG/LOGTRACE/LOGDATA are gone.
Previous memcpy/FORTIFY warning is gone.
Previous invalid cmd lvl_adj_5g_chan
* messages are gone.

Remaining messages after clean reboot:
AICWFDBG(LOGERROR) Read FW mem: 00120198
AICWFDBG(LOGERROR) 120198=177390
AICWFDBG(LOGERROR) 1201a0=177c00
** trace_printk() being used. Allocating extra memory. **
** CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES **

So the new stack improves the situation, but trace_printk and permissive regulatory warnings are still present.
Is there a newer AIC8800 driver build or recommended module parameter to disable these remaining warnings?

Thx very much for support!

user_2

Photonicat2: AIC8800 and kernel 6.18.35 update

This post is a full technical report and reproducible runbook for our Photonicat2 update. We tested the vendor-provided kernel and AIC8800 USB Wi-Fi driver bundle recommended in the support thread, preserved a local vendor package snapshot, verified the U-Boot boot chain and DKMS state before reboot, upgraded from kernel 6.12.45 to 6.18.35 and AIC8800 3.0 to 5.0, and then checked that USB Wi-Fi came back after reboot. The post includes the exact commands, pre-reboot gates, post-reboot results, remaining warnings, and rollback notes so that the procedure can be reviewed, reproduced, or audited.

Status: done
Started: 2026-06-29 09:41
Finished: 2026-06-29 11:48
Scope: Preserving the Photonicat vendor snapshot, checking the boot-chain and DKMS, updating kernel 6.12.45 to 6.18.35 and AIC8800 3.0 to 5.0, with USB Wi-Fi verification after reboot.
Related: server:photonicat2-debian | file:/srv/nvme_data/work/photonicat2/drivers/vendor-20260629 | file:/etc/kernel/postinst.d/zz-update-kernel | file:/etc/modprobe.d/99-aic8800-loglevel.conf | url:https://dl.photonicat.com/repos/linux-mainline/photonicat2/ | url:https://photonicat.com/forums/technical-support/debian-aic8800-usb-driver-warnings-trace_printk-regulatory-db-and-recommended-driver-version

0. Implementation map

  • Result: the update completed successfully; the system booted into 6.18.35, USB Wi-Fi wlxb841d9ebe0c5 came up and connected to SSID TT.
  • The AIC8800 stack was updated to 5.0+git20260123.5f7be68d-4; DKMS was built for 6.12.45 and 6.18.35.
  • Excessive journaling is absent: LOGINFO=0, LOGDEBUG=0, LOGTRACE=0, LOGDATA=0; the previous memcpy/FORTIFY and invalid cmd: lvl_adj_5g_chan_* did not recur after reboot.
  • linux-image-*-dbg and the downloaded linux-libc-dev_* were not installed; the old linux-image-6.12.45 and linux-headers-6.12.45 were kept as rollback scope.
  • Remaining items: trace_printk, permissive regulatory warning, and three vendor AICWFDBG(LOGERROR) Read FW mem messages persist; these are residual vendor warnings, not rollback blockers.

1. Initial state

Before the update:

Kernel: 6.12.45
Architecture: aarch64
aic8800-firmware: 3.0+git20240327.3561b08f-7
aic8800-usb-dkms: 3.0+git20240327.3561b08f-7

The working USB Wi-Fi used the modules:

/lib/modules/6.12.45/updates/dkms/aic8800_fdrv_usb.ko
/lib/modules/6.12.45/updates/dkms/aic_load_fw_usb.ko

The loglevel parameters had already been pinned through the actual DKMS names:

# /etc/modprobe.d/99-aic8800-loglevel.conf
options aic_load_fw_usb aicwf_dbg_level=1
options aic8800_fdrv_usb aicwf_dbg_level=1

Photonicat support recommended checking the new kernel and AIC8800 driver from the vendor repository:

https://dl.photonicat.com/repos/linux-mainline/photonicat2/

The point of the decision: do not continue local DKMS patching of the old aic8800-usb/3.0, but check the official kernel + headers + firmware + DKMS bundle.

2. Boot-chain nuance

Photonicat2 boots through U-Boot, not through ordinary GRUB selection. /boot/boot.cmd loads unversioned files:

load mmc ${devnum}:1 ${fdt_addr_r} rockchip.dtb
load mmc ${devnum}:1 ${kernel_addr_r} Image
load mmc ${devnum}:1 ${ramdisk_addr_r} initrd.img
booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}

Therefore, before reboot, it is necessary to check not only the installed packages, but also the active boot artifacts:

/boot/Image
/boot/initrd.img
/boot/rockchip.dtb

The system has a local hook:

/etc/kernel/postinst.d/zz-update-kernel

It updates the U-Boot artifacts after kernel package installation:

zcat ${LATEST_KERNEL_PATH} > /boot/Image.new
mv /boot/Image.new /boot/Image
mkimage ... -d ${LATEST_KERNEL_INITRD_PATH} /boot/initrd.img.new
mv /boot/initrd.img.new /boot/initrd.img
cp ${LATEST_KERNEL_DTB_PATH} /boot/rockchip.dtb

mkimage was installed:

/usr/bin/mkimage
mkimage version 2025.01

3. Vendor snapshot

All vendor repository files were saved locally:

/srv/nvme_data/work/photonicat2/drivers/vendor-20260629

Download command:

set -euo pipefail

BASE="/srv/nvme_data/work/photonicat2/drivers"
DEST="$BASE/vendor-20260629"
SRC_URL="https://dl.photonicat.com/repos/linux-mainline/photonicat2/"
SUPPORT_URL="https://photonicat.com/forums/technical-support/debian-aic8800-usb-driver-warnings-trace_printk-regulatory-db-and-recommended-driver-version"

mkdir -p "$DEST"
cd "$DEST"

cat > README.txt <<EOF
Photonicat2 vendor driver/kernel snapshot
=========================================

Snapshot date:
$(date -u '+%Y-%m-%d %H:%M:%S UTC')

Local path:
$DEST

Source repository:
$SRC_URL

Support thread:
$SUPPORT_URL

Purpose:
Vendor package snapshot for Photonicat2 kernel and AIC8800 USB Wi-Fi driver upgrade.

Important boot note:
This device boots unversioned /boot/Image, /boot/initrd.img and /boot/rockchip.dtb through U-Boot.
Before reboot after a kernel upgrade, verify these active boot artifacts explicitly.
EOF

wget \
  --recursive \
  --level=1 \
  --no-parent \
  --no-host-directories \
  --no-directories \
  --reject 'index.html*' \
  --execute robots=off \
  --server-response \
  --timestamping \
  "$SRC_URL" \
  2>&1 | tee "$DEST/download.log"

find . -maxdepth 1 -type f -name '*.deb' -printf '%P\0' \
  | sort -z \
  | xargs -0 sha256sum \
  > "$DEST/SHA256SUMS.vendor.txt"

{
  echo
  echo "Downloaded inventory:"
  find . -maxdepth 1 -type f -printf '%f\t%s bytes\n' | sort
  echo
  echo "SHA256SUMS.vendor.txt:"
  cat SHA256SUMS.vendor.txt
} >> README.txt

Saved .deb files:

aic8800-firmware_5.0+git20260123.5f7be68d-4_all.deb
aic8800-usb-dkms_5.0+git20260123.5f7be68d-4_all.deb
linux-headers-6.18.33_6.18.33-2_arm64.deb
linux-headers-6.18.35_6.18.35-2_arm64.deb
linux-image-6.18.33_6.18.33-2_arm64.deb
linux-image-6.18.33-dbg_6.18.33-2_arm64.deb
linux-image-6.18.35_6.18.35-2_arm64.deb
linux-image-6.18.35-dbg_6.18.35-2_arm64.deb
linux-libc-dev_6.18.33-2_arm64.deb
linux-libc-dev_6.18.35-2_arm64.deb

Only the following were used for the completed update:

aic8800-firmware_5.0+git20260123.5f7be68d-4_all.deb
aic8800-usb-dkms_5.0+git20260123.5f7be68d-4_all.deb
linux-headers-6.18.35_6.18.35-2_arm64.deb
linux-image-6.18.35_6.18.35-2_arm64.deb

Not installed:

linux-image-6.18.33*
linux-image-6.18.35-dbg_6.18.35-2_arm64.deb
linux-libc-dev_6.18.33-2_arm64.deb
linux-libc-dev_6.18.35-2_arm64.deb

4. Checking packages without installation

Before install, metadata, control scripts, and payload were checked:

set -euo pipefail

DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-20260629"
cd "$DEST"

for f in ./*.deb; do
  echo "===== $f ====="
  dpkg-deb -f "$f" Package Version Architecture Depends 2>/dev/null || true
  echo
done

INSPECT="$DEST/inspect"
mkdir -p "$INSPECT"

for deb in ./*.deb; do
  base="$(basename "$deb" .deb)"
  mkdir -p "$INSPECT/$base/control" "$INSPECT/$base/data"
  dpkg-deb -I "$deb" > "$INSPECT/$base/info.txt"
  dpkg-deb -e "$deb" "$INSPECT/$base/control"
  dpkg-deb -c "$deb" > "$INSPECT/$base/contents.txt"
  dpkg-deb -x "$deb" "$INSPECT/$base/data"
done

For linux-image-6.18.35, the following were confirmed to be present:

/boot/vmlinuz-6.18.35
/usr/lib/linux-image-6.18.35/rockchip/rk3576-photonicat2.dtb

For aic8800-usb-dkms, standard dh_dkms scripts and dependencies were confirmed:

Package: aic8800-usb-dkms
Version: 5.0+git20260123.5f7be68d-4
Depends: aic8800-firmware (= 5.0+git20260123.5f7be68d-4), dkms (>= 2.1.0.0)

dkms.conf builds three modules:

aic_load_fw_usb.ko
aic8800_fdrv_usb.ko
aic_btusb_usb.ko

Result: module names for Wi-Fi remained compatible with /etc/modprobe.d/99-aic8800-loglevel.conf.

5. Backup before install

Before the changes, /boot, the baseline, and AIC paths were saved:

set -euo pipefail

DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-20260629"
LOG="$DEST/install-logs-$(date '+%Y%m%d-%H%M%S')"
BACK="$DEST/preinstall-backup-$(date '+%Y%m%d-%H%M%S')"
mkdir -p "$LOG" "$BACK"

{
  echo '=== date ==='
  date -Is

  echo
  echo '=== uname ==='
  uname -a

  echo
  echo '=== dpkg baseline ==='
  dpkg -l | grep -E 'aic8800|linux-image|linux-headers|linux-libc-dev|dkms|u-boot-tools|initramfs-tools' || true

  echo
  echo '=== dkms baseline ==='
  dkms status || true

  echo
  echo '=== boot cmd ==='
  cat /boot/boot.cmd || true

  echo
  echo '=== boot files ==='
  ls -lah /boot

  echo
  echo '=== loaded AIC/cfg80211 modules ==='
  lsmod | grep -E 'aic|cfg80211' || true

  echo
  echo '=== current AIC module files ==='
  find /lib/modules/$(uname -r)/updates/dkms -maxdepth 1 -type f -name '*aic*' -print 2>/dev/null || true
} | tee "$BACK/baseline.txt" "$LOG/01-baseline-before-install.log"

cp -a /boot "$BACK/boot"

find /usr/src -maxdepth 1 -type d -name 'aic8800-usb*' -print > "$BACK/aic-src-paths.txt" || true
find /lib/modules/$(uname -r)/updates/dkms -maxdepth 1 -type f -name '*aic*' -print > "$BACK/aic-module-paths.txt" || true

tar --ignore-failed-read -czf "$BACK/aic8800-current-src-and-modules.tar.gz" \
  -T "$BACK/aic-src-paths.txt" \
  -T "$BACK/aic-module-paths.txt" \
  2>&1 | tee "$BACK/tar.log" || true

Package-level rollback was preserved: the old linux-image-6.12.45 and linux-headers-6.12.45 were not removed.

6. Installation

The installation was performed in stages: first AIC firmware/DKMS, then headers, then the kernel image. This reduces the risk of ending up with both a broken DKMS and a modified boot-chain at the same time.

6.1. Simulation

set -euo pipefail

DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-20260629"
LOG="$(find "$DEST" -maxdepth 1 -type d -name 'install-logs-*' | sort | tail -1)"
cd "$DEST"

apt-get -s install \
  ./aic8800-firmware_5.0+git20260123.5f7be68d-4_all.deb \
  ./aic8800-usb-dkms_5.0+git20260123.5f7be68d-4_all.deb \
  ./linux-headers-6.18.35_6.18.35-2_arm64.deb \
  ./linux-image-6.18.35_6.18.35-2_arm64.deb \
  2>&1 | tee "$LOG/00-apt-simulation-all.log"

Before continuing, check that the simulation does not remove:

linux-image-6.12.45
initramfs-tools
cryptsetup
dkms
u-boot-tools

6.2. Phase A: firmware + DKMS

set -euo pipefail

DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-20260629"
LOG="$(find "$DEST" -maxdepth 1 -type d -name 'install-logs-*' | sort | tail -1)"
cd "$DEST"

DEBIAN_FRONTEND=noninteractive apt-get install -y \
  ./aic8800-firmware_5.0+git20260123.5f7be68d-4_all.deb \
  ./aic8800-usb-dkms_5.0+git20260123.5f7be68d-4_all.deb \
  2>&1 | tee "$LOG/10-install-aic8800-firmware-dkms.log"

Check after Phase A:

set -euo pipefail

DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-20260629"
LOG="$(find "$DEST" -maxdepth 1 -type d -name 'install-logs-*' | sort | tail -1)"

{
  echo '=== dpkg aic ==='
  dpkg -l | grep -E 'aic8800'

  echo
  echo '=== dkms aic8800 ==='
  dkms status -m aic8800-usb || true

  echo
  echo '=== current kernel AIC modules on disk ==='
  find "/lib/modules/$(uname -r)/updates/dkms" -maxdepth 1 -type f -name '*aic*' \
    -print -exec modinfo {} \; 2>/dev/null \
    | grep -E 'filename:|version:|name:|vermagic:|depends:|parm:.*aicwf_dbg_level' || true

  echo
  echo '=== dkms make logs ==='
  find /var/lib/dkms/aic8800-usb -name make.log -type f -print -exec tail -80 {} \; 2>/dev/null || true
} | tee "$LOG/11-check-aic8800-dkms-current-kernel.log"

Result on the current kernel 6.12.45:

aic8800-usb/5.0+git20260123.5f7be68d-4, 6.12.45, aarch64: installed

The build completed with exit code: 0. The make.log contained warnings sprintf argument 3 overlaps destination object 'aic_fw_path' [-Wrestrict]; they did not stop DKMS.

6.3. Phase B: headers 6.18.35

set -euo pipefail

DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-20260629"
LOG="$(find "$DEST" -maxdepth 1 -type d -name 'install-logs-*' | sort | tail -1)"
cd "$DEST"

DEBIAN_FRONTEND=noninteractive apt-get install -y \
  ./linux-headers-6.18.35_6.18.35-2_arm64.deb \
  2>&1 | tee "$LOG/20-install-linux-headers-6.18.35.log"

Check after headers:

set -euo pipefail

DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-20260629"
LOG="$(find "$DEST" -maxdepth 1 -type d -name 'install-logs-*' | sort | tail -1)"

{
  echo '=== dkms status after headers ==='
  dkms status -m aic8800-usb || true

  echo
  echo '=== 6.18.35 AIC modules if already built ==='
  find /lib/modules/6.18.35/updates/dkms -maxdepth 1 -type f -name '*aic*' \
    -print -exec modinfo {} \; 2>/dev/null \
    | grep -E 'filename:|version:|name:|vermagic:|depends:|parm:.*aicwf_dbg_level' || true

  echo
  echo '=== dkms make logs ==='
  find /var/lib/dkms/aic8800-usb -name make.log -type f -print -exec tail -80 {} \; 2>/dev/null || true
} | tee "$LOG/21-check-dkms-after-headers.log"

In the actual update, modules for 6.18.35 had not appeared yet after installing headers. This was an acceptable intermediate state. The build for 6.18.35 happened after installing linux-image-6.18.35.

6.4. Phase C: kernel image 6.18.35

set -euo pipefail

DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-20260629"
LOG="$(find "$DEST" -maxdepth 1 -type d -name 'install-logs-*' | sort | tail -1)"
cd "$DEST"

DEBIAN_FRONTEND=noninteractive apt-get install -y \
  ./linux-image-6.18.35_6.18.35-2_arm64.deb \
  2>&1 | tee "$LOG/30-install-linux-image-6.18.35.log"

After image installation, DKMS was built for both kernels:

aic8800-usb/5.0+git20260123.5f7be68d-4, 6.12.45, aarch64: installed
aic8800-usb/5.0+git20260123.5f7be68d-4, 6.18.35, aarch64: installed

7. Gate before reboot

Reboot is allowed only after the full gate.

set -euo pipefail

DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-20260629"
LOG="$(find "$DEST" -maxdepth 1 -type d -name 'install-logs-*' | sort | tail -1)"

{
  echo '=== installed packages ==='
  dpkg -l | grep -E 'aic8800|linux-image|linux-headers|linux-libc-dev|dkms|u-boot-tools|initramfs-tools' || true

  echo
  echo '=== dkms status ==='
  dkms status || true

  echo
  echo '=== 6.18.35 AIC module files ==='
  find /lib/modules/6.18.35/updates/dkms -maxdepth 1 -type f -name '*aic*' \
    -print -exec modinfo {} \; 2>/dev/null \
    | grep -E 'filename:|version:|name:|vermagic:|depends:|parm:.*aicwf_dbg_level' || true

  echo
  echo '=== boot files ==='
  ls -lah /boot/Image /boot/initrd.img /boot/vmlinuz-6.18.35 /boot/initrd.img-6.18.35 /boot/rockchip.dtb 2>/dev/null || true

  echo
  echo '=== /boot/Image embedded version ==='
  grep -a -m1 'Linux version' /boot/Image || true

  echo
  echo '=== initrd formats ==='
  file /boot/initrd.img /boot/initrd.img-6.18.35 2>/dev/null || true

  echo
  echo '=== dumpimage /boot/initrd.img ==='
  dumpimage -l /boot/initrd.img 2>/dev/null || true

  echo
  echo '=== DTB compare ==='
  if cmp -s /boot/rockchip.dtb /usr/lib/linux-image-6.18.35/rockchip/rk3576-photonicat2.dtb; then
    echo 'DTB OK: /boot/rockchip.dtb matches rk3576-photonicat2.dtb'
  else
    echo 'DTB MISMATCH'
    sha256sum /boot/rockchip.dtb /usr/lib/linux-image-6.18.35/rockchip/rk3576-photonicat2.dtb || true
  fi

  echo
  echo '=== modprobe aic config ==='
  grep -R --line-number -E 'aic|aicwf_dbg_level' /etc/modprobe.d /lib/modprobe.d 2>/dev/null || true

  echo
  echo '=== initramfs contains aic modprobe config? ==='
  lsinitramfs /boot/initrd.img-6.18.35 2>/dev/null | grep -E 'aic|99-aic8800|modprobe' || true
} | tee "$LOG/40-pre-reboot-gate.log"

Minimum conditions for reboot:

/boot/Image contains target kernel version
/boot/initrd.img is u-boot legacy uImage
/boot/rockchip.dtb matches /usr/lib/linux-image-<kernel>/rockchip/rk3576-photonicat2.dtb
aic8800-usb DKMS is installed for target kernel
/lib/modules/<kernel>/updates/dkms contains aic_load_fw_usb.ko, aic8800_fdrv_usb.ko, aic_btusb_usb.ko
/etc/modprobe.d/99-aic8800-loglevel.conf is present in target initramfs

The actual gate passed:

/boot/Image contains Linux version 6.18.35
/boot/initrd.img: u-boot legacy uImage
/boot/initrd.img-6.18.35: Zstandard compressed data
DTB OK: /boot/rockchip.dtb matches rk3576-photonicat2.dtb
/etc/modprobe.d/99-aic8800-loglevel.conf present in initramfs

After that, the following was executed:

sync
sleep 2
systemctl reboot

8. Check after reboot

Check command:

set -euo pipefail

DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-20260629"
POST="$DEST/postreboot-check-$(date '+%Y%m%d-%H%M%S').log"

{
  echo '=== date ==='
  date -Is

  echo
  echo '=== kernel ==='
  uname -a
  uname -r

  echo
  echo '=== packages ==='
  dpkg -l | grep -E 'aic8800|linux-image|linux-headers' || true

  echo
  echo '=== dkms ==='
  dkms status -m aic8800-usb || true

  echo
  echo '=== loaded modules ==='
  lsmod | grep -E 'aic|cfg80211|bluetooth|btusb' || true

  echo
  echo '=== modinfo target modules ==='
  modinfo aic_load_fw_usb 2>/dev/null | grep -E 'filename:|version:|name:|vermagic:|parm:.*aicwf_dbg_level' || true
  modinfo aic8800_fdrv_usb 2>/dev/null | grep -E 'filename:|version:|name:|vermagic:|depends:|parm:.*aicwf_dbg_level' || true
  modinfo aic_btusb_usb 2>/dev/null | grep -E 'filename:|version:|name:|vermagic:|depends:' || true

  echo
  echo '=== runtime debug params ==='
  for p in \
    /sys/module/aic_load_fw/parameters/aicwf_dbg_level \
    /sys/module/aic8800_fdrv/parameters/aicwf_dbg_level \
    /sys/module/aic_btusb/parameters/aicwf_dbg_level
  do
    [ -e "$p" ] && printf '%s=' "$p" && cat "$p"
  done

  echo
  echo '=== network ==='
  ip link
  iw dev 2>/dev/null || true

  echo
  echo '=== AIC journal filtered ==='
  journalctl -b -k --no-pager \
    | grep -Ei 'aic|aicwf|trace_printk|regulatory|cfg80211|memcpy|fortify|LOGINFO|LOGDEBUG|LOGTRACE|LOGDATA|LOGERROR|invalid cmd' \
    | tee /tmp/aic8800-journal-current.txt || true

  echo
  echo '=== counters ==='
  for x in LOGINFO LOGDEBUG LOGTRACE LOGDATA LOGERROR trace_printk regulatory memcpy FORTIFY 'invalid cmd'; do
    printf '%-16s ' "$x"
    grep -ci "$x" /tmp/aic8800-journal-current.txt || true
  done
} | tee "$POST"

echo "$POST"

Actual result after reboot:

Linux photonicat2-debian 6.18.35 #2 SMP PREEMPT Thu Jun 18 18:12:26 JST 2026 aarch64 GNU/Linux
6.18.35

Packages after reboot:

aic8800-firmware  5.0+git20260123.5f7be68d-4
aic8800-usb-dkms  5.0+git20260123.5f7be68d-4
linux-image-6.12.45
linux-image-6.18.35
linux-headers-6.12.45
linux-headers-6.18.35

DKMS:

aic8800-usb/5.0+git20260123.5f7be68d-4, 6.12.45, aarch64: installed
aic8800-usb/5.0+git20260123.5f7be68d-4, 6.18.35, aarch64: installed

Runtime loglevel:

/sys/module/aic_load_fw/parameters/aicwf_dbg_level=1
/sys/module/aic8800_fdrv/parameters/aicwf_dbg_level=1

Wi-Fi:

wlxb841d9ebe0c5: UP, LOWER_UP
SSID: TT
channel 1 (2412 MHz), width: 20 MHz

Journal counters after reboot:

LOGINFO          0
LOGDEBUG         0
LOGTRACE         0
LOGDATA          0
LOGERROR         3
trace_printk     1
regulatory       3
memcpy           0
FORTIFY          0
invalid cmd      0

Remaining vendor messages:

AICWFDBG(LOGERROR)        Read FW mem: 00120198
AICWFDBG(LOGERROR)        120198=177390
AICWFDBG(LOGERROR)        1201a0=177c00
** trace_printk() being used. Allocating extra memory.  **
** CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES **

9. Standalone runbook for the next update

This block is intended for independently repeating the procedure. The commands are intended for a root shell. If the work is done through SSH and USB Wi-Fi is the only access path, reboot only after a successful pre-reboot gate. Otherwise, it is possible to get correctly installed packages and an inaccessible device at the same time.

9.1. Prepare variables and download vendor snapshot

set -euo pipefail

BASE="/srv/nvme_data/work/photonicat2/drivers"
STAMP="$(date '+%Y%m%d')"
DEST="$BASE/vendor-$STAMP"
SRC_URL="https://dl.photonicat.com/repos/linux-mainline/photonicat2/"
SUPPORT_URL="https://photonicat.com/forums/technical-support/debian-aic8800-usb-driver-warnings-trace_printk-regulatory-db-and-recommended-driver-version"

mkdir -p "$DEST"
cd "$DEST"

cat > README.txt <<EOF
Photonicat2 vendor driver/kernel snapshot
=========================================

Snapshot date:
$(date -u '+%Y-%m-%d %H:%M:%S UTC')

Local path:
$DEST

Source repository:
$SRC_URL

Support thread:
$SUPPORT_URL

Purpose:
Vendor package snapshot for Photonicat2 kernel and AIC8800 USB Wi-Fi driver upgrade.

Boot note:
Photonicat2 boots unversioned /boot/Image, /boot/initrd.img and /boot/rockchip.dtb through U-Boot.
Before reboot after kernel upgrade, verify these active boot artifacts explicitly.
EOF

wget \
  --recursive \
  --level=1 \
  --no-parent \
  --no-host-directories \
  --no-directories \
  --reject 'index.html*' \
  --execute robots=off \
  --server-response \
  --timestamping \
  "$SRC_URL" \
  2>&1 | tee "$DEST/download.log"

find . -maxdepth 1 -type f -name '*.deb' -printf '%P\0' \
  | sort -z \
  | xargs -0 sha256sum \
  > SHA256SUMS.vendor.txt

{
  echo
  echo "Downloaded inventory:"
  find . -maxdepth 1 -type f -printf '%f\t%s bytes\n' | sort
  echo
  echo "SHA256SUMS.vendor.txt:"
  cat SHA256SUMS.vendor.txt
} >> README.txt

9.2. Choose target kernel and target packages

For the known-good update, 6.18.35 and AIC 5.0+git20260123.5f7be68d-4 were used. For the next vendor drop, first check which versions were actually downloaded:

set -euo pipefail
cd "$DEST"

echo '=== available kernel images ==='
find . -maxdepth 1 -type f -name 'linux-image-[0-9]*_*.deb' ! -name '*-dbg_*' -printf '%f\n' | sort -V

echo
 echo '=== available headers ==='
find . -maxdepth 1 -type f -name 'linux-headers-[0-9]*_*.deb' -printf '%f\n' | sort -V

echo
 echo '=== available AIC packages ==='
find . -maxdepth 1 -type f \( -name 'aic8800-firmware_*.deb' -o -name 'aic8800-usb-dkms_*.deb' \) -printf '%f\n' | sort -V

Choose the target kernel. For the completed update:

TARGET_KERNEL="6.18.35"

Select files:

set -euo pipefail
cd "$DEST"

FW_DEB="$(find . -maxdepth 1 -type f -name 'aic8800-firmware_*_all.deb' -printf '%f\n' | sort -V | tail -1)"
DKMS_DEB="$(find . -maxdepth 1 -type f -name 'aic8800-usb-dkms_*_all.deb' -printf '%f\n' | sort -V | tail -1)"
HDR_DEB="$(find . -maxdepth 1 -type f -name "linux-headers-${TARGET_KERNEL}_*_arm64.deb" -printf '%f\n' | sort -V | tail -1)"
IMG_DEB="$(find . -maxdepth 1 -type f -name "linux-image-${TARGET_KERNEL}_*_arm64.deb" ! -name '*-dbg_*' -printf '%f\n' | sort -V | tail -1)"

for f in "$FW_DEB" "$DKMS_DEB" "$HDR_DEB" "$IMG_DEB"; do
  [ -n "$f" ] && [ -f "$f" ] || { echo "missing target package: $f" >&2; exit 1; }
done

printf 'FW_DEB=%s\nDKMS_DEB=%s\nHDR_DEB=%s\nIMG_DEB=%s\n' "$FW_DEB" "$DKMS_DEB" "$HDR_DEB" "$IMG_DEB"

FW_VER="$(dpkg-deb -f "$FW_DEB" Version)"
DKMS_VER="$(dpkg-deb -f "$DKMS_DEB" Version)"
[ "$FW_VER" = "$DKMS_VER" ] || { echo "AIC firmware/DKMS version mismatch: $FW_VER vs $DKMS_VER" >&2; exit 1; }

Do not install linux-image-*-dbg unless there is a separate kernel debugging task. Do not install linux-libc-dev_* for an ordinary kernel boot and AIC8800 DKMS check.

9.3. Capture baseline

set -euo pipefail
cd "$DEST"

LOG="$DEST/install-logs-$(date '+%Y%m%d-%H%M%S')"
BACK="$DEST/preinstall-backup-$(date '+%Y%m%d-%H%M%S')"
mkdir -p "$LOG" "$BACK"

{
  echo '=== date ==='
  date -Is

  echo
  echo '=== kernel ==='
  uname -a
  uname -r

  echo
  echo '=== packages ==='
  dpkg -l | grep -E 'aic8800|linux-image|linux-headers|linux-libc-dev|dkms|u-boot-tools|initramfs-tools' || true

  echo
  echo '=== dkms ==='
  dkms status || true

  echo
  echo '=== boot.cmd ==='
  cat /boot/boot.cmd || true

  echo
  echo '=== boot files ==='
  ls -lah /boot

  echo
  echo '=== AIC modules current kernel ==='
  find /lib/modules/$(uname -r)/updates/dkms -maxdepth 1 -type f -name '*aic*' -print 2>/dev/null || true
} | tee "$BACK/baseline.txt" "$LOG/01-baseline-before-install.log"

cp -a /boot "$BACK/boot"

9.4. Check package payload before installation

set -euo pipefail
cd "$DEST"

INSPECT="$DEST/inspect"
mkdir -p "$INSPECT"

for deb in "$FW_DEB" "$DKMS_DEB" "$HDR_DEB" "$IMG_DEB"; do
  base="$(basename "$deb" .deb)"
  mkdir -p "$INSPECT/$base/control" "$INSPECT/$base/data"
  dpkg-deb -I "$deb" > "$INSPECT/$base/info.txt"
  dpkg-deb -e "$deb" "$INSPECT/$base/control"
  dpkg-deb -c "$deb" > "$INSPECT/$base/contents.txt"
  dpkg-deb -x "$deb" "$INSPECT/$base/data"
done

IMG_BASE="$(basename "$IMG_DEB" .deb)"
DKMS_BASE="$(basename "$DKMS_DEB" .deb)"

grep -nE "\\./boot/vmlinuz-${TARGET_KERNEL}|rk3576-photonicat2\\.dtb" "$INSPECT/$IMG_BASE/contents.txt" || {
  echo "target linux-image does not contain expected vmlinuz or Photonicat2 DTB" >&2
  exit 1
}

cat "$INSPECT/$DKMS_BASE/control/control"
sed -n '1,220p' "$INSPECT/$DKMS_BASE/control/postinst" 2>/dev/null || true
find "$INSPECT/$DKMS_BASE/data" -name dkms.conf -type f -print -exec sed -n '1,220p' {} \;

Manually check in dkms.conf that the destination modules remain as expected:

aic_load_fw_usb
aic8800_fdrv_usb
aic_btusb_usb

If the Wi-Fi module names changed, /etc/modprobe.d/99-aic8800-loglevel.conf must be reviewed before reboot.

9.5. Check boot-chain hooks

set -euo pipefail

{
  echo '=== relevant kernel/initramfs hooks ==='
  grep -R --line-number -E 'mkimage|boot\.scr|boot\.cmd|/boot/Image|initrd\.img|rockchip|update-initramfs' \
    /etc/kernel /etc/initramfs-tools /usr/share/initramfs-tools 2>/dev/null || true

  echo
  echo '=== mkimage ==='
  command -v mkimage || true
  mkimage -V 2>/dev/null || true
} | tee "$LOG/02-boot-chain-hooks.log"

On Photonicat2, the hook /etc/kernel/postinst.d/zz-update-kernel must be present. If the hook is absent, the kernel package may install, but U-Boot will continue loading the old /boot/Image or an incorrect initrd. In this case, do not reboot until the active boot artifacts have been built and checked.

9.6. Simulation and staged install

set -euo pipefail
cd "$DEST"

apt-get -s install \
  "./$FW_DEB" \
  "./$DKMS_DEB" \
  "./$HDR_DEB" \
  "./$IMG_DEB" \
  2>&1 | tee "$LOG/00-apt-simulation-all.log"

Stop conditions in the simulation:

REMOVE linux-image-<current>
REMOVE initramfs-tools
REMOVE cryptsetup
REMOVE dkms
REMOVE u-boot-tools
unmet dependencies
held broken packages

If the simulation is normal:

DEBIAN_FRONTEND=noninteractive apt-get install -y \
  "./$FW_DEB" \
  "./$DKMS_DEB" \
  2>&1 | tee "$LOG/10-install-aic8800-firmware-dkms.log"

dkms status -m aic8800-usb | tee "$LOG/11-dkms-after-aic.log"

DEBIAN_FRONTEND=noninteractive apt-get install -y \
  "./$HDR_DEB" \
  2>&1 | tee "$LOG/20-install-headers.log"

dkms status -m aic8800-usb | tee "$LOG/21-dkms-after-headers.log"

DEBIAN_FRONTEND=noninteractive apt-get install -y \
  "./$IMG_DEB" \
  2>&1 | tee "$LOG/30-install-image.log"

9.7. Hard gate before reboot

set -euo pipefail

GATE="$LOG/40-pre-reboot-gate.log"

{
  echo '=== packages ==='
  dpkg -l | grep -E 'aic8800|linux-image|linux-headers|linux-libc-dev|dkms|u-boot-tools|initramfs-tools' || true

  echo
  echo '=== dkms ==='
  dkms status -m aic8800-usb || true

  echo
  echo '=== target AIC modules ==='
  find "/lib/modules/$TARGET_KERNEL/updates/dkms" -maxdepth 1 -type f -name '*aic*' \
    -print -exec modinfo {} \; 2>/dev/null \
    | grep -E 'filename:|version:|name:|vermagic:|depends:|parm:.*aicwf_dbg_level' || true

  echo
  echo '=== boot files ==='
  ls -lah /boot/Image /boot/initrd.img "/boot/vmlinuz-$TARGET_KERNEL" "/boot/initrd.img-$TARGET_KERNEL" /boot/rockchip.dtb 2>/dev/null || true

  echo
  echo '=== Image version ==='
  grep -a -m1 'Linux version' /boot/Image || true

  echo
  echo '=== initrd format ==='
  file /boot/initrd.img "/boot/initrd.img-$TARGET_KERNEL" 2>/dev/null || true
  dumpimage -l /boot/initrd.img 2>/dev/null || true

  echo
  echo '=== DTB compare ==='
  if cmp -s /boot/rockchip.dtb "/usr/lib/linux-image-$TARGET_KERNEL/rockchip/rk3576-photonicat2.dtb"; then
    echo 'DTB OK'
  else
    echo 'DTB MISMATCH'
    sha256sum /boot/rockchip.dtb "/usr/lib/linux-image-$TARGET_KERNEL/rockchip/rk3576-photonicat2.dtb" || true
  fi

  echo
  echo '=== modprobe config ==='
  grep -R --line-number -E 'aic|aicwf_dbg_level' /etc/modprobe.d /lib/modprobe.d 2>/dev/null || true

  echo
  echo '=== target initramfs modprobe config ==='
  lsinitramfs "/boot/initrd.img-$TARGET_KERNEL" 2>/dev/null | grep -E 'aic|99-aic8800|modprobe' || true
} | tee "$GATE"

Reboot is forbidden if at least one condition is not met:

dkms status does not show target kernel as installed
/lib/modules/<target>/updates/dkms has no aic_load_fw_usb.ko or aic8800_fdrv_usb.ko
/boot/Image does not contain target kernel version
/boot/initrd.img is not U-Boot legacy uImage
/boot/rockchip.dtb does not match rk3576-photonicat2.dtb from target linux-image
/etc/modprobe.d/99-aic8800-loglevel.conf is missing from target initramfs

If the gate is green:

sync
sleep 2
systemctl reboot

9.8. If the hook did not update /boot before reboot

The normal path is to let /etc/kernel/postinst.d/zz-update-kernel do this automatically. This fallback is needed only if the package installed, but the pre-reboot gate shows an old /boot/Image or an incorrect /boot/initrd.img.

set -euo pipefail

cp -a /boot "$BACK/boot-before-manual-active-artifacts"

update-initramfs -u -k "$TARGET_KERNEL"

zcat "/boot/vmlinuz-$TARGET_KERNEL" > /boot/Image.new
mv /boot/Image.new /boot/Image

mkimage -A arm -O linux -T ramdisk -C none -a 0 -e 0 \
  -d "/boot/initrd.img-$TARGET_KERNEL" \
  /boot/initrd.img.new
mv /boot/initrd.img.new /boot/initrd.img

cp "/usr/lib/linux-image-$TARGET_KERNEL/rockchip/rk3576-photonicat2.dtb" /boot/rockchip.dtb

After manual rebuild, it is mandatory to repeat the hard gate from the previous section. Do not reboot without repeating the gate.

9.9. Post-reboot check

set -euo pipefail

DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-$(date '+%Y%m%d')"
[ -d "$DEST" ] || DEST="/srv/nvme_data/work/photonicat2/drivers/vendor-20260629"
POST="$DEST/postreboot-check-$(date '+%Y%m%d-%H%M%S').log"

{
  echo '=== date ==='
  date -Is

  echo
  echo '=== kernel ==='
  uname -a
  uname -r

  echo
  echo '=== packages ==='
  dpkg -l | grep -E 'aic8800|linux-image|linux-headers' || true

  echo
  echo '=== dkms ==='
  dkms status -m aic8800-usb || true

  echo
  echo '=== loaded modules ==='
  lsmod | grep -E 'aic|cfg80211|bluetooth|btusb' || true

  echo
  echo '=== modinfo AIC ==='
  modinfo aic_load_fw_usb 2>/dev/null | grep -E 'filename:|version:|name:|vermagic:|parm:.*aicwf_dbg_level' || true
  modinfo aic8800_fdrv_usb 2>/dev/null | grep -E 'filename:|version:|name:|vermagic:|depends:|parm:.*aicwf_dbg_level' || true
  modinfo aic_btusb_usb 2>/dev/null | grep -E 'filename:|version:|name:|vermagic:|depends:' || true

  echo
  echo '=== runtime debug params ==='
  for p in \
    /sys/module/aic_load_fw/parameters/aicwf_dbg_level \
    /sys/module/aic8800_fdrv/parameters/aicwf_dbg_level \
    /sys/module/aic_btusb/parameters/aicwf_dbg_level
  do
    [ -e "$p" ] && printf '%s=' "$p" && cat "$p"
  done

  echo
  echo '=== network ==='
  ip link
  iw dev 2>/dev/null || true

  echo
  echo '=== AIC journal filtered ==='
  journalctl -b -k --no-pager \
    | grep -Ei 'aic|aicwf|trace_printk|regulatory|cfg80211|memcpy|fortify|LOGINFO|LOGDEBUG|LOGTRACE|LOGDATA|LOGERROR|invalid cmd' \
    | tee /tmp/aic8800-journal-current.txt || true

  echo
  echo '=== counters ==='
  for x in LOGINFO LOGDEBUG LOGTRACE LOGDATA LOGERROR trace_printk regulatory memcpy FORTIFY 'invalid cmd'; do
    printf '%-16s ' "$x"
    grep -ci "$x" /tmp/aic8800-journal-current.txt || true
  done
} | tee "$POST"

echo "$POST"

Success criteria:

uname -r equals target kernel
USB Wi-Fi interface is present and associated
DKMS installed for target kernel
modinfo points to /lib/modules/<target>/updates/dkms/*
aic_load_fw and aic8800_fdrv aicwf_dbg_level are 1
LOGINFO/LOGDEBUG/LOGTRACE/LOGDATA are 0

10. Rollback notes

The old kernel was kept as a package-level rollback:

linux-image-6.12.45
linux-headers-6.12.45

But there is no automatic GRUB-like selection. After an unsuccessful reboot, recovery may require local/serial access and restoring unversioned files from backup:

/boot/Image
/boot/initrd.img
/boot/rockchip.dtb
/boot/boot.cmd
/boot/boot.scr

If the gate failed before reboot, active boot artifacts can be rolled back from the saved backup without rebooting:

set -euo pipefail

# example: BACK=/srv/nvme_data/work/photonicat2/drivers/vendor-20260629/preinstall-backup-YYYYmmdd-HHMMSS
[ -n "${BACK:-}" ]
[ -d "$BACK/boot" ]

cp -a "$BACK/boot/Image" /boot/Image
cp -a "$BACK/boot/initrd.img" /boot/initrd.img
cp -a "$BACK/boot/rockchip.dtb" /boot/rockchip.dtb
cp -a "$BACK/boot/boot.cmd" /boot/boot.cmd 2>/dev/null || true
cp -a "$BACK/boot/boot.scr" /boot/boot.scr 2>/dev/null || true
sync

If reboot has already been performed and the device does not come online, further rollback can be done only through a local console or serial. Until stabilization, do not remove 6.12.45 and do not clean up the vendor snapshot.

11. Final assessment

The update has positive expected value and was left in operation. It solved the main operational problem and removed part of the vendor defects in the old driver stack. The remaining trace_printk, permissive regulatory warning, and three LOGERROR messages are classified as residual vendor warnings, not as a regression.

Want to reply to this topic?

Sign in to participate

Don't have an account? Sign up