Follow up issue #117: use each module chip enum and the real Wi-Fi device, preserve flat-layout fallback on missing files, and handle allocation and size failures. Based on the report by ggorbi99-dev.
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.
Backport the issue #117 loader fix, declaring the 80 firmware/configuration files actually shipped by legacy-mcu1 rather than the main firmware set. Preserve the existing V3 binaries and loader profiles.
All three modules build against Linux 6.17 headers; inventory, built-module metadata and extracted probe error/re-enumeration regression checks pass. Hardware boot validation remains pending.
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>
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.
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.
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).
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)
Sync WiFi driver, firmware, and DKMS configuration from the bluetooth
branch (which itself is radxa USB driver_fw + Linux 6.16/6.17/6.19
kernel compat). aic_btusb and Bluetooth-specific install.sh logic
are intentionally excluded from main.
Driver updates:
- Add Linux kernel 6.12-6.19 compatibility support
- Add Linux 6.16 timer_container_of and wakelock API support
- Add Debian 6.1.0-26 backport support
- Add USB device ID 368b:8d81 support
- Add AIC8800DW device support
- Add TP-Link Archer TX1U Nano support (USB_VENDOR_ID_TENDA_V2:0x0110)
- Add TENDA series device support (U2, U11, U11 PRO)
- Add AIC8800FC_CUS1-6 series support
- Add AIC8800M80_CUS0-8 series support
- Add UGREEN AIC8800D80 adapter support
- Add Mercury (TP-Link OEM) support
- Allow 1 or 3 USB interfaces (BT-disabled SKUs report 1)
New compat modules:
- aicwf_compat_8800d80n.{c,h}
- aicwf_compat_8800dln.{c,h}
Firmware:
- New: fw/aic8800/, fw/aic8800D80N/, fw/aic8800D80X2/, fw/aic8800DLN/
- Updated: fw/aic8800D80/, fw/aic8800DC/
install.sh:
- Loop over all fw/aic8800* variants instead of hard-coding aic8800D80
- Install usb_modeswitch/1111_1111 config for "Pandora" clone adapter
- Verify firmware install by counting variants
dkms.conf: pass KDIR explicitly to make for cross-kernel builds.
Excluded from this commit (BT-only, kept on bluetooth branch):
- drivers/aic8800/aic_btusb/
- modprobe/aic8800-bt.conf
- diagnose_bt.sh
- install.sh btusb auto-load / hciconfig / bluez status checks
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Device 368b:8d84 is an AIC 8800D80 variant not included in the USB
device table. Add it as AIC8800M80_CUS0 alongside the other M80 CUS
variants; it maps to PRODUCT_ID_AIC8800D81 like its siblings.
Tested on kernel 6.19.8-arch1 with a physical dongle (Bus 001 Device
005: ID 368b:8d84 AICSemi AIC 8800D80).
Added USB VID/PID for TP-Link vendor (0x2357) and Mercury product (0x014b)
to support WiFi adapters that re-enumerate with these IDs after firmware
loading. The device is recognized as AIC8800D81 chip with RX aggregation.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>