Keep the product-specific syscfg writes and restore all patch uploads, including patch configuration. Derive the syscfg condition from the current product readback without retaining a loader flag.
Update regression checks for full patch uploads on both products and syscfg write failures, and document the reported hardware results and remaining validation.
Derive the FMAC-only profile from each device readback instead of a module-global latch. A regular D80 must still load its patches after another adapter reports product 0x8820. Reject a busy connect with EBUSY without resetting the state of an operation already in flight.
Extracted-function tests cover alternating devices, reprobe, cache setup, configuration errors and unchanged busy states. All three modules build against Linux 6.17 headers. Hardware retest of this revision and Bluetooth remain pending.
Two independent fixes found on a UGREEN a69c:5723 adapter
(chip_id=7, chip_mcu_id=1, product_id=0x8820, issue #118):
1) The firmware boots and answers every configuration request, but never
confirms MM_START_REQ, so the MAC never starts and wlan0 stays unusable
(the symptom reported in #79). The Windows loader (aicloadfw.sys) handles
product 0x8820 differently: it writes 0x40500010 = 0x2, masked-writes
0x40506024 (mask 0xff) = 0xdf, and uploads only the FMAC firmware without
the adid/patch/patch-table/patch-config layer. Mirror that behaviour,
gated on product_id == 0x8820 so that other D80 revisions (for example the
a69c:572f from #58) keep uploading the patch layer and stay unaffected.
The existing MCU1 cache fix (0x40100020 |= 0x1) is kept for both.
2) rwnx_cfg80211_connect() returned 0 when the state machine was already
CONNECTING/DISCONNECTING, without ever reporting a result. cfg80211 then
keeps wdev->conn allocated and rejects every later NL80211_CMD_CONNECT
with -EALREADY, so the driver's connect op is never called again and
NetworkManager loops on the password prompt ("associating -> disconnected"
every 5 s) with no driver activity at all. Report the failure instead:
reset the state and return -EBUSY.
Tested on Ubuntu 26.04 / 7.0.0-14-generic: 5 GHz association, DHCP, IPv6
SLAAC and internet traffic all work, and it survives reboot and USB re-plug.
Full logs and analysis: #118
Backport main commit 2c4ab4b421 to
legacy-mcu1, preserving the branch's MCU1 firmware and loader profile.
Adapt the probe status link ID, probe_peer callback and input cookie APIs;
retain cfg80211-assigned cookies through asynchronous completion paths.
Add an isolated native-kernel build check and record the regression results.
The original branch reproduces all six reported errors on 7.3-rc3. The fix
builds all three modules and passes MODPOST on upstream 7.3 final and Ubuntu
7.3-rc3, 7.2 and 6.17 headers. The final-release module_layout CRCs match
the fully built test kernel. Hardware operation has not been tested.
Refs #111
Co-authored-by: MastaG <badouri.g@gmail.com>
Link issue #110 and keep the report scoped to the tested device, matched legacy driver/firmware, standard btusb and reported reboot/reconnection checks.
(cherry picked from commit 5327c777d0)
Document matching kernel headers, pacman dependencies, repository checkout, mode-switch destination creation and MCU1 branch selection. Distinguish missing DKMS builds from stale module indexes and firmware-loader IDs from working interfaces. Correct the installer support claim and explain the NetworkManager connectivity penalty with its upstream reference.
Keeps the contributor-reported Lukton DQ-211 results scoped to that unit. Validation: all Bash examples parse, local links resolve, and commands were checked against the repository installer, Makefile, AUR packaging and upstream documentation. Follow-up corrections for #109; no Arch hardware test is claimed.
(cherry picked from commit 1b071be3e1)
Add INSTALL_ARCH.md covering installation on Arch-based distributions,
validated on a Lukton DQ-211 (AIC8800D80, Pandora 88M80 clone) under
CachyOS with kernels 7.2.0-1-cachyos and 6.18.42-1-cachyos-lts.
The notes cover the AUR/DKMS path, the manual build path, and two gotchas
that are not documented for these distros:
- the AUR package ships aic.rules but not /etc/usb_modeswitch.d/1111:1111,
so the mode switch silently does nothing without it;
- the DKMS modules live under updates/dkms/ and need depmod -a before
modprobe aic8800_fdrv can find them.
Also document that aic_load_fw already carries the usb:vA69Cp8D80d* alias,
so no modules-load.d entry is required, plus NetworkManager route-metric
notes for preferring the dongle over the onboard radio.
README: link the new notes from the Installation Steps section.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
(cherry picked from commit 68498ff48c)
Netdev close normally runs inside platform teardown while drvdata remains valid. Document the guards as defense for missing-bus paths and sequential repeated cleanup, without claiming a proven upstream use-after-free or concurrent teardown safety. Clarifies #106.
Install Arch dependencies using the existing package database and explain how to recover from stale package metadata. Avoid errexit on the first firmware count, handle Secure Boot prompt EOF as cancellation, propagate error traps into functions, and reject empty firmware sources before modifying installed firmware.
Validation: eight isolated installer regression tests pass; the original installer fails the affected cases. Bash syntax and ShellCheck error-level checks pass. Fixes#100. Addresses the confirmed findings in #108; other audit suggestions remain separate.
Keep the internal monitor-channel API independent of kernel versions and select a correctly typed cfg80211 adapter at compile time. This covers Ubuntu 6.8.0-147 and stable/backports without release-string heuristics or function-pointer casts.
Validation: reproduced the original failure on Ubuntu 6.8.0-147; all three modules build on 6.8.0-146, 6.8.0-147 and 6.17.0-14. Fixes#107.
Both reader families do `bus_if = dev_get_drvdata(dev)` and immediately
dereference bus_if->bus_priv.usb. With the ordering from the parent
commit the corresponding threads (cmd tx, bustx) are quiesced before
drvdata is cleared, so these guards should be unreachable in the current
call graph — explicit belt-and-suspenders per the #103 reader audit,
covering both CONFIG_USB_TX_AGGR txdata variants and txmsg against any
future or premature caller.
Per review: distinguish the tested hardware revision (this unit:
chip_id=7, chip_sub_id=1, chip_mcu_id=1) from any assumption that every
device with this VID/PID is MCU1. The ID-table entry only routes to the
DC path; mcu gating is runtime.
In the vif_started==0 branch rwnx_close() evaluates
usbdev->bus_if->state without checking usbdev. On the disconnect path
aicwf_bus_deinit() runs before netdev close, so close observes usbdev==NULL
and oopses (CR2=0x8, pinned by disassembly relocation rwnx_send_reset;
field symptom: host hard-hang on physical unplug, reproduced x8 in the lab
with this stack -> BUG=0 after this guard). In the unpatched tree the same
expression reads a still-allocated DOWN-state object in the synchronous
disconnect path — our earlier "latent UAF" phrasing is retracted (no
freed-object access was observed or proven). Covers USB and SDIO variants.
Both maintained branches ship no binding for this PID: the TP entries in
aicwf_usb_id_table cover 0x014b (Mercury) and 0x014e only, and
aicwf_usb_chipmatch only matches pid == 0x88dc for the DC family, so the
device is ignored by the interface table and rejected by chipmatch even
if force-bound.
- add USB_PRODUCT_ID_TP_AIC8800DC (0x0147)
- match it in aicwf_usb_id_table and in aicwf_usb_chipmatch (DC chipid)
Verified on legacy-mcu1 @ b7a476c (arch1-2 kernel7.2.8, VFIO lab):
clean baseline probe shows BIND=NONE (no driver claims 1-10); with this
commit the interface binds and the issue71 loader profile boots the
chip (Firmware Version: zh Aug 08 2022 ... gcf79227 -> wlan0 created).
Review-driven rework of the teardown lifetime (shenmintao/aic8800d80#103):
- aicwf_bus_deinit(): keep the entry NULL guard (sequential double-deinit
on probe-failure paths), but move dev_set_drvdata(dev, NULL) to the END
of completed cleanup — after URB cancel, platform/rx/cmd teardown and the
kthread_stop() join of bustx_thread. The previous placement (right after
bus_stop) opened a real race: aicwf_usb_bus_txdata() re-reads drvdata and
runs from bustx_thread, which is joined only later, and the TX-path state
check is not a synchronization point. With the new ordering every cleanup
callback and TX reader observes a non-NULL pointer throughout.
- aicwf_usb_bus_stop(): NULL-check bus_if before dereferencing
bus_if->bus_priv.usb (defense in depth; historical host oops
RIP aicwf_usb_bus_stop+0x11 on probe-failure rollback).
Verification (isolated VFIO lab, one 2357:0147 unit, sustained ping -f):
a test-only fault-injection build (not included) reaches the repeated-deinit
path and prints "already deinitialized, skip" with BUG=0; missing-firmware
init failure runs one clean deinit; physical unplug x8, sysfs unbind and
authorized cold cycles, disconnect during scanning and during connection
establishment, ifdown/up x5, rmmod/insmod x3 -> BUG=0 throughout (only the
pre-existing WARNs at rwnx_main.c:1529 and rwnx_cfg80211_disconnect:3328).
Copy src/LICENSE verbatim from radxa-pkg/aic8800 commit
969601fd69b5c33f965558c9e90633067733e8c1 and document its provenance.
Upstream copyright metadata assigns GPL-2 to driver sources and the
same license to driver patches; GPL-3+ applies to Radxa packaging.
Refs #101.
Validation: byte-for-byte upstream license comparison and git diff --check.
27af5ad added the CFG80211_VERSION make variable for OpenWrt builds that
use a newer mac80211 backport than the target kernel, but it is only
described in a Makefile comment. Document how to pass it from an OpenWrt
package Makefile, link the notes from the installation steps, and add
the build script and the kernel/backports combinations verified for
issue #94.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The spec used the pinned commit hash as Version, and rpm does not order
hashes by commit history: 51b7b6e sorts after c8327ea, and 13baa9b after
e93a7d2, so a newer snapshot could be treated as an older package.
Version snapshots as 1.0.0^<date>git<commit>, where 1.0.0 is the DKMS
PACKAGE_VERSION, and add Epoch 1 so every snapshot sorts after all of
the earlier hash versions. Checked with rpm 4.18: the spec parses and
the new EVR compares newer than every previous Version.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The legacy spec still pins 51b7b6e, which predates 44748e1 ("fix:
support Linux 7.2 cfg80211 API"). Against Linux 7.2 headers that
snapshot fails with an implicit declaration of strncpy() and an
incompatible cfg80211_ops::remain_on_channel initializer, the same
failure dd74ae6 fixed for the main package.
Pin c8327ea, which also carries the fixes synchronized from main, and
reset Release for the new snapshot. The pinned tree builds all three
modules against 7.2.6 headers.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Build the existing monitor transmit path by default. Validate the radiotap header before parsing it and align the transmit prototype with netdev_tx_t.
Hardware-tested-by: jkroepke (GitHub)
cfg80211_ops.set_monitor_channel() gained a "struct net_device *dev"
parameter in mainline 6.13, and the change was backported to the 6.12
stable series starting with 6.12.101. Debian 13 ships 6.12.107, so the
existing ">= 6.13.0" guards select the old prototype there and the build
fails with -Wincompatible-pointer-types:
rwnx_main.c: error: initialization of
'int (*)(struct wiphy *, struct net_device *, struct cfg80211_chan_def *)'
from incompatible pointer type
'int (*)(struct wiphy *, struct cfg80211_chan_def *)'
[-Wincompatible-pointer-types]
This is the failure reported in #96 for Debian 13 trixie.
Introduce AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV in rwnx_compat.h,
defined at AICWF_CFG80211_VERSION_CODE >= 6.12.101, and gate the nine
set_monitor_channel call sites on it instead of comparing against 6.13.0.
The threshold covers both the 6.12 backport and mainline 6.13, while
kernels 6.11 and earlier 6.12.x keep the old prototype. The check now
lives in one place and follows the existing AICWF_CFG80211_VERSION_CODE
convention, so OpenWrt builds can override it with CFG80211_VERSION.
The MODULE_IMPORT_NS guard at rwnx_main.c that also checks 6.13.0 is
unrelated and is left untouched.
Verified with clean builds against linux-headers 5.15.0-191,
6.1.0-53, 6.8.0-139, 6.11.0-8 and 6.12.107+deb13.
Allow CFG80211_VERSION to select wireless API signatures independently of the target kernel. Keep native kernel builds on their existing version checks.
Also guard the WEXT-only label and replace overlapping firmware path formatting with bounded appends so OpenWrt builds pass with Werror.
Validated all three modules against OpenWrt Linux 6.12.94 with backports 6.18.26, plus native 6.11, 6.17 and 7.2 headers. Refs #94.
Disable CONFIG_USB_ALIGN_DATA and enable CONFIG_USB_NO_TRANS_DMA_MAP
when CONFIG_ARCH_SUN60IW2P1 is set, following the upstream USB controller
workaround. Preserve the current defaults on other platforms.
Source: radxa-pkg/aic8800 commit 33f19ba,
fix-usbc1-controller-wifi-rate-of-sun60iw2p1.patch.
Validation: GNU make resolves the expected settings for both platform
branches; Linux 6.14, 6.17 and 7.2 module builds succeeded. No SUN60IW2P1
hardware was available for runtime validation.
Linux 7.1 moved action_code outside tdls_discover_resp. Reserve both
category and action_code bytes before the response body so appending an
IE does not overwrite the capability field.
Sync the USB hunk from radxa-pkg/aic8800 commit
bd01abe95bc83c4708dd1d117e27424ee41cc747.
Validation: Linux 6.14, 6.17 and 7.2 module builds succeeded. A focused
frame construction check detects the original one-byte overwrite and
passes with this change. Hardware TDLS operation remains untested.
This adapter uses the AIC8800D80 chipset and was previously not
matched by the fdrv probe. Add vendor/product IDs so the driver
binds and both Wi-Fi and Bluetooth (via standard btusb) work.
Tested on Linux 7.1.6 with TP-Link AX900 TL-XDN7000H.
Do not send monitor frames through the normal data path when simultaneous monitor/data support is disabled. Handle monitor skb allocation failures without dereferencing NULL or dropping the original combined-mode frame.
Fixes#83
(cherry picked from commit 531d16c4d6)
Read the first kernel argument from ARM_r0 on 32-bit ARM, where regs_get_kernel_argument() is unavailable.
Fixes#82
(cherry picked from commit 40f00e69af)