Unplugging the adapter while the interface is connecting or disconnecting
prints a spurious kernel warning:
rwnx_close connecting or disconnecting, not finish
WARNING: CPU: ... rwnx_close+0x96/0x3f0 [aic8800_fdrv]
rwnx_close() waits up to 4 seconds for drv_conn_state to leave
CONNECTING/DISCONNECTING, but that state only changes when the firmware
answers the pending request. During USB teardown the bus is already down
by the time rwnx_close() runs, and rwnx_send_msg() drops the message and
returns 0, so the confirmation never arrives. The wait therefore always
runs its full timeout and fires WARN_ON(1) for a condition that cannot be
satisfied.
Skip both waits when the bus is down, using the same condition already
used a few lines below in the vif_started path. This removes the wait
itself, not just the warning: previously teardown blocked for up to 4 (and
2) seconds waiting on a dead bus.
Reproduced on 6.12.107+deb13 with an AIC8800D80: unplug while connected
fires the warning on main and produces none with this change, while the
replug path still re-enumerates and restores Wi-Fi and Bluetooth. Builds
on 5.15.0-191, 6.1.0-53, 6.8.0-139, 6.11.0-8 and 6.12.107+deb13 with no
new warnings.
7.3 lands the last part of a two-commit series that converts several
cfg80211_ops cookie parameters from driver-invented output values to
values cfg80211 pre-assigns and passes in as input, and renames
probe_client to probe_peer. Building against 7.3 fails with 5 errors:
- cfg80211_probe_status() gained an MLO link_id parameter between cookie
and acked (kernel commit 010e955c203e). This driver has no MLO
support; -1 is the documented value for non-MLO.
- cfg80211_ops::probe_client was renamed to probe_peer (4ab9b637b94a).
- cfg80211_ops::mgmt_tx, ::remain_on_channel and ::probe_peer all
changed their cookie parameter from u64 * to u64 (914781c72813):
cfg80211 now pre-assigns the cookie before calling the driver instead
of the driver inventing one and returning it through the pointer.
The cookie change is more than a type fix. This driver invents its
mgmt_tx/remain_on_channel/probe_peer cookies from a skb pointer, an
internal roc_cookie_cnt counter, and an internal probe_id counter
respectively, and separately re-derives "the same" value later when
reporting completion. Once cfg80211 assigns the cookie itself, the
completion report must echo back the value cfg80211 gave the driver.
Two of the three ops are thin wrappers around a lower-level helper that
is also called from a purely-internal path with no cfg80211-assigned
cookie to honor: rwnx_start_mgmt_xmit() is reused by TDLS, and
rwnx_cfg80211_remain_on_channel_() starts the internal RoC from inside
mgmt_tx. Each of those helpers gets a bool (use_given_cookie / the
existing mgmt_roc_flag) so the internal callers keep inventing a cookie
exactly as before on every kernel, while the cfg80211 op wrappers honor
the pre-assigned value on 7.3+ and thread it through to the completion
report. probe_peer has no helper and no internal caller; the op stores
the cookie itself.
- rwnx_start_mgmt_xmit() gains use_given_cookie; the resulting cookie is
stored in a new rwnx_sw_txhdr::cookie and echoed back via
cfg80211_mgmt_tx_status(). Because sw_txhdr comes from a kmem_cache
and is never zeroed, every one of the five allocation sites
initialises the field -- to the skb pointer, which is exactly what the
completion path reported before the field existed -- so the
TXU_CNTRL_MGMT filter on the reporting side is not what keeps it safe.
- rwnx_cfg80211_remain_on_channel_()'s mgmt_roc_flag also selects the
cookie source, stored in a new rwnx_roc_elem::cookie that the
rwnx_msg_rx.c completion handlers read.
- rwnx_cfg80211_probe_client() stores the given cookie in a new
apm_probe_sta::cookie field for the async probe-status work.
Every gate this adds uses AICWF_CFG80211_VERSION_CODE, so an OpenWrt
backports build selects these paths from the wireless stack's version
rather than the kernel's, matching the existing 7.2 gates.
On kernels before 7.3 the compiled behaviour is identical to main with
two exceptions, both requested in review and both changing only the
order of a store relative to a queue/send: *cookie for probe_client is
taken from probe_id before queue_work() rather than after it, and the
RoC cookie is read from roc_cookie_cnt once, before rwnx_send_roc(),
rather than after it returns. In each case the value differs from
main's only if the worker/RX path has already completed and bumped the
counter in between -- a window in which main returns N+1 while having
already reported N to cfg80211. The reported and returned values now
agree by construction.
v2, addressing review:
- RoC: the cookie is decided and stored in roc_elem before the element
is published and rwnx_send_roc() is called, so an early channel-switch
indication cannot report an uninitialised cookie.
- probe_peer: the cookie is stored before queue_work(), so a worker
running immediately on another CPU reports the right one.
- Monitor injection: intended to initialise sw_txhdr->cookie in
rwnx_start_monitor_if_xmit(), but the store landed in
rwnx_start_xmit() instead, where it is never read. Fixed in v5.
- Pre-3.14: use_given_cookie is part of that signature too and both
old-signature callers pass false.
- Rebased onto the OpenWrt backport-version change.
v3:
- rwnx_main.h gated the probe_client prototype on LINUX_VERSION_CODE
while rwnx_main.c gated the definition on AICWF_CFG80211_VERSION_CODE.
Identical on a native build, but a backports build with the two
decoupled would see a u64 * prototype against a u64 definition.
- rwnx_cfg80211_remain_on_channel() no longer duplicates the whole call
to the shared helper just to change one argument; only the cookie
pointer is selected by version.
v4:
- rwnx_cfg80211_remain_on_channel_() no longer writes *cookie before
rwnx_send_roc(). The cookie is snapshotted into a local, roc_elem
keeps its early assignment, and *cookie is written where it was
before this patch: inside the error == 0 branch.
v5:
- The monitor-injection initialisation is now where it was always
meant to be: rwnx_start_monitor_if_xmit(), between the skb
assignment and raw_frame = 1, ungated, since that path runs on every
kernel with CONFIG_RWNX_MON_XMIT. The value is (unsigned long)skb_mgmt,
which is what rwnx_txdatacfm() reported for these frames before.
- The remaining allocation sites that did not set the field --
intf_tx() and rwnx_probersp_work() -- now do, so all five do.
- The internal RoC's block-local cookie in rwnx_cfg80211_mgmt_tx() is
renamed roc_cookie: on 7.3 it had come to shadow a same-typed
parameter with a different meaning.
- Comment fixes: the rwnx_start_mgmt_xmit() kerneldoc documents
use_given_cookie; the probe_peer comment states the 7.3 contract; the
two #endif trailers that close chains now opening on the 7.3 gate say
so; the unused rx_addr is explained on the 7.3 arm as well.
- Rebased onto main (set_monitor_channel on 6.12 stable).
Verified against real linux-cachyos-bc250 (7.2.6) and linux-cachyos-rc-bc250
(7.3-rc4) headers with LLVM=1, the way DKMS builds them, asserting on exit
code and module count:
upstream main @ 7.2.6 rc=0, 3 modules, 13 warnings
upstream main @ 7.3-rc4 rc=2 - the errors this patch fixes
this branch @ 7.2.6 rc=0, 3 modules, 13 warnings
this branch @ 7.3-rc4 rc=0, 3 modules, 13 warnings
warning sets on 7.2.6: identical, and none names a function this
patch touches.
The backports configuration is not something I can build here, so the
header/definition agreement in v3 rests on both sites using the same
macro rather than on a test.
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 spec still pins e93a7d2, so Bazzite builds miss the fixes merged
since: the Linux 7.1+ TDLS discovery response length (31b726a), the
SUN60IW2P1 USB transfer settings (9594c5c), OpenWrt cfg80211 backport
version handling (27af5ad) and the 6.12 stable set_monitor_channel()
prototype (#97).
Pin 3e9a025, the merge of #97. The pinned tree builds all three modules
against Linux 7.2.6 headers.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
The spec still pins 13baa9b, which predates 40379fe ("fix: support Linux
7.2 cfg80211 API"), so on Bazzite 44 (kernel 7.2) rpmbuild fails in
%build with an implicit declaration of the removed strncpy() and an
incompatible pointer type for cfg80211_ops::remain_on_channel, whose
prototype gained a trailing rx_addr argument.
Pin the current main branch instead and reset Release for the new
snapshot. Verified by building the package against kernel
7.2.0-ogc4.1.fc44.x86_64.
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.
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)
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
- Disable automatic creation of debuginfo packages to fix issue #77.
- Require usb_modeswitch as package dependency instead of file dependency to fix issue #77.
Pin the Wi-Fi package to the current main code commit, ship both maintained modules and all firmware variants, and remove obsolete Bluetooth packaging.
Install mode-switch dependencies, support a69c:572f, avoid redundant generic headers when a usable kernel build tree exists, and discover DKMS logs dynamically. Addresses installer portions of #28, #55, #65, #66, and #68.
Follow-up to d66e5cb which shipped fw/aic8800{,D80N,D80X2,DLN} but
forgot to update install.sh — so users still got only aic8800D80
firmware installed and the "Pandora" mode-switch config was missing.
install_firmware:
- Loop over all fw/aic8800* variants instead of hard-coding aic8800D80
- Install usb_modeswitch/1111_1111 to /etc/usb_modeswitch.d/1111:1111
verify_installation: count installed firmware variants instead of
checking for the single aic8800D80 directory.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>