mirror of
https://github.com/shenmintao/aic8800d80.git
synced 2026-09-26 17:44:16 +00:00
Compare commits
69
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
332677e771 | ||
|
|
a86affa3c6 | ||
|
|
6229bf3c7e | ||
|
|
c8327eab5b | ||
|
|
b0ef216ed8 | ||
|
|
0dfe7588fc | ||
|
|
40f1d081e9 | ||
|
|
966de5e878 | ||
|
|
4b717f4048 | ||
|
|
0e56f1a1f8 | ||
|
|
8378d2ce34 | ||
|
|
2384dbe450 | ||
|
|
8cbefea252 | ||
|
|
655c14f9f3 | ||
|
|
44748e193a | ||
|
|
35f32c238c | ||
|
|
1b7c44ddd4 | ||
|
|
5ea5196eea | ||
|
|
fffad12a26 | ||
|
|
95d889d961 | ||
|
|
4bae903599 | ||
|
|
51b8ab8062 | ||
|
|
ded6920d06 | ||
|
|
eb3aad9e8d | ||
|
|
bbc1a04e59 | ||
|
|
e7b7599ad9 | ||
|
|
b100e7a7ec | ||
|
|
e53523ba48 | ||
|
|
957b5f5a82 | ||
|
|
0d7a07e8aa | ||
|
|
1358e55a0e | ||
|
|
51b7b6e729 | ||
|
|
800a7b93ba | ||
|
|
13baa9b0b1 | ||
|
|
6550131e18 | ||
|
|
268c4f7122 | ||
|
|
c83ae8b4e6 | ||
|
|
4b31d02392 | ||
|
|
1f0c3e28ac | ||
|
|
59e6b00abe | ||
|
|
dbfbfa0c64 | ||
|
|
cc2a888d22 | ||
|
|
027a7a8662 | ||
|
|
7b2541e5c0 | ||
|
|
bff42860ff | ||
|
|
388a0192c7 | ||
|
|
d10bc52903 | ||
|
|
3f9916b6ff | ||
|
|
c5e635bf4c | ||
|
|
f97281254a | ||
|
|
46f420f8f6 | ||
|
|
8bf93919e7 | ||
|
|
a5db07c4d4 | ||
|
|
d66e5cb859 | ||
|
|
9a3b01eead | ||
|
|
0bcec3069e | ||
|
|
f8df5e741e | ||
|
|
d1b60ff10d | ||
|
|
05710dff05 | ||
|
|
ed0e373a0d | ||
|
|
2bf62be7c8 | ||
|
|
6e9be3b658 | ||
|
|
6a37c4224b | ||
|
|
7e420f3745 | ||
|
|
6c2496a2dc | ||
|
|
953488c4bd | ||
|
|
fd0867729f | ||
|
|
31aa18b841 | ||
|
|
15a9272867 |
+11
-2
@@ -1,2 +1,11 @@
|
|||||||
tests/issue63-btusb-zlp/*.patch -whitespace
|
fw/aic8800D80/*.txt text eol=lf
|
||||||
tests/issue63-btusb-zlp/*.sh text eol=lf
|
fw/aic8800D80/*.bin binary
|
||||||
|
fw/aic8800DC/*.txt text eol=lf
|
||||||
|
fw/aic8800DC/*.bin binary
|
||||||
|
/.gitattributes text eol=lf
|
||||||
|
drivers/aic8800/aic_zlp_quirk/*.c text eol=lf
|
||||||
|
drivers/aic8800/aic_zlp_quirk/Makefile text eol=lf
|
||||||
|
tests/issue63-zlp-quirk/*.conf text eol=lf
|
||||||
|
tests/issue63-zlp-quirk/*.md text eol=lf
|
||||||
|
tests/issue63-zlp-quirk/*.sh text eol=lf
|
||||||
|
tests/issue63-zlp-quirk/Makefile text eol=lf
|
||||||
|
|||||||
+9
-2
@@ -2,12 +2,19 @@
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This automated installation script (`install.sh`) simplifies the process of installing the AIC8800D80 WiFi driver on Linux systems.
|
This automated installation script (`install.sh`) installs the AIC8800 Wi-Fi
|
||||||
|
driver and firmware loader on Linux systems. Wi-Fi/Bluetooth combo adapters use
|
||||||
|
the standard kernel `btusb` driver after firmware initialization. For USB
|
||||||
|
device `368b:8d81`, it also installs a device-scoped ACL bulk TX ZLP companion
|
||||||
|
module without replacing the distribution's `btusb.ko`.
|
||||||
|
|
||||||
- Automatic Secure Boot detection
|
- Automatic Secure Boot detection
|
||||||
- Automatic dependency installation
|
- Automatic dependency installation
|
||||||
- Automatic driver compilation and installation
|
- Automatic driver compilation and installation
|
||||||
- Automatic module loading on boot
|
- Automatic module loading on boot
|
||||||
|
- Automatic cleanup of obsolete `aic_btusb` configuration
|
||||||
|
- Automatic `aic_zlp_quirk` handling for the validated `368b:8d81` device
|
||||||
|
- Wi-Fi-only and Wi-Fi/Bluetooth combo adapter support from the same branch
|
||||||
- Comprehensive error handling
|
- Comprehensive error handling
|
||||||
- Colored output and logging
|
- Colored output and logging
|
||||||
- Compatible with Ubuntu, Debian, Fedora, and derivatives (DKMS supported `dkms.conf`)
|
- Compatible with Ubuntu, Debian, Fedora, and derivatives (DKMS supported `dkms.conf`)
|
||||||
@@ -16,7 +23,7 @@ This automated installation script (`install.sh`) simplifies the process of inst
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repository and download the script, make the script executable
|
# Clone the repository and download the script, make the script executable
|
||||||
git clone -b bluetooth https://github.com/shenmintao/aic8800d80.git && cd aic8800d80 && chmod +x install.sh
|
git clone https://github.com/shenmintao/aic8800d80.git && cd aic8800d80 && chmod +x install.sh
|
||||||
|
|
||||||
# Run the installation
|
# Run the installation
|
||||||
sudo ./install.sh
|
sudo ./install.sh
|
||||||
|
|||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
# Building with OpenWrt backports
|
||||||
|
|
||||||
|
OpenWrt's target kernel and wireless stack can have different versions.
|
||||||
|
For example, [issue #94](https://github.com/shenmintao/aic8800d80/issues/94)
|
||||||
|
uses Linux **6.12.94** with **backports 6.18.26** on OpenWrt 25.12.5.
|
||||||
|
The Ubuntu build host's kernel version is not used to select these APIs.
|
||||||
|
|
||||||
|
## Package Makefile
|
||||||
|
|
||||||
|
Pass `CFG80211_VERSION=6.18.26` to the kernel make invocation for that
|
||||||
|
combination. Use the `PKG_VERSION` from your OpenWrt
|
||||||
|
`package/kernel/mac80211/Makefile`, in `major.minor.patch` format. Keep the
|
||||||
|
backports include paths and symbol versions from the same build:
|
||||||
|
|
||||||
|
```make
|
||||||
|
NOSTDINC_FLAGS := \
|
||||||
|
$(KERNEL_NOSTDINC_FLAGS) \
|
||||||
|
-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
|
||||||
|
-I$(STAGING_DIR)/usr/include/mac80211-backport \
|
||||||
|
-I$(STAGING_DIR)/usr/include/mac80211/uapi \
|
||||||
|
-I$(STAGING_DIR)/usr/include/mac80211 \
|
||||||
|
-include backport/backport.h
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
+$(KERNEL_MAKE) $(PKG_JOBS) \
|
||||||
|
M="$(PKG_BUILD_DIR)/drivers/aic8800" \
|
||||||
|
KBUILD_EXTRA_SYMBOLS="$(LINUX_DIR)/../symvers/mac80211.symvers" \
|
||||||
|
NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
|
||||||
|
CFG80211_VERSION=6.18.26 \
|
||||||
|
modules
|
||||||
|
endef
|
||||||
|
```
|
||||||
|
|
||||||
|
The package must depend on `kmod-cfg80211` so its headers and symbol versions
|
||||||
|
are staged before this driver is built. Keep any additional dependencies,
|
||||||
|
firmware installation rules and module packaging rules your device needs.
|
||||||
|
Update the package's pinned source revision to one containing this fix, or
|
||||||
|
apply the fix as an OpenWrt package patch, then clean and rebuild the package:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make package/kernel/aic8800d80/clean
|
||||||
|
make package/kernel/aic8800d80/compile V=sc -j1
|
||||||
|
```
|
||||||
|
|
||||||
|
Changing `CFG80211_VERSION` alone does not update the driver source or the
|
||||||
|
wireless headers. The value must match the actual wireless stack; do not set
|
||||||
|
it to the host kernel version or redefine `LINUX_VERSION_CODE`.
|
||||||
|
|
||||||
|
## Compatibility scope
|
||||||
|
|
||||||
|
The override selects the wireless API changes since Linux 6.12, including
|
||||||
|
monitor-channel callbacks, radio/link arguments, radar notifications and
|
||||||
|
newer cfg80211 callbacks. Timer, USB, memory-management and module namespace
|
||||||
|
checks continue to use the target kernel version. Older target kernels with
|
||||||
|
newer backports may need additional wireless API adaptations.
|
||||||
|
|
||||||
|
Leave `CFG80211_VERSION` unset when building against the kernel's own wireless
|
||||||
|
stack, as on a regular Ubuntu/Debian installation. The driver then uses the
|
||||||
|
kernel version as before. Hardware revision still determines whether to use
|
||||||
|
`main` or `legacy-mcu1`; a wireless API mismatch does not change that choice.
|
||||||
|
|
||||||
|
The feeds/Kconfig duplicate definitions and recursive dependencies also
|
||||||
|
reported in issue #94 belong to the OpenWrt build configuration and require
|
||||||
|
separate investigation.
|
||||||
|
|
||||||
|
See the [build regression recipe](tests/openwrt-backports/README.md) for
|
||||||
|
the tested kernel/backports combinations and a script to repeat the build.
|
||||||
@@ -1,11 +1,45 @@
|
|||||||
# AIC8800D80 Linux Driver
|
# AIC8800 Linux Wi-Fi and Bluetooth Driver
|
||||||
This driver is for the AIC8800D80 chipset, supported by devices such as the Tenda U11 and AX913B.
|
This driver supports AIC8800-family chipsets used by devices such as the Tenda U11, AX913B, and TP-Link Archer TX1U Nano.
|
||||||
|
|
||||||
|
> **Legacy MCU revision 1 branch:** You are viewing `legacy-mcu1`. This branch
|
||||||
|
> is only for AIC8800D80 or AIC8800DC/DW devices that report
|
||||||
|
> `chip_id=7, chip_mcu_id=1`. It provides complete matched V3 firmware and
|
||||||
|
> loader profiles for the D80 upload-limit failure validated in
|
||||||
|
> [issue #58](https://github.com/shenmintao/aic8800d80/issues/58) and the DC/DW
|
||||||
|
> V5 main-application timeout validated in
|
||||||
|
> [issue #71](https://github.com/shenmintao/aic8800d80/issues/71). Use
|
||||||
|
> [`main`](https://github.com/shenmintao/aic8800d80/tree/main) for newer
|
||||||
|
> `chip_mcu_id=0` hardware or when the MCU revision is unknown. See the
|
||||||
|
> [D80](tests/issue58-mcu1-legacy-fw/README.md) and
|
||||||
|
> [DC/DW](tests/issue71-mcu1-v3-profile/README.md) support notes before installing.
|
||||||
|
>
|
||||||
|
> After switching branches, rerun `sudo ./install.sh` and reboot; switching the
|
||||||
|
> Git branch alone does not replace firmware already installed under
|
||||||
|
> `/lib/firmware`.
|
||||||
|
|
||||||
Added support for devices with Vendor ID 368B (tested).
|
Added support for devices with Vendor ID 368B (tested).
|
||||||
|
|
||||||
Tested on Linux kernel 6.16 with Ubuntu 25.04 and 6.1.0.27 with Debian 12.
|
Tested on Linux kernel 6.16 with Ubuntu 25.04 and 6.1.0.27 with Debian 12.
|
||||||
|
|
||||||
This branch (`bluetooth`) fully supports both **Wi-Fi** and **Bluetooth**.
|
The same driver supports Wi-Fi-only adapters and Wi-Fi/Bluetooth combo
|
||||||
|
adapters. On combo devices, `aic_load_fw` uploads the AIC firmware and the
|
||||||
|
standard Linux `btusb` driver handles the Bluetooth HCI interface. The obsolete
|
||||||
|
custom `aic_btusb` module is not used.
|
||||||
|
|
||||||
|
USB device `368b:8d81` also uses the bundled `aic_zlp_quirk` companion module.
|
||||||
|
It adds the Bluetooth ACL bulk TX zero-length-packet behavior validated in
|
||||||
|
[issue #63](https://github.com/shenmintao/aic8800d80/issues/63), while leaving
|
||||||
|
the distribution's original `btusb.ko` installed and bound to the device. The
|
||||||
|
quirk is filtered to that VID:PID and fails closed when the required kernel
|
||||||
|
probe support is unavailable.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> **Maintained branches:** This repository now maintains only `main` and
|
||||||
|
> `legacy-mcu1`. You are viewing the branch for `chip_mcu_id=1`; do not switch
|
||||||
|
> this hardware to the former separate `bluetooth` branch, which is retired.
|
||||||
|
> Wi-Fi, the kernel's standard `btusb` Bluetooth path, and the device-scoped
|
||||||
|
> `368b:8d81` ZLP support are integrated here. The ZLP module remains inactive
|
||||||
|
> on other VID:PID combinations.
|
||||||
|
|
||||||
### Disclaimer
|
### Disclaimer
|
||||||
I did not develop this software, The code is sourced from the Tenda U11 driver. I only made some modifications to the code to adapt it to newer kernel versions. Apart from compilation issues, I am unable to address other problems.
|
I did not develop this software, The code is sourced from the Tenda U11 driver. I only made some modifications to the code to adapt it to newer kernel versions. Apart from compilation issues, I am unable to address other problems.
|
||||||
@@ -13,25 +47,49 @@ I did not develop this software, The code is sourced from the Tenda U11 driver.
|
|||||||
### Attention
|
### Attention
|
||||||
Before installing the driver, delete all aic8800-related folders under /lib/firmware. Using an incorrect firmware version may cause the system to freeze.
|
Before installing the driver, delete all aic8800-related folders under /lib/firmware. Using an incorrect firmware version may cause the system to freeze.
|
||||||
|
|
||||||
|
#### Pandora 88M80 mode switching
|
||||||
|
|
||||||
|
Pandora 88M80 adapters that initially appear as USB device `1111:1111` are
|
||||||
|
automatically switched to `a69c:8d80` by sending the required `F3` then `F2`
|
||||||
|
commands. Existing users must rerun `sudo ./install.sh` to replace the installed
|
||||||
|
usb_modeswitch configuration, then unplug the adapter completely and plug it
|
||||||
|
back in.
|
||||||
|
|
||||||
|
If automatic switching does not occur, try the same sequence manually:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo usb_modeswitch -v 1111 -p 1111 \
|
||||||
|
-M "555342438765432100000000000010fd0000000000000000000000000000f3" \
|
||||||
|
-2 "555342438765432100000000000010fd0000000000000000000000000000f2"
|
||||||
|
```
|
||||||
|
|
||||||
|
This only addresses switching from `1111:1111` to `a69c:8d80`. If the device
|
||||||
|
has reached `a69c:8d80` but firmware startup still fails, see
|
||||||
|
[issue #79](https://github.com/shenmintao/aic8800d80/issues/79).
|
||||||
|
|
||||||
### Installation Steps
|
### Installation Steps
|
||||||
|
|
||||||
|
For OpenWrt SDK/buildroot builds, see [OpenWrt build notes](OPENWRT.md).
|
||||||
|
OpenWrt can use a newer cfg80211 backport than its target kernel; these builds
|
||||||
|
must pass the wireless stack version separately.
|
||||||
|
|
||||||
#### Method 1: [Quick Installation](INSTALL_SCRIPT.md) (Recommended)
|
#### Method 1: [Quick Installation](INSTALL_SCRIPT.md) (Recommended)
|
||||||
|
|
||||||
#### Method 2: Manual Installation
|
#### Method 2: Manual Installation
|
||||||
|
|
||||||
#### Copy udev rules:
|
#### Copy udev rules:
|
||||||
Copy the aic.rules file to /lib/udev/rules.d/:
|
Copy the aic.rules file to /usr/lib/udev/rules.d/:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo cp aic.rules /lib/udev/rules.d/
|
sudo cp aic.rules /usr/lib/udev/rules.d/
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Copy firmware:
|
#### Copy firmware:
|
||||||
|
|
||||||
Copy the aic8800D80 folder from ./fw to /lib/firmware/:
|
Copy the firmware directories from `./fw` to `/lib/firmware/`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo cp -r ./fw/aic8800D80 /lib/firmware/
|
sudo cp -r ./fw/aic8800* /lib/firmware/
|
||||||
```
|
```
|
||||||
#### Navigate to the driver directory:
|
#### Navigate to the driver directory:
|
||||||
|
|
||||||
@@ -98,56 +156,52 @@ If the device is still not active, check the kernel logs for any errors related
|
|||||||
sudo dmesg
|
sudo dmesg
|
||||||
```
|
```
|
||||||
|
|
||||||
### Bluetooth Support
|
### Bluetooth on Combo Adapters
|
||||||
|
|
||||||
The `aic_load_fw` module loads the Bluetooth firmware during initialization. After the firmware is correctly uploaded, the standard Linux `btusb` driver handles the Bluetooth interface — no custom `aic_btusb` module is needed (see [PR #35](https://github.com/shenmintao/aic8800d80/pull/35) for details).
|
Bluetooth support does not require a separate AIC transport module. After
|
||||||
|
`aic_load_fw` initializes a combo adapter, the kernel automatically binds its
|
||||||
|
Bluetooth interface to `btusb`. A Wi-Fi-only adapter does not expose that
|
||||||
|
interface, so the Bluetooth path remains inactive.
|
||||||
|
|
||||||
#### Verify Bluetooth is Working
|
Verify the expected modules and controller with:
|
||||||
|
|
||||||
After loading the driver and plugging in the USB device, check if the Bluetooth HCI device is registered:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
hciconfig -a
|
lsmod | grep -E 'aic_load_fw|aic8800_fdrv|aic_zlp_quirk|btusb'
|
||||||
|
lsusb -t
|
||||||
|
bluetoothctl list
|
||||||
```
|
```
|
||||||
|
|
||||||
You should see an HCI device (e.g., `hci0`) listed. If the device is down, bring it up:
|
To scan after a controller appears:
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo hciconfig hci0 up
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also use `bluetoothctl` to scan and connect to Bluetooth devices:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bluetoothctl
|
bluetoothctl
|
||||||
# Inside bluetoothctl:
|
|
||||||
power on
|
power on
|
||||||
scan on
|
scan on
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Bluetooth Troubleshooting
|
If Bluetooth is missing or reports HCI timeouts, run the read-only diagnostic
|
||||||
|
script and attach its output together with the current boot log:
|
||||||
If Bluetooth is not working, run the diagnostic script:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
chmod +x diagnose_bt.sh
|
chmod +x diagnose_bt.sh
|
||||||
sudo ./diagnose_bt.sh
|
sudo ./diagnose_bt.sh
|
||||||
|
sudo journalctl -k -b --no-pager
|
||||||
```
|
```
|
||||||
|
|
||||||
Common issues and solutions:
|
The installer removes active references to the retired `aic_btusb` integration.
|
||||||
|
It does not force-load `btusb` or globally change the Bluetooth rfkill state;
|
||||||
|
normal kernel device matching and the user's system policy remain in control.
|
||||||
|
|
||||||
1. **Firmware not found**: Ensure the firmware files are correctly copied to `/lib/firmware/aic8800D80/`. Key Bluetooth firmware files include:
|
For `368b:8d81`, verify the ZLP hook and its injection counter while Bluetooth
|
||||||
- `fw_patch_8800d80_u02.bin`
|
traffic is active:
|
||||||
- `fw_patch_table_8800d80_u02.bin`
|
|
||||||
- `fw_adid_8800d80_u02.bin`
|
|
||||||
|
|
||||||
2. **Check kernel logs** for Bluetooth-related errors:
|
```bash
|
||||||
```bash
|
cat /sys/module/aic_zlp_quirk/parameters/hook
|
||||||
sudo dmesg | grep -iE "aicbt|bluetooth|hci|fw_patch"
|
cat /sys/module/aic_zlp_quirk/parameters/injections
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The Wi-Fi-reset recovery behavior tracked in
|
||||||
|
[issue #53](https://github.com/shenmintao/aic8800d80/issues/53) remains a known
|
||||||
|
limitation: after an airplane-mode or hotspot reset, Bluetooth may require a
|
||||||
|
physical unplug/replug of the adapter.
|
||||||
|
|
||||||
3. **RF-Kill blocking Bluetooth**:
|
|
||||||
```bash
|
|
||||||
rfkill list bluetooth
|
|
||||||
sudo rfkill unblock bluetooth
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# AIC8800 USB Mass Storage mode switch rules
|
# AIC8800 USB mass-storage mode switch rules
|
||||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k"
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k"
|
||||||
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5722", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k"
|
||||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5723", SYMLINK+="tendaudisk", RUN+="/usr/bin/eject /dev/%k"
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5723", SYMLINK+="tendaudisk", RUN+="/usr/bin/eject /dev/%k"
|
||||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5724", SYMLINK+="ugreenax900", RUN+="/usr/bin/eject /dev/%k"
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5724", SYMLINK+="ugreenax900", RUN+="/usr/bin/eject /dev/%k"
|
||||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5725", SYMLINK+="tendaudiskv2", RUN+="/usr/bin/eject /dev/%k"
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5725", SYMLINK+="tendaudiskv2", RUN+="/usr/bin/eject /dev/%k"
|
||||||
@@ -9,20 +10,5 @@ KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572a", SYMLINK+="ten
|
|||||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572c", SYMLINK+="cudydiskv2", RUN+="/usr/bin/eject /dev/%k"
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572c", SYMLINK+="cudydiskv2", RUN+="/usr/bin/eject /dev/%k"
|
||||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572f", SYMLINK+="aicudisk572f", RUN+="/usr/bin/eject /dev/%k"
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572f", SYMLINK+="aicudisk572f", RUN+="/usr/bin/eject /dev/%k"
|
||||||
|
|
||||||
# AIC8800D80 "Pandora" clone adapter - automatic mode switch & driver binding
|
# AIC8800D80 "Pandora" clone: switch 1111:1111 to its operational USB ID.
|
||||||
# Triggers usb_modeswitch when the device is plugged in as 1111:1111
|
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1111", ATTR{idProduct}=="1111", RUN+="/bin/sh -c 'if [ -x /usr/sbin/usb_modeswitch ]; then exec /usr/sbin/usb_modeswitch -c /etc/usb_modeswitch.d/1111:1111; elif [ -x /usr/bin/usb_modeswitch ]; then exec /usr/bin/usb_modeswitch -c /etc/usb_modeswitch.d/1111:1111; fi'"
|
||||||
|
|
||||||
# --- Mode Switch ---
|
|
||||||
ACTION=="add", ATTRS{idVendor}=="1111", ATTRS{idProduct}=="1111", RUN+="/bin/sh -c 'if [ -x /usr/sbin/usb_modeswitch ]; then exec /usr/sbin/usb_modeswitch -c /etc/usb_modeswitch.d/1111:1111; elif [ -x /usr/bin/usb_modeswitch ]; then exec /usr/bin/usb_modeswitch -c /etc/usb_modeswitch.d/1111:1111; fi'"
|
|
||||||
|
|
||||||
# --- WiFi Driver Binding ---
|
|
||||||
# After mode switch, the device re-enumerates as a69c:8d81 (Radxa fw) or a69c:8d83 (Brostrend fw).
|
|
||||||
# If aic8800_fdrv doesn't auto-bind to the WiFi interface, add the VID:PID dynamically:
|
|
||||||
ACTION=="add", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="8d81", RUN+="/bin/sh -c 'echo a69c 8d81 > /sys/bus/usb/drivers/aic8800_fdrv/new_id 2>/dev/null || true'"
|
|
||||||
ACTION=="add", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="8d83", RUN+="/bin/sh -c 'echo a69c 8d83 > /sys/bus/usb/drivers/aic8800_fdrv/new_id 2>/dev/null || true'"
|
|
||||||
ACTION=="add", ATTRS{idVendor}=="368b", ATTRS{idProduct}=="8d81", RUN+="/bin/sh -c 'echo 368b 8d81 > /sys/bus/usb/drivers/aic8800_fdrv/new_id 2>/dev/null || true'"
|
|
||||||
|
|
||||||
# Unblock rfkill for Bluetooth
|
|
||||||
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="8d81", RUN+="/bin/sh -c 'rfkill unblock bluetooth 2>/dev/null || true'"
|
|
||||||
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="8d83", RUN+="/bin/sh -c 'rfkill unblock bluetooth 2>/dev/null || true'"
|
|
||||||
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="368b", ATTRS{idProduct}=="8d81", RUN+="/bin/sh -c 'rfkill unblock bluetooth 2>/dev/null || true'"
|
|
||||||
|
|||||||
+6
-3
@@ -32,7 +32,7 @@ Copy aic8800d80.spec to rpmbuild/SPECS
|
|||||||
|
|
||||||
~~~bash
|
~~~bash
|
||||||
cd $HOME/rpmbuild/SPECS
|
cd $HOME/rpmbuild/SPECS
|
||||||
curl -LO -s https://raw.githubusercontent.com/shenmintao/aic8800d80/refs/heads/bluetooth/bazzite/aic8800d80.spec
|
curl -LO -s https://raw.githubusercontent.com/shenmintao/aic8800d80/refs/heads/main/bazzite/aic8800d80.spec
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Prepare and download required files.
|
Prepare and download required files.
|
||||||
@@ -56,8 +56,11 @@ sudo rpm-ostree install "$rpm_path"
|
|||||||
sudo systemctl reboot
|
sudo systemctl reboot
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
After reboot, the Wi-Fi module and firmware loader will be available. Bluetooth
|
After reboot, the Wi-Fi module and firmware loader will be available. On combo
|
||||||
is handled by the standard `btusb` kernel module after firmware initialization.
|
adapters, Bluetooth is handled by the standard `btusb` kernel module after
|
||||||
|
firmware initialization. USB device `368b:8d81` also autoloads the packaged
|
||||||
|
`aic_zlp_quirk` companion module for its required Bluetooth ACL bulk TX zero
|
||||||
|
packet behavior; the distribution's `btusb` module is not replaced.
|
||||||
|
|
||||||
This RPM is built for the kernel reported by `uname -r`. Rebuild and reinstall
|
This RPM is built for the kernel reported by `uname -r`. Rebuild and reinstall
|
||||||
it after a Bazzite kernel upgrade.
|
it after a Bazzite kernel upgrade.
|
||||||
|
|||||||
+50
-12
@@ -1,11 +1,16 @@
|
|||||||
%global commit 6b8cb98e969b04236f8726f7591393a040171735
|
%global commit c8327eab5be246d4b517afdba034775f00afa988
|
||||||
%global shortcommit %(echo %{commit} | cut -c1-7)
|
%global shortcommit %(echo %{commit} | cut -c1-7)
|
||||||
|
%global snapdate 20260924
|
||||||
|
%global debug_package %{nil}
|
||||||
%{!?kver:%global kver %(uname -r)}
|
%{!?kver:%global kver %(uname -r)}
|
||||||
|
|
||||||
Name: aic8800d80
|
Name: aic8800d80
|
||||||
Version: %{shortcommit}
|
# Versions before 2026-09-24 were bare commit hashes, which rpm does not
|
||||||
|
# order by commit history. Epoch 1 sorts every snapshot version after them.
|
||||||
|
Epoch: 1
|
||||||
|
Version: 1.0.0^%{snapdate}git%{shortcommit}
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: AIC8800D80 USB Wi-Fi and Bluetooth driver
|
Summary: AIC8800 USB Wi-Fi, Bluetooth firmware, and ZLP quirk driver
|
||||||
|
|
||||||
License: GPL-2.0-only
|
License: GPL-2.0-only
|
||||||
URL: https://github.com/shenmintao/aic8800d80
|
URL: https://github.com/shenmintao/aic8800d80
|
||||||
@@ -17,16 +22,16 @@ BuildRequires: kernel-devel-uname-r = %{kver}
|
|||||||
|
|
||||||
Requires: kernel-uname-r = %{kver}
|
Requires: kernel-uname-r = %{kver}
|
||||||
Requires: /usr/bin/eject
|
Requires: /usr/bin/eject
|
||||||
Requires: /usr/sbin/usb_modeswitch
|
Requires: usb_modeswitch
|
||||||
Requires: /usr/sbin/rfkill
|
|
||||||
Requires(post): /usr/sbin/depmod
|
Requires(post): /usr/sbin/depmod
|
||||||
Requires(postun): /usr/sbin/depmod
|
Requires(postun): /usr/sbin/depmod
|
||||||
|
|
||||||
%description
|
%description
|
||||||
Out-of-tree AIC8800D80 USB driver with Wi-Fi support, Bluetooth firmware
|
Out-of-tree AIC8800 USB driver with Wi-Fi support, Bluetooth firmware loading,
|
||||||
loading, udev mode-switch rules, and all firmware variants shipped by the
|
udev mode-switch rules, and all firmware variants shipped by the upstream
|
||||||
upstream repository. Bluetooth interfaces are handled by the standard Linux
|
repository. Combo adapters use the standard Linux btusb transport driver. A
|
||||||
btusb driver after aic_load_fw initializes the device.
|
device-scoped companion module supplies the required ACL bulk TX ZLP behavior
|
||||||
|
for USB device 368b:8d81 without replacing the distribution btusb module.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -n %{name}-%{commit}
|
%autosetup -n %{name}-%{commit}
|
||||||
@@ -46,6 +51,10 @@ install -Dpm0644 \
|
|||||||
drivers/aic8800/aic_load_fw/aic_load_fw.ko \
|
drivers/aic8800/aic_load_fw/aic_load_fw.ko \
|
||||||
%{buildroot}/usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800/aic_load_fw.ko
|
%{buildroot}/usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800/aic_load_fw.ko
|
||||||
|
|
||||||
|
install -Dpm0644 \
|
||||||
|
drivers/aic8800/aic_zlp_quirk/aic_zlp_quirk.ko \
|
||||||
|
%{buildroot}/usr/lib/modules/%{kver}/kernel/drivers/bluetooth/aic8800/aic_zlp_quirk.ko
|
||||||
|
|
||||||
install -Dpm0644 \
|
install -Dpm0644 \
|
||||||
aic.rules \
|
aic.rules \
|
||||||
%{buildroot}/usr/lib/udev/rules.d/90-aic8800-mode-switch.rules
|
%{buildroot}/usr/lib/udev/rules.d/90-aic8800-mode-switch.rules
|
||||||
@@ -67,12 +76,41 @@ cp -a fw/aic8800* %{buildroot}/usr/lib/firmware/
|
|||||||
%dir /usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800
|
%dir /usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800
|
||||||
/usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800/aic8800_fdrv.ko
|
/usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800/aic8800_fdrv.ko
|
||||||
/usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800/aic_load_fw.ko
|
/usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800/aic_load_fw.ko
|
||||||
|
/usr/lib/modules/%{kver}/kernel/drivers/bluetooth/aic8800/aic_zlp_quirk.ko
|
||||||
/usr/lib/udev/rules.d/90-aic8800-mode-switch.rules
|
/usr/lib/udev/rules.d/90-aic8800-mode-switch.rules
|
||||||
%config(noreplace) /etc/usb_modeswitch.d/1111:1111
|
%config(noreplace) /etc/usb_modeswitch.d/1111:1111
|
||||||
/usr/lib/firmware/aic8800*
|
/usr/lib/firmware/aic8800*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Tue Jul 14 2026 Shen Mintao <shenmintao@gmail.com> - 6b8cb98-1
|
* Thu Sep 24 2026 Shen Mintao <shenmintao@gmail.com> - 1:1.0.0^20260924gitc8327ea-1
|
||||||
- Build the current bluetooth branch without the removed aic_btusb module.
|
- Version snapshots as 1.0.0^<date>git<commit> with Epoch 1. The previous
|
||||||
|
commit-hash versions do not sort in commit order, so rpm could treat a
|
||||||
|
newer snapshot as an older package.
|
||||||
|
|
||||||
|
* Thu Sep 24 2026 Shen Mintao <shenmintao@gmail.com> - c8327ea-1
|
||||||
|
- Build the current legacy-mcu1 branch, which carries the Linux 7.2
|
||||||
|
cfg80211 and strncpy() fixes needed to compile on Bazzite 44.
|
||||||
|
- Include the monitor packet injection path and the 6.12 stable
|
||||||
|
set_monitor_channel() fix synchronized from main.
|
||||||
|
|
||||||
|
* Wed Jul 29 2026 Shen Mintao <shenmintao@gmail.com> - 51b7b6e-2
|
||||||
|
- Disable automatic debug package generation for Bazzite builds.
|
||||||
|
- Require usb_modeswitch by package name for rpm-ostree dependency resolution.
|
||||||
|
|
||||||
|
* Sat Jul 25 2026 Shen Mintao <shenmintao@gmail.com> - 51b7b6e-1
|
||||||
|
- Package the unified installer and ZLP quirk with the legacy MCU1 profiles.
|
||||||
|
- Preserve the matched D80 and DC/DW firmware and loader combinations.
|
||||||
|
|
||||||
|
* Sat Jul 25 2026 Shen Mintao <shenmintao@gmail.com> - 13baa9b-1
|
||||||
|
- Unify Wi-Fi and standard-btusb Bluetooth support in one package.
|
||||||
|
- Add the device-scoped 368b:8d81 ACL bulk TX ZLP companion module.
|
||||||
|
- Clean up obsolete aic_btusb and issue #63 diagnostic installations.
|
||||||
|
|
||||||
|
* Fri Jul 24 2026 Shen Mintao <shenmintao@gmail.com> - 88dbc0a-1
|
||||||
|
- Use the unified Wi-Fi and Bluetooth installer/package description.
|
||||||
|
- Keep Bluetooth transport on the standard Linux btusb driver.
|
||||||
|
|
||||||
|
* Tue Jul 14 2026 Shen Mintao <shenmintao@gmail.com> - d10bc52-1
|
||||||
|
- Build the current main branch without the legacy custom Bluetooth module.
|
||||||
- Package all firmware variants and current mode-switch rules.
|
- Package all firmware variants and current mode-switch rules.
|
||||||
- Remove the obsolete custom Bluetooth module integration.
|
- Remove obsolete Bluetooth-specific configuration from the Wi-Fi package.
|
||||||
|
|||||||
+104
-86
@@ -1,142 +1,160 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# Diagnose Bluetooth on AIC8800 Wi-Fi/Bluetooth combo adapters.
|
||||||
#
|
#
|
||||||
# AIC8800D80 Bluetooth Diagnostic Script
|
# aic_load_fw initializes the device and uploads the AIC firmware. The
|
||||||
# 用于诊断蓝牙问题
|
# standard in-kernel btusb driver must then bind to the Bluetooth HCI USB
|
||||||
#
|
# interface. The removed aic_btusb module must not be installed or loaded.
|
||||||
# 本分支 (bluetooth) 使用内核标准 btusb 驱动接管蓝牙,
|
|
||||||
# aic_load_fw 负责把蓝牙固件上传到芯片。
|
|
||||||
# 不应该再安装/加载 aic_btusb。
|
|
||||||
#
|
|
||||||
|
|
||||||
echo "=== AIC8800D80 蓝牙诊断 ==="
|
echo "=== AIC8800 Bluetooth diagnostics ==="
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 1. 检查 USB 设备
|
echo "1. AIC USB devices:"
|
||||||
echo "1. USB 设备状态:"
|
if command -v lsusb >/dev/null 2>&1; then
|
||||||
echo " 当前 AIC 设备:"
|
lsusb | grep -iE 'a69c|368b|3625' || echo " No known AIC USB ID found"
|
||||||
lsusb | grep -iE "a69c|368b|1111" || echo " 未找到 AIC 设备"
|
else
|
||||||
|
echo " lsusb is not installed"
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 2. 检查 USB 接口数量
|
echo "2. USB interfaces and bound drivers:"
|
||||||
echo "2. USB 接口详情:"
|
bt_interface_found=false
|
||||||
|
btusb_bound=false
|
||||||
|
zlp_target_found=false
|
||||||
for dev in /sys/bus/usb/devices/*; do
|
for dev in /sys/bus/usb/devices/*; do
|
||||||
if [ -f "$dev/idVendor" ] && [ -f "$dev/idProduct" ]; then
|
[ -f "$dev/idVendor" ] || continue
|
||||||
|
[ -f "$dev/idProduct" ] || continue
|
||||||
|
|
||||||
vid=$(cat "$dev/idVendor" 2>/dev/null)
|
vid=$(cat "$dev/idVendor" 2>/dev/null)
|
||||||
pid=$(cat "$dev/idProduct" 2>/dev/null)
|
pid=$(cat "$dev/idProduct" 2>/dev/null)
|
||||||
if [[ "$vid" == "a69c" || "$vid" == "368b" ]]; then
|
case "$vid" in
|
||||||
echo " 设备: $vid:$pid"
|
a69c|368b|3625) ;;
|
||||||
if [ -d "$dev" ]; then
|
*) continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo " Device: $vid:$pid"
|
||||||
|
if [ "$vid" = "368b" ] && [ "$pid" = "8d81" ]; then
|
||||||
|
zlp_target_found=true
|
||||||
|
fi
|
||||||
for intf in "$dev"/*:*; do
|
for intf in "$dev"/*:*; do
|
||||||
if [ -d "$intf" ]; then
|
[ -d "$intf" ] || continue
|
||||||
class=$(cat "$intf/bInterfaceClass" 2>/dev/null)
|
class=$(cat "$intf/bInterfaceClass" 2>/dev/null)
|
||||||
subclass=$(cat "$intf/bInterfaceSubClass" 2>/dev/null)
|
subclass=$(cat "$intf/bInterfaceSubClass" 2>/dev/null)
|
||||||
protocol=$(cat "$intf/bInterfaceProtocol" 2>/dev/null)
|
protocol=$(cat "$intf/bInterfaceProtocol" 2>/dev/null)
|
||||||
driver=$(basename "$(readlink "$intf/driver" 2>/dev/null)" 2>/dev/null)
|
driver=$(basename "$(readlink "$intf/driver" 2>/dev/null)" 2>/dev/null)
|
||||||
echo " 接口: $class/$subclass/$protocol -> 驱动: ${driver:-未绑定}"
|
echo " $(basename "$intf"): ${class:-??}/${subclass:-??}/${protocol:-??} -> ${driver:-unbound}"
|
||||||
|
|
||||||
|
if [ "$driver" = "btusb" ]; then
|
||||||
|
btusb_bound=true
|
||||||
|
bt_interface_found=true
|
||||||
|
elif [ "$class" = "e0" ] && [ "$subclass" = "01" ] && [ "$protocol" = "01" ]; then
|
||||||
|
bt_interface_found=true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 3. 检查已加载的模块
|
echo "3. Relevant kernel modules (combo expectation: aic_load_fw + btusb):"
|
||||||
echo "3. 已加载的相关模块 (期望: aic_load_fw + btusb):"
|
lsmod | grep -E '^(aic_load_fw|aic8800_fdrv|aic_zlp_quirk|aic_btusb|btusb|bluetooth)[[:space:]]' || \
|
||||||
lsmod | grep -E "aic_load_fw|aicwf|aic_btusb|btusb|bluetooth" || echo " 未找到相关模块"
|
echo " No related module is currently loaded"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 4. 检查 HCI 设备
|
echo "4. Bluetooth controllers:"
|
||||||
echo "4. HCI 设备:"
|
if command -v bluetoothctl >/dev/null 2>&1; then
|
||||||
hciconfig -a 2>/dev/null || echo " 无法获取 HCI 信息 (可能需要 root 权限)"
|
bluetoothctl list 2>/dev/null || echo " No controller reported by bluetoothctl"
|
||||||
|
elif command -v hciconfig >/dev/null 2>&1; then
|
||||||
|
hciconfig -a 2>/dev/null || echo " No controller reported by hciconfig"
|
||||||
|
else
|
||||||
|
echo " BlueZ command-line tools are not installed"
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 5. 检查蓝牙固件加载日志
|
echo "5. Firmware, btusb, ZLP quirk, and HCI log messages:"
|
||||||
echo "5. 蓝牙固件加载日志 (最近 50 行):"
|
dmesg 2>/dev/null | grep -iE 'fw_patch|fw_adid|aicbt|aic_zlp_quirk|bluetooth|btusb|hci' | tail -80 || true
|
||||||
dmesg | grep -iE "fw_patch|fw_adid|aicbt|bluetooth|btusb|hci" | tail -50
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 6. 检查 rfkill 状态
|
echo "6. Bluetooth rfkill state:"
|
||||||
echo "6. RF-Kill 状态:"
|
if command -v rfkill >/dev/null 2>&1; then
|
||||||
rfkill list bluetooth 2>/dev/null || echo " 无法获取 rfkill 信息"
|
rfkill list bluetooth 2>/dev/null || echo " No Bluetooth rfkill entry"
|
||||||
|
else
|
||||||
|
echo " rfkill is not installed"
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 7. 检查残留的旧 aic_btusb 配置 (issue #53)
|
echo "7. Obsolete aic_btusb installation/configuration:"
|
||||||
echo "7. 残留旧配置检查:"
|
|
||||||
legacy_refs_found=false
|
legacy_refs_found=false
|
||||||
mapfile -t legacy_modprobe_files < <(
|
mapfile -t legacy_modprobe_files < <(
|
||||||
grep -RIlE '^[[:space:]]*(softdep|alias)[^#]*aic_btusb([[:space:]]|$)' \
|
grep -RIlE '^[[:space:]]*(softdep|alias)[^#]*aic_btusb([[:space:]]|$)' \
|
||||||
/etc/modprobe.d /run/modprobe.d /usr/local/lib/modprobe.d /usr/lib/modprobe.d /lib/modprobe.d \
|
/etc/modprobe.d /run/modprobe.d /usr/local/lib/modprobe.d \
|
||||||
2>/dev/null || true
|
/usr/lib/modprobe.d /lib/modprobe.d 2>/dev/null | \
|
||||||
|
grep -vE '\.aic8800-backup$' || true
|
||||||
)
|
)
|
||||||
mapfile -t legacy_udev_files < <(
|
mapfile -t legacy_udev_files < <(
|
||||||
grep -RIl 'aic_btusb/new_id' \
|
grep -RIl 'aic_btusb/new_id' \
|
||||||
/etc/udev/rules.d /run/udev/rules.d /usr/lib/udev/rules.d /lib/udev/rules.d \
|
/etc/udev/rules.d /run/udev/rules.d \
|
||||||
2>/dev/null || true
|
/usr/lib/udev/rules.d /lib/udev/rules.d 2>/dev/null | \
|
||||||
|
grep -vE '\.aic8800-backup$' || true
|
||||||
)
|
)
|
||||||
|
|
||||||
for legacy_file in "${legacy_modprobe_files[@]}"; do
|
for legacy_file in "${legacy_modprobe_files[@]}"; do
|
||||||
echo " ⚠️ 发现旧 modprobe 指令: $legacy_file"
|
echo " Obsolete modprobe directive: $legacy_file"
|
||||||
legacy_refs_found=true
|
legacy_refs_found=true
|
||||||
done
|
done
|
||||||
|
|
||||||
for legacy_file in "${legacy_udev_files[@]}"; do
|
for legacy_file in "${legacy_udev_files[@]}"; do
|
||||||
echo " ⚠️ 发现旧 udev 绑定规则: $legacy_file"
|
echo " Obsolete udev binding rule: $legacy_file"
|
||||||
legacy_refs_found=true
|
legacy_refs_found=true
|
||||||
done
|
done
|
||||||
|
|
||||||
if lsmod | awk '{print $1}' | grep -qx 'aic_btusb'; then
|
if lsmod | awk '{print $1}' | grep -qx 'aic_btusb'; then
|
||||||
echo " ⚠️ 旧 aic_btusb 模块当前仍已加载"
|
echo " Obsolete aic_btusb module is loaded"
|
||||||
legacy_refs_found=true
|
legacy_refs_found=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if modinfo -n aic_btusb >/dev/null 2>&1; then
|
if modinfo -n aic_btusb >/dev/null 2>&1; then
|
||||||
echo " ⚠️ 系统中仍存在 aic_btusb 模块: $(modinfo -n aic_btusb 2>/dev/null)"
|
echo " Obsolete module file: $(modinfo -n aic_btusb 2>/dev/null)"
|
||||||
legacy_refs_found=true
|
legacy_refs_found=true
|
||||||
fi
|
fi
|
||||||
|
if [ "$legacy_refs_found" = false ]; then
|
||||||
|
echo " No active aic_btusb module, directive, or binding rule found (expected)"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
if [ "$legacy_refs_found" = true ]; then
|
echo "8. Device-scoped Bluetooth ACL ZLP quirk:"
|
||||||
echo " 这些残留会尝试加载已删除的模块, 并干扰标准 btusb 的自动加载/绑定顺序。"
|
if [ "$zlp_target_found" = true ]; then
|
||||||
echo " 修复: 拉取最新 bluetooth 分支后重新运行 sudo ./install.sh"
|
if [ -d /sys/module/aic_zlp_quirk ]; then
|
||||||
if command -v update-initramfs >/dev/null 2>&1; then
|
zlp_hook="unknown"
|
||||||
echo " 然后执行: sudo update-initramfs -u"
|
zlp_injections="unavailable"
|
||||||
elif command -v dracut >/dev/null 2>&1; then
|
[ -r /sys/module/aic_zlp_quirk/parameters/hook ] && \
|
||||||
echo " 然后执行: sudo dracut -f"
|
zlp_hook=$(cat /sys/module/aic_zlp_quirk/parameters/hook)
|
||||||
elif command -v mkinitcpio >/dev/null 2>&1; then
|
[ -r /sys/module/aic_zlp_quirk/parameters/injections ] && \
|
||||||
echo " 然后执行: sudo mkinitcpio -P"
|
zlp_injections=$(cat /sys/module/aic_zlp_quirk/parameters/injections)
|
||||||
|
echo " Target 368b:8d81 present"
|
||||||
|
echo " aic_zlp_quirk loaded: yes"
|
||||||
|
echo " active hook: $zlp_hook"
|
||||||
|
echo " ZLP injections: $zlp_injections"
|
||||||
|
else
|
||||||
|
echo " Target 368b:8d81 present, but aic_zlp_quirk is not loaded"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo " 未发现活动的 aic_btusb 配置、规则或模块 (正常)"
|
echo " Target 368b:8d81 not present; quirk is not required"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 8. 建议
|
echo "=== Assessment ==="
|
||||||
echo "=== 诊断建议 ==="
|
if ! lsmod | awk '{print $1}' | grep -qx 'aic_load_fw'; then
|
||||||
echo ""
|
echo "- aic_load_fw is not loaded; run: sudo modprobe aic8800_fdrv"
|
||||||
|
fi
|
||||||
# 检查 aic_load_fw 是否加载 (它负责上传 WiFi + BT 固件)
|
if [ "$bt_interface_found" = true ] && [ "$btusb_bound" = false ]; then
|
||||||
if ! lsmod | grep -q "^aic_load_fw"; then
|
echo "- A Bluetooth USB interface exists but is not bound to btusb."
|
||||||
echo "⚠️ aic_load_fw 未加载"
|
echo " Check for a btusb blacklist, then try: sudo modprobe btusb"
|
||||||
echo " 该模块负责把蓝牙固件上传到芯片, 必须先于 btusb 工作"
|
fi
|
||||||
echo " 解决方案: sudo modprobe aic_load_fw"
|
if dmesg 2>/dev/null | grep -iE 'hci[0-9]+:.*(command|opcode|tx).*timed out|hci[0-9]+: link tx timeout' | tail -1 | grep -q .; then
|
||||||
echo ""
|
echo "- HCI timeout detected. Confirm that aic_load_fw uploaded the firmware before btusb bound."
|
||||||
|
echo " Also check for obsolete aic_btusb configuration above."
|
||||||
|
fi
|
||||||
|
if [ "$bt_interface_found" = false ]; then
|
||||||
|
echo "- No Bluetooth HCI USB interface was found. This is normal for a Wi-Fi-only adapter."
|
||||||
|
fi
|
||||||
|
if [ "$zlp_target_found" = true ] && [ ! -d /sys/module/aic_zlp_quirk ]; then
|
||||||
|
echo "- Device 368b:8d81 requires the ACL ZLP quirk, but the module is not loaded."
|
||||||
|
echo " Try: sudo modprobe aic_zlp_quirk"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 检查 HCI_Reset 超时 (典型症状: 固件未上传却让 btusb 接管)
|
echo "=== Diagnostics complete ==="
|
||||||
if dmesg | grep -iE "hci0:.*command (0x|tx) timed out|hci0.*opcode.*0x0c03" | tail -5 | grep -q .; then
|
|
||||||
echo "⚠️ 检测到 HCI 命令超时 (HCI_Reset/-110)"
|
|
||||||
echo " 常见原因:"
|
|
||||||
echo " a) 旧 aic_btusb 配置或 udev 规则残留 (见第 7 项)"
|
|
||||||
echo " b) aic_load_fw 没有先把蓝牙固件 patch 上传到芯片"
|
|
||||||
echo " c) usb_modeswitch 没把 1111:1111 切换到真实 VID:PID"
|
|
||||||
echo " 排查: 看上面第 5 项日志, 应能看到 fw_patch_table_8800d80 / fw_adid 字样"
|
|
||||||
echo " 临时缓解: 拔插一次设备 (软件复位/飞行模式切换通常无法救活)"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# btusb 是否已接管 BT 接口 (这是正常预期)
|
|
||||||
if lsmod | grep -q "^btusb"; then
|
|
||||||
echo "✅ btusb 已加载 (正常, 本分支由 btusb 接管蓝牙)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "=== 诊断完成 ==="
|
|
||||||
|
|||||||
@@ -13,4 +13,9 @@ BUILT_MODULE_NAME[1]="aic_load_fw"
|
|||||||
BUILT_MODULE_LOCATION[1]="drivers/aic8800/aic_load_fw"
|
BUILT_MODULE_LOCATION[1]="drivers/aic8800/aic_load_fw"
|
||||||
DEST_MODULE_LOCATION[1]="/updates/dkms"
|
DEST_MODULE_LOCATION[1]="/updates/dkms"
|
||||||
|
|
||||||
|
# Device-scoped standard-btusb ACL bulk TX ZLP quirk (368b:8d81 only)
|
||||||
|
BUILT_MODULE_NAME[2]="aic_zlp_quirk"
|
||||||
|
BUILT_MODULE_LOCATION[2]="drivers/aic8800/aic_zlp_quirk"
|
||||||
|
DEST_MODULE_LOCATION[2]="/updates/dkms"
|
||||||
|
|
||||||
AUTOINSTALL="yes"
|
AUTOINSTALL="yes"
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
CONFIG_AIC_LOADFW_SUPPORT := m
|
CONFIG_AIC_LOADFW_SUPPORT := m
|
||||||
CONFIG_AIC8800_WLAN_SUPPORT := m
|
CONFIG_AIC8800_WLAN_SUPPORT := m
|
||||||
|
CONFIG_AIC_ZLP_QUIRK := m
|
||||||
|
|
||||||
obj-$(CONFIG_AIC_LOADFW_SUPPORT) += aic_load_fw/
|
obj-$(CONFIG_AIC_LOADFW_SUPPORT) += aic_load_fw/
|
||||||
obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/
|
obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/
|
||||||
|
obj-$(CONFIG_AIC_ZLP_QUIRK) += aic_zlp_quirk/
|
||||||
|
|
||||||
########## config option ##########
|
########## config option ##########
|
||||||
export CONFIG_USE_FW_REQUEST = n
|
export CONFIG_USE_FW_REQUEST = n
|
||||||
@@ -51,6 +53,7 @@ KVER ?= $(shell uname -r)
|
|||||||
KDIR ?= /lib/modules/$(KVER)/build
|
KDIR ?= /lib/modules/$(KVER)/build
|
||||||
PWD = $(shell pwd)
|
PWD = $(shell pwd)
|
||||||
MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
|
MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
|
||||||
|
BTMODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/bluetooth/aic8800
|
||||||
SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/ -e s/loongarch64/loongarch/ -e s/loong64/loongarch/ -e s/riscv64/riscv/)
|
SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/ -e s/loongarch64/loongarch/ -e s/loong64/loongarch/ -e s/riscv64/riscv/)
|
||||||
ARCH ?= $(SUBARCH)
|
ARCH ?= $(SUBARCH)
|
||||||
CROSS_COMPILE ?=
|
CROSS_COMPILE ?=
|
||||||
@@ -58,8 +61,6 @@ endif
|
|||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
|
|
||||||
MAKEFLAGS +=-j$(shell nproc)
|
|
||||||
|
|
||||||
KERNEL_AUTOCONF := $(KDIR)/include/config/auto.conf
|
KERNEL_AUTOCONF := $(KDIR)/include/config/auto.conf
|
||||||
KERNEL_CONFIG := $(KDIR)/.config
|
KERNEL_CONFIG := $(KDIR)/.config
|
||||||
KERNEL_CC_IS_CLANG := $(shell if [ -r "$(KERNEL_AUTOCONF)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_AUTOCONF)"; then echo y; elif [ -r "$(KERNEL_CONFIG)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_CONFIG)"; then echo y; fi)
|
KERNEL_CC_IS_CLANG := $(shell if [ -r "$(KERNEL_AUTOCONF)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_AUTOCONF)"; then echo y; elif [ -r "$(KERNEL_CONFIG)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_CONFIG)"; then echo y; fi)
|
||||||
@@ -78,16 +79,20 @@ modules:
|
|||||||
|
|
||||||
install:
|
install:
|
||||||
mkdir -p $(MODDESTDIR)
|
mkdir -p $(MODDESTDIR)
|
||||||
|
mkdir -p $(BTMODDESTDIR)
|
||||||
install -p -m 644 aic_load_fw/aic_load_fw.ko $(MODDESTDIR)/
|
install -p -m 644 aic_load_fw/aic_load_fw.ko $(MODDESTDIR)/
|
||||||
install -p -m 644 aic8800_fdrv/aic8800_fdrv.ko $(MODDESTDIR)/
|
install -p -m 644 aic8800_fdrv/aic8800_fdrv.ko $(MODDESTDIR)/
|
||||||
|
install -p -m 644 aic_zlp_quirk/aic_zlp_quirk.ko $(BTMODDESTDIR)/
|
||||||
/sbin/depmod -a ${KVER}
|
/sbin/depmod -a ${KVER}
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -rfv $(MODDESTDIR)/aic_load_fw.ko
|
rm -rfv $(MODDESTDIR)/aic_load_fw.ko
|
||||||
rm -rfv $(MODDESTDIR)/aic8800_fdrv.ko
|
rm -rfv $(MODDESTDIR)/aic8800_fdrv.ko
|
||||||
|
rm -rfv $(BTMODDESTDIR)/aic_zlp_quirk.ko
|
||||||
/sbin/depmod -a ${KVER}
|
/sbin/depmod -a ${KVER}
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
cd aic_load_fw/;make clean;cd ..
|
cd aic_load_fw/;make clean;cd ..
|
||||||
cd aic8800_fdrv/;make clean;cd ..
|
cd aic8800_fdrv/;make clean;cd ..
|
||||||
|
cd aic_zlp_quirk/;make clean;cd ..
|
||||||
rm -rf modules.order Module.symvers .modules.order.cmd .Module.symvers.cmd .tmp_versions/
|
rm -rf modules.order Module.symvers .modules.order.cmd .Module.symvers.cmd .tmp_versions/
|
||||||
|
|||||||
@@ -2,6 +2,16 @@ EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS)
|
|||||||
EXTRA_CFLAGS += -Wno-implicit-fallthrough
|
EXTRA_CFLAGS += -Wno-implicit-fallthrough
|
||||||
#EXTRA_CFLAGS += -Wno-unused-variable
|
#EXTRA_CFLAGS += -Wno-unused-variable
|
||||||
|
|
||||||
|
# OpenWrt may build a newer cfg80211 backport on an older kernel.
|
||||||
|
# Set this to the wireless stack's version, e.g. CFG80211_VERSION=6.18.26.
|
||||||
|
ifneq ($(strip $(CFG80211_VERSION)),)
|
||||||
|
aicwf_cfg80211_version := $(subst ., ,$(CFG80211_VERSION))
|
||||||
|
ifneq ($(words $(aicwf_cfg80211_version)),3)
|
||||||
|
$(error CFG80211_VERSION must have the form major.minor.patch)
|
||||||
|
endif
|
||||||
|
ccflags-y += '-DAICWF_CFG80211_VERSION_CODE=KERNEL_VERSION($(word 1,$(aicwf_cfg80211_version)),$(word 2,$(aicwf_cfg80211_version)),$(word 3,$(aicwf_cfg80211_version)))'
|
||||||
|
endif
|
||||||
|
|
||||||
RWNX_VERS_NUM := 6.4.3.0
|
RWNX_VERS_NUM := 6.4.3.0
|
||||||
|
|
||||||
CONFIG_AIC8800_WLAN_SUPPORT = m
|
CONFIG_AIC8800_WLAN_SUPPORT = m
|
||||||
@@ -74,7 +84,11 @@ CONFIG_VHT_FOR_OLD_KERNEL = n
|
|||||||
CONFIG_COEX = y
|
CONFIG_COEX = y
|
||||||
CONFIG_ALIGN_8BYTES = y
|
CONFIG_ALIGN_8BYTES = y
|
||||||
CONFIG_TXRX_THREAD_PRIO = y
|
CONFIG_TXRX_THREAD_PRIO = y
|
||||||
|
ifdef CONFIG_ARCH_SUN60IW2P1
|
||||||
|
CONFIG_USB_ALIGN_DATA = n
|
||||||
|
else
|
||||||
CONFIG_USB_ALIGN_DATA = y
|
CONFIG_USB_ALIGN_DATA = y
|
||||||
|
endif
|
||||||
CONFIG_RX_TASKLET = n
|
CONFIG_RX_TASKLET = n
|
||||||
CONFIG_TX_TASKLET = n
|
CONFIG_TX_TASKLET = n
|
||||||
CONFIG_RX_NETIF_RECV_SKB = y
|
CONFIG_RX_NETIF_RECV_SKB = y
|
||||||
@@ -88,7 +102,11 @@ CONFIG_WOWLAN ?= n
|
|||||||
CONFIG_USB_RX_AGGR = n
|
CONFIG_USB_RX_AGGR = n
|
||||||
CONFIG_USB_TX_AGGR = n
|
CONFIG_USB_TX_AGGR = n
|
||||||
|
|
||||||
|
ifdef CONFIG_ARCH_SUN60IW2P1
|
||||||
|
CONFIG_USB_NO_TRANS_DMA_MAP = y
|
||||||
|
else
|
||||||
CONFIG_USB_NO_TRANS_DMA_MAP = n
|
CONFIG_USB_NO_TRANS_DMA_MAP = n
|
||||||
|
endif
|
||||||
CONFIG_GPIO_WAKEUP = n
|
CONFIG_GPIO_WAKEUP = n
|
||||||
CONFIG_CREATE_TRACE_POINTS = n
|
CONFIG_CREATE_TRACE_POINTS = n
|
||||||
CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y
|
CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y
|
||||||
@@ -154,7 +172,7 @@ CONFIG_RWNX_BCMC ?= y
|
|||||||
|
|
||||||
# Enable Monitor+Data interface support (need FW support)
|
# Enable Monitor+Data interface support (need FW support)
|
||||||
CONFIG_RWNX_MON_DATA =n
|
CONFIG_RWNX_MON_DATA =n
|
||||||
CONFIG_RWNX_MON_XMIT ?= n
|
CONFIG_RWNX_MON_XMIT ?= y
|
||||||
CONFIG_RWNX_MON_RXFILTER ?= n
|
CONFIG_RWNX_MON_RXFILTER ?= n
|
||||||
|
|
||||||
CONFIG_FILTER_TCP_ACK =y
|
CONFIG_FILTER_TCP_ACK =y
|
||||||
@@ -349,8 +367,6 @@ ccflags-$(CONFIG_TEMP_CONTROL) += -DCONFIG_TEMP_CONTROL
|
|||||||
ccflags-$(CONFIG_POWER_LIMIT) += -DCONFIG_POWER_LIMIT
|
ccflags-$(CONFIG_POWER_LIMIT) += -DCONFIG_POWER_LIMIT
|
||||||
ccflags-$(CONFIG_EXT_FEM_8800DCDW) += -DCONFIG_EXT_FEM_8800DCDW
|
ccflags-$(CONFIG_EXT_FEM_8800DCDW) += -DCONFIG_EXT_FEM_8800DCDW
|
||||||
ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN
|
ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN
|
||||||
MAKEFLAGS +=-j$(shell nproc)
|
|
||||||
|
|
||||||
# Platform support list
|
# Platform support list
|
||||||
CONFIG_PLATFORM_ROCKCHIP ?= n
|
CONFIG_PLATFORM_ROCKCHIP ?= n
|
||||||
CONFIG_PLATFORM_ALLWINNER ?= n
|
CONFIG_PLATFORM_ALLWINNER ?= n
|
||||||
|
|||||||
@@ -1832,7 +1832,7 @@ void set_vendor_extension_ie(char *command){
|
|||||||
|
|
||||||
}
|
}
|
||||||
#endif//CONFIG_SET_VENDOR_EXTENSION_IE
|
#endif//CONFIG_SET_VENDOR_EXTENSION_IE
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, struct net_device *dev,
|
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, struct net_device *dev,
|
||||||
struct cfg80211_chan_def *chandef);
|
struct cfg80211_chan_def *chandef);
|
||||||
#else
|
#else
|
||||||
@@ -1840,7 +1840,7 @@ int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
|||||||
struct cfg80211_chan_def *chandef);
|
struct cfg80211_chan_def *chandef);
|
||||||
#endif
|
#endif
|
||||||
int rwnx_atoi2(char *value, int c_len);
|
int rwnx_atoi2(char *value, int c_len);
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter)
|
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter)
|
||||||
#else
|
#else
|
||||||
void set_mon_chan(struct rwnx_vif *vif, char *parameter)
|
void set_mon_chan(struct rwnx_vif *vif, char *parameter)
|
||||||
@@ -1867,7 +1867,7 @@ void set_mon_chan(struct rwnx_vif *vif, char *parameter)
|
|||||||
chandef->center_freq1 = chandef->chan->center_freq;
|
chandef->center_freq1 = chandef->chan->center_freq;
|
||||||
chandef->center_freq2 = 0;
|
chandef->center_freq2 = 0;
|
||||||
|
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, dev, chandef);
|
rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, dev, chandef);
|
||||||
#else
|
#else
|
||||||
rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, chandef);
|
rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, chandef);
|
||||||
@@ -2136,7 +2136,7 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
|
|||||||
char *set_parameter;
|
char *set_parameter;
|
||||||
skip = strlen(CMD_SET_MON_FREQ) + 1;
|
skip = strlen(CMD_SET_MON_FREQ) + 1;
|
||||||
set_parameter = command + skip;
|
set_parameter = command + skip;
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
set_mon_chan(vif, net, set_parameter);
|
set_mon_chan(vif, net, set_parameter);
|
||||||
#else
|
#else
|
||||||
set_mon_chan(vif, set_parameter);
|
set_mon_chan(vif, set_parameter);
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val);
|
|||||||
unsigned int command_strtoul(const char *cp, char **endp, unsigned int base);
|
unsigned int command_strtoul(const char *cp, char **endp, unsigned int base);
|
||||||
int str_starts(const char *str, const char *start);
|
int str_starts(const char *str, const char *start);
|
||||||
int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len);
|
int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len);
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter);
|
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter);
|
||||||
#else
|
#else
|
||||||
void set_mon_chan(struct rwnx_vif *vif, char *parameter);
|
void set_mon_chan(struct rwnx_vif *vif, char *parameter);
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){
|
|||||||
char *filename = FW_USERCONFIG_NAME_8800D80;
|
char *filename = FW_USERCONFIG_NAME_8800D80;
|
||||||
|
|
||||||
#ifndef ANDROID_PLATFORM
|
#ifndef ANDROID_PLATFORM
|
||||||
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80");
|
if (strlcat(aic_fw_path, "/aic8800D80", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||||
|
return -ENAMETOOLONG;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ int rwnx_plat_userconfig_load_8800d80x2(struct rwnx_hw *rwnx_hw){
|
|||||||
char *filename = FW_USERCONFIG_NAME_8800D80X2;
|
char *filename = FW_USERCONFIG_NAME_8800D80X2;
|
||||||
|
|
||||||
#ifndef ANDROID_PLATFORM
|
#ifndef ANDROID_PLATFORM
|
||||||
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80X2");
|
if (strlcat(aic_fw_path, "/aic8800D80X2", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||||
|
return -ENAMETOOLONG;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
||||||
|
|||||||
@@ -45,6 +45,8 @@
|
|||||||
#define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt"
|
#define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt"
|
||||||
#define FW_POWERLIMIT_NAME_8800DC "aic_powerlimit_8800dc.txt"
|
#define FW_POWERLIMIT_NAME_8800DC "aic_powerlimit_8800dc.txt"
|
||||||
#define FW_POWERLIMIT_NAME_8800DW "aic_powerlimit_8800dw.txt"
|
#define FW_POWERLIMIT_NAME_8800DW "aic_powerlimit_8800dw.txt"
|
||||||
|
#define FW_USERCONFIG_NAME_8800DW_W311 "aic_userconfig_8800dw_w311.txt"
|
||||||
|
#define FW_USERCONFIG_NAME_8800DW_U2 "aic_userconfig_8800dw_u2.txt"
|
||||||
|
|
||||||
#ifdef CONFIG_LOAD_BT_PATCH_IN_FDRV
|
#ifdef CONFIG_LOAD_BT_PATCH_IN_FDRV
|
||||||
enum aicbt_patch_table_type {
|
enum aicbt_patch_table_type {
|
||||||
@@ -167,7 +169,6 @@ u32 syscfg_tbl_masked_8800dc[][3] = {
|
|||||||
{0x700010A0, (0x1 << 11), (0x1 << 11)},
|
{0x700010A0, (0x1 << 11), (0x1 << 11)},
|
||||||
{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
|
{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
|
||||||
{0x70001038, (0x1 << 8), (0x1 << 8)},
|
{0x70001038, (0x1 << 8), (0x1 << 8)},
|
||||||
{0x70001084, (0x3 << 13), (0x0 << 13)},
|
|
||||||
{0x70001094, (0x3 << 2), (0x0 << 2)},
|
{0x70001094, (0x3 << 2), (0x0 << 2)},
|
||||||
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
|
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
|
||||||
{0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)),
|
{0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)),
|
||||||
@@ -185,7 +186,6 @@ u32 syscfg_tbl_masked_8800dc[][3] = {
|
|||||||
{0x700010A0, (0x1 << 11), (0x1 << 11)},
|
{0x700010A0, (0x1 << 11), (0x1 << 11)},
|
||||||
{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
|
{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
|
||||||
{0x70001038, (0x1 << 8), (0x1 << 8)},
|
{0x70001038, (0x1 << 8), (0x1 << 8)},
|
||||||
{0x70001084, (0x3 << 13), (0x0 << 13)},
|
|
||||||
{0x70001094, (0x3 << 2), (0x0 << 2)},
|
{0x70001094, (0x3 << 2), (0x0 << 2)},
|
||||||
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
|
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
|
||||||
{0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)),
|
{0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)),
|
||||||
@@ -211,7 +211,6 @@ u32 syscfg_tbl_masked_8800dc_h[][3] = {
|
|||||||
{0x700010A0, (0x1 << 11), (0x1 << 11)},
|
{0x700010A0, (0x1 << 11), (0x1 << 11)},
|
||||||
//{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
|
//{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
|
||||||
{0x70001038, (0x1 << 8), (0x1 << 8)},
|
{0x70001038, (0x1 << 8), (0x1 << 8)},
|
||||||
{0x70001084, (0x3 << 13), (0x0 << 13)},
|
|
||||||
{0x70001094, (0x3 << 2), (0x0 << 2)},
|
{0x70001094, (0x3 << 2), (0x0 << 2)},
|
||||||
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
|
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
|
||||||
#if defined(CONFIG_VRF_DCDC_MODE)
|
#if defined(CONFIG_VRF_DCDC_MODE)
|
||||||
@@ -243,6 +242,7 @@ u32 syscfg_tbl_8800dc[][2] = {
|
|||||||
|
|
||||||
u32 patch_tbl_wifisetting[][2] =
|
u32 patch_tbl_wifisetting[][2] =
|
||||||
{
|
{
|
||||||
|
{0x0004, 0x00020010}, //wdt_reboot_type, wdt_period_sec
|
||||||
#if !defined(CONFIG_FPGA_VERIFICATION)
|
#if !defined(CONFIG_FPGA_VERIFICATION)
|
||||||
{0x0090, 0x0013FC00}, //rx_ringbuf_start2
|
{0x0090, 0x0013FC00}, //rx_ringbuf_start2
|
||||||
#endif
|
#endif
|
||||||
@@ -251,9 +251,10 @@ u32 patch_tbl_wifisetting[][2] =
|
|||||||
{0x0120, 0x140A0100}, //usb agg tx params(total cnt, aggr cnt, out en, global out nak)
|
{0x0120, 0x140A0100}, //usb agg tx params(total cnt, aggr cnt, out en, global out nak)
|
||||||
#endif //CONFIG_USB_TX_AGGR
|
#endif //CONFIG_USB_TX_AGGR
|
||||||
{0x00b0, 0xAD180100},
|
{0x00b0, 0xAD180100},
|
||||||
#ifdef CONFIG_PRBREQ_REPORT
|
#ifdef CONFIG_BAND_STEERING
|
||||||
{0x0138, 0x00010a00}, //apm probe resp offload en
|
{0x0138, 0x00010a00}, //apm probe resp offload en
|
||||||
#endif
|
#endif
|
||||||
|
{0x0084, 0x00000040},
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 jump_tbl[][2] =
|
u32 jump_tbl[][2] =
|
||||||
@@ -1871,104 +1872,104 @@ const uint32_t txgain_map_femkct[96] =
|
|||||||
const uint32_t txgain_map_femkct_h[96] =
|
const uint32_t txgain_map_femkct_h[96] =
|
||||||
{
|
{
|
||||||
//11b
|
//11b
|
||||||
0x00ffd86c,//15
|
0x00ffd872,//15
|
||||||
0x00ffd879,//16
|
0x00ffd880,//16
|
||||||
0x00ffd96c,//17
|
0x00ffd972,//17
|
||||||
0x00ffd979,//18
|
0x00ffd980,//18
|
||||||
0x00ffd988,//19
|
0x00ffd990,//19
|
||||||
0x00ffda6c,//20
|
0x00ffda72,//20
|
||||||
0x00ffda79,//21
|
0x00ffda80,//21
|
||||||
0x00ffdb6c,//22
|
0x00ffdb72,//22
|
||||||
0x00ffdb79,//23
|
0x00ffdb80,//23
|
||||||
0x00ffdc6c,//24
|
0x00ffdc72,//24
|
||||||
0x00ffdc79,//25
|
0x00ffdc80,//25
|
||||||
0x00ffdd6c,//26
|
0x00ffdd72,//26
|
||||||
0x00ffdd79,//27
|
0x00ffdd80,//27
|
||||||
0x00ffde6c,//28
|
0x00ffde72,//28
|
||||||
0x00ffde79,//29
|
0x00ffde80,//29
|
||||||
0x00ffdf6c,//30
|
0x00ffdf72,//30
|
||||||
0x00ffd06c,//-1
|
0x00ffd072,//-1
|
||||||
0x00ffd06c,//0
|
0x00ffd072,//0
|
||||||
0x00ffd079,//1
|
0x00ffd080,//1
|
||||||
0x00ffd16c,//2
|
0x00ffd172,//2
|
||||||
0x00ffd179,//3
|
0x00ffd180,//3
|
||||||
0x00ffd26c,//4
|
0x00ffd272,//4
|
||||||
0x00ffd279,//5
|
0x00ffd280,//5
|
||||||
0x00ffd372,//6
|
0x00ffd379,//6
|
||||||
0x00ffd467,//7
|
0x00ffd46d,//7
|
||||||
0x00ffd472,//8
|
0x00ffd479,//8
|
||||||
0x00ffd56c,//9
|
0x00ffd572,//9
|
||||||
0x00ffd579,//10
|
0x00ffd580,//10
|
||||||
0x00ffd66c,//11
|
0x00ffd672,//11
|
||||||
0x00ffd679,//12
|
0x00ffd680,//12
|
||||||
0x00ffd76c,//13
|
0x00ffd772,//13
|
||||||
0x00ffd779,//14
|
0x00ffd780,//14
|
||||||
//high
|
//high
|
||||||
0x00ffc879,//11
|
0x00ffc880,//11
|
||||||
0x00ffc96c,//12
|
0x00ffc972,//12
|
||||||
0x00ffc979,//13
|
0x00ffc980,//13
|
||||||
0x00ffca6c,//14
|
0x00ffca72,//14
|
||||||
0x00ffca79,//15
|
0x00ffca80,//15
|
||||||
0x00ffcb6c,//16
|
0x00ffcb72,//16
|
||||||
0x00ffcb79,//17
|
0x00ffcb80,//17
|
||||||
0x00ffcc6c,//18
|
0x00ffcc72,//18
|
||||||
0x00ffcc79,//19
|
0x00ffcc80,//19
|
||||||
0x00ffcc88,//20
|
0x00ffcc90,//20
|
||||||
0x00ffcd6c,//21
|
0x00ffcd72,//21
|
||||||
0x00ffcd79,//22
|
0x00ffcd80,//22
|
||||||
0x00ffce6c,//23
|
0x00ffce72,//23
|
||||||
0x00ffce79,//24
|
0x00ffce80,//24
|
||||||
0x00ffcf6c,//25
|
0x00ffcf72,//25
|
||||||
0x00ffcf79,//26
|
0x00ffcf80,//26
|
||||||
0x00ffc079,//-5
|
0x00ffc080,//-5
|
||||||
0x00ffc16c,//-4
|
0x00ffc172,//-4
|
||||||
0x00ffc179,//-3
|
0x00ffc180,//-3
|
||||||
0x00ffc26c,//-2
|
0x00ffc272,//-2
|
||||||
0x00ffc279,//-1
|
0x00ffc280,//-1
|
||||||
0x00ffc36c,//0
|
0x00ffc372,//0
|
||||||
0x00ffc379,//1
|
0x00ffc380,//1
|
||||||
0x00ffc46c,//2
|
0x00ffc472,//2
|
||||||
0x00ffc479,//3
|
0x00ffc480,//3
|
||||||
0x00ffc56c,//4
|
0x00ffc572,//4
|
||||||
0x00ffc579,//5
|
0x00ffc580,//5
|
||||||
0x00ffc66c,//6
|
0x00ffc672,//6
|
||||||
0x00ffc679,//7
|
0x00ffc680,//7
|
||||||
0x00ffc76c,//8
|
0x00ffc772,//8
|
||||||
0x00ffc779,//9
|
0x00ffc780,//9
|
||||||
0x00ffc86c,//10
|
0x00ffc872,//10
|
||||||
//low
|
//low
|
||||||
0x00ffc879,//11
|
0x00ffc880,//11
|
||||||
0x00ffc96c,//12
|
0x00ffc972,//12
|
||||||
0x00ffc979,//13
|
0x00ffc980,//13
|
||||||
0x00ffca6c,//14
|
0x00ffca72,//14
|
||||||
0x00ffca79,//15
|
0x00ffca80,//15
|
||||||
0x00ffcb6c,//16
|
0x00ffcb72,//16
|
||||||
0x00ffcb79,//17
|
0x00ffcb80,//17
|
||||||
0x00ffcc6c,//18
|
0x00ffcc72,//18
|
||||||
0x00ffcc79,//19
|
0x00ffcc80,//19
|
||||||
0x00ffcc88,//20
|
0x00ffcc90,//20
|
||||||
0x00ffcd6c,//21
|
0x00ffcd72,//21
|
||||||
0x00ffcd79,//22
|
0x00ffcd80,//22
|
||||||
0x00ffce6c,//23
|
0x00ffce72,//23
|
||||||
0x00ffce79,//24
|
0x00ffce80,//24
|
||||||
0x00ffcf6c,//25
|
0x00ffcf72,//25
|
||||||
0x00ffcf79,//26
|
0x00ffcf80,//26
|
||||||
0x00ffc079,//-5
|
0x00ffc080,//-5
|
||||||
0x00ffc16c,//-4
|
0x00ffc172,//-4
|
||||||
0x00ffc179,//-3
|
0x00ffc180,//-3
|
||||||
0x00ffc26c,//-2
|
0x00ffc272,//-2
|
||||||
0x00ffc279,//-1
|
0x00ffc280,//-1
|
||||||
0x00ffc36c,//0
|
0x00ffc372,//0
|
||||||
0x00ffc379,//1
|
0x00ffc380,//1
|
||||||
0x00ffc46c,//2
|
0x00ffc472,//2
|
||||||
0x00ffc479,//3
|
0x00ffc480,//3
|
||||||
0x00ffc56c,//4
|
0x00ffc572,//4
|
||||||
0x00ffc579,//5
|
0x00ffc580,//5
|
||||||
0x00ffc66c,//6
|
0x00ffc672,//6
|
||||||
0x00ffc679,//7
|
0x00ffc680,//7
|
||||||
0x00ffc76c,//8
|
0x00ffc772,//8
|
||||||
0x00ffc779,//9
|
0x00ffc780,//9
|
||||||
0x00ffc86c,//10
|
0x00ffc872,//10
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2204,141 +2205,6 @@ uint32_t wifi_txgain_table_24g_1_8800dcdw_femkct[32] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_5M10M
|
|
||||||
u32 wifi_rxgain_table_24g_dcdw_5m[64] = {
|
|
||||||
0x82f282d1,//index 0
|
|
||||||
0x9591a200,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x42f282d1,//index 1
|
|
||||||
0x95923400,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x22f282d1,//index 2
|
|
||||||
0x9592c600,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282d1,//index 3
|
|
||||||
0x9591a200,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x06f282d1,//index 4
|
|
||||||
0x9591a200,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x0ef282d1,//index 5
|
|
||||||
0x9591a200,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x0ef282d3,//index 6
|
|
||||||
0x95923400,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x0ef282d7,//index 7
|
|
||||||
0x9595a200,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282d2,//index 8
|
|
||||||
0x95951000,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282f4,//index 9
|
|
||||||
0x95951000,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282e6,//index 10
|
|
||||||
0x9595a200,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282e6,//index 11
|
|
||||||
0x9599a200,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282e6,//index 12
|
|
||||||
0x959da200,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282e6,//index 13
|
|
||||||
0x959f5800,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x06f282e6,//index 14
|
|
||||||
0x959f5800,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x0ef282e6,//index 15
|
|
||||||
0x959f5800,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0
|
|
||||||
};
|
|
||||||
|
|
||||||
u32 wifi_rxgain_table_24g_dcdw_10m[64] = {
|
|
||||||
0x82f282d1,//index 0
|
|
||||||
0x9591a320,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x42f282d1,//index 1
|
|
||||||
0x95923520,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x22f282d1,//index 2
|
|
||||||
0x9592c720,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282d1,//index 3
|
|
||||||
0x9591a320,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x06f282d1,//index 4
|
|
||||||
0x9591a320,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x0ef282d1,//index 5
|
|
||||||
0x9591a320,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x0ef282d3,//index 6
|
|
||||||
0x95923520,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x0ef282d7,//index 7
|
|
||||||
0x9595a320,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282d2,//index 8
|
|
||||||
0x95951120,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282f4,//index 9
|
|
||||||
0x95951120,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282e6,//index 10
|
|
||||||
0x9595a320,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282e6,//index 11
|
|
||||||
0x9599a320,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282e6,//index 12
|
|
||||||
0x959da320,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x02f282e6,//index 13
|
|
||||||
0x959f5920,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x06f282e6,//index 14
|
|
||||||
0x959f5920,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0,
|
|
||||||
0x0ef282e6,//index 15
|
|
||||||
0x959f5920,
|
|
||||||
0x80808419,
|
|
||||||
0x000000f0
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = {
|
u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = {
|
||||||
0x82f282d1,//index 0
|
0x82f282d1,//index 0
|
||||||
0x9591a324,
|
0x9591a324,
|
||||||
@@ -3057,13 +2923,7 @@ int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_c
|
|||||||
|
|
||||||
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32, 0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256)))
|
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32, 0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256)))
|
||||||
return -1;
|
return -1;
|
||||||
#ifdef CONFIG_5M10M
|
|
||||||
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 0, (u8_l *)wifi_rxgain_table_24g_dcdw_5m, 256)))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 48, 0, (u8_l *)wifi_rxgain_table_24g_dcdw_10m, 256)))
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
|
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -3178,35 +3038,61 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out)
|
|||||||
uint32_t misc_ram_addr;
|
uint32_t misc_ram_addr;
|
||||||
uint32_t ram_base_addr, ram_word_cnt;
|
uint32_t ram_base_addr, ram_word_cnt;
|
||||||
uint32_t bit_mask[4];
|
uint32_t bit_mask[4];
|
||||||
|
uint32_t dpd_info_read_addr = 0xfe004;
|
||||||
|
uint32_t boot_argc_read_addr = 0x1220f0;
|
||||||
|
uint32_t flash_size_mem_addr = 0x40038030;
|
||||||
|
uint8_t flash_size = 0;
|
||||||
int i;
|
int i;
|
||||||
if (valid_out) {
|
if (valid_out) {
|
||||||
*valid_out = 0;
|
*valid_out = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "issue71: checking legacy V3 DPD result\n");
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, boot_argc_read_addr, &cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "boot argc [0x%x] rd fail: %d\n", boot_argc_read_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO, "issue71: boot argc=0x%x\n", cfm.memdata);
|
||||||
|
if (cfm.memdata & 0x10) {
|
||||||
|
if (valid_out) {
|
||||||
|
*valid_out = 1;
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO, "issue71: boot arguments mark DPD result valid\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (chip_mcu_id) {
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, flash_size_mem_addr, &cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "flash size[0x%x] rd fail: %d\n", flash_size_mem_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
flash_size = cfm.memdata & 0xff;
|
||||||
|
if (flash_size == 0x16) {
|
||||||
|
dpd_info_read_addr += 0x4300000;
|
||||||
|
} else if (flash_size == 0x15) {
|
||||||
|
dpd_info_read_addr += 0x4100000;
|
||||||
|
} else if (flash_size == 0x18) {
|
||||||
|
dpd_info_read_addr += 0x4700000;
|
||||||
|
} else {
|
||||||
|
dpd_info_read_addr += 0x4100000;
|
||||||
|
}
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, dpd_info_read_addr, &cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "dpd info [0x%x] rd fail: %d\n", dpd_info_read_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO,
|
||||||
|
"issue71: flash size=0x%x, DPD info [0x%x]=0x%x\n",
|
||||||
|
flash_size, dpd_info_read_addr, cfm.memdata);
|
||||||
|
if (cfm.memdata & (1<<7)) {
|
||||||
|
if (valid_out) {
|
||||||
|
*valid_out = 1;
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO, "issue71: legacy V3 flash DPD result is valid\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (testmode == FW_RFTEST_MODE) {
|
if (testmode == FW_RFTEST_MODE) {
|
||||||
uint32_t vect1 = 0;
|
|
||||||
uint32_t vect2 = 0;
|
|
||||||
cfg_base = RAM_LMAC_FW_ADDR + 0x0004;
|
|
||||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm);
|
|
||||||
if (ret) {
|
|
||||||
AICWFDBG(LOGERROR, "cfg_base:%x vcet1 rd fail: %d\n", cfg_base, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
vect1 = cfm.memdata;
|
|
||||||
if ((vect1 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) {
|
|
||||||
AICWFDBG(LOGERROR, "vect1 invalid: %x\n", vect1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
cfg_base = RAM_LMAC_FW_ADDR + 0x0008;
|
|
||||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm);
|
|
||||||
if (ret) {
|
|
||||||
AICWFDBG(LOGERROR, "cfg_base:%x vcet2 rd fail: %d\n", cfg_base, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
vect2 = cfm.memdata;
|
|
||||||
if ((vect2 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) {
|
|
||||||
AICWFDBG(LOGERROR, "vect2 invalid: %x\n", vect2);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
|
cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
|
||||||
}
|
}
|
||||||
// init misc ram
|
// init misc ram
|
||||||
@@ -3235,6 +3121,7 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out)
|
|||||||
*valid_out = 1;
|
*valid_out = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3630,7 +3517,19 @@ int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw){
|
|||||||
int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){
|
int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){
|
||||||
int size;
|
int size;
|
||||||
u32 *dst=NULL;
|
u32 *dst=NULL;
|
||||||
|
u16 pid = le16_to_cpu(rwnx_hw->usbdev->udev->descriptor.idProduct);
|
||||||
char *filename = FW_USERCONFIG_NAME_8800DW;
|
char *filename = FW_USERCONFIG_NAME_8800DW;
|
||||||
|
if (pid == USB_PRODUCT_ID_TENDA
|
||||||
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS3
|
||||||
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS5
|
||||||
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS6) {
|
||||||
|
filename = FW_USERCONFIG_NAME_8800DW_W311;
|
||||||
|
} else if (pid == USB_PRODUCT_ID_TENDA_U2
|
||||||
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS1
|
||||||
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS2
|
||||||
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS4) {
|
||||||
|
filename = FW_USERCONFIG_NAME_8800DW_U2;
|
||||||
|
}
|
||||||
|
|
||||||
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
||||||
|
|
||||||
@@ -3684,7 +3583,7 @@ int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id
|
|||||||
/* Copy the file on the Embedded side */
|
/* Copy the file on the Embedded side */
|
||||||
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
rwnx_plat_powerlimit_parsing((char *)dst, size);
|
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code);
|
||||||
|
|
||||||
rwnx_release_firmware_common(&dst);
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
@@ -3739,6 +3638,7 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){
|
|||||||
array3_tbl_t p_syscfg_msk_tbl;
|
array3_tbl_t p_syscfg_msk_tbl;
|
||||||
int ret, cnt;
|
int ret, cnt;
|
||||||
const u32 mem_addr = 0x40500000;
|
const u32 mem_addr = 0x40500000;
|
||||||
|
const u32 cache_mem_addr = 0x40100020;
|
||||||
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||||
|
|
||||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
|
||||||
@@ -3752,6 +3652,21 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){
|
|||||||
chip_mcu_id = 1;
|
chip_mcu_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (chip_mcu_id) {
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cache_mem_addr, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rd_mem_addr_cfm.memdata |= 0x01;
|
||||||
|
ret = rwnx_send_dbg_mem_write_req(rwnx_hw, cache_mem_addr, rd_mem_addr_cfm.memdata);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "%x write fail: %d\n", cache_mem_addr, ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm);
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret);
|
AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret);
|
||||||
@@ -3759,7 +3674,10 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){
|
|||||||
}
|
}
|
||||||
chip_sub_id = (u8)(rd_mem_addr_cfm.memdata);
|
chip_sub_id = (u8)(rd_mem_addr_cfm.memdata);
|
||||||
//printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
|
//printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
|
||||||
AICWFDBG(LOGINFO, "chip_id=%x, chip_sub_id=%x\n", chip_id, chip_sub_id);
|
AICWFDBG(LOGINFO, "chip_id=%x, chip_mcu_id=%x, chip_sub_id=%x\n",
|
||||||
|
chip_id, chip_mcu_id, chip_sub_id);
|
||||||
|
AICWFDBG(LOGINFO,
|
||||||
|
"issue71: using complete pre-SDK-V5/V3 DC/DW firmware and loader profile\n");
|
||||||
|
|
||||||
|
|
||||||
//Crystal provided by CPU (start)
|
//Crystal provided by CPU (start)
|
||||||
|
|||||||
@@ -297,18 +297,6 @@ static void aicwf_usb_rx_complete(struct urb *urb)
|
|||||||
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
||||||
if(urb->status < 0){
|
if(urb->status < 0){
|
||||||
AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status);
|
AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status);
|
||||||
|
|
||||||
if(g_rwnx_plat->wait_disconnect_cb == false){
|
|
||||||
g_rwnx_plat->wait_disconnect_cb = true;
|
|
||||||
if(atomic_read(&aicwf_deinit_atomic) > 0){
|
|
||||||
atomic_set(&aicwf_deinit_atomic, 0);
|
|
||||||
down(&aicwf_deinit_sem);
|
|
||||||
AICWFDBG(LOGINFO, "%s need to wait for disconnect callback \r\n", __func__);
|
|
||||||
}else{
|
|
||||||
g_rwnx_plat->wait_disconnect_cb = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}else{
|
}else{
|
||||||
//schedule_work(&usb_dev->rx_urb_work);
|
//schedule_work(&usb_dev->rx_urb_work);
|
||||||
@@ -385,18 +373,6 @@ static void aicwf_usb_rx_complete(struct urb *urb)
|
|||||||
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
||||||
if(urb->status < 0){
|
if(urb->status < 0){
|
||||||
AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status);
|
AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status);
|
||||||
|
|
||||||
if(g_rwnx_plat->wait_disconnect_cb == false){
|
|
||||||
g_rwnx_plat->wait_disconnect_cb = true;
|
|
||||||
if(atomic_read(&aicwf_deinit_atomic) > 0){
|
|
||||||
atomic_set(&aicwf_deinit_atomic, 0);
|
|
||||||
down(&aicwf_deinit_sem);
|
|
||||||
AICWFDBG(LOGINFO, "%s need to wait for disconnect callback \r\n", __func__);
|
|
||||||
}else{
|
|
||||||
g_rwnx_plat->wait_disconnect_cb = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}else{
|
}else{
|
||||||
//schedule_work(&usb_dev->rx_urb_work);
|
//schedule_work(&usb_dev->rx_urb_work);
|
||||||
@@ -1979,10 +1955,6 @@ static void aicwf_usb_bus_stop(struct device *dev)
|
|||||||
if (usb_dev->state == USB_DOWN_ST)
|
if (usb_dev->state == USB_DOWN_ST)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(g_rwnx_plat && g_rwnx_plat->wait_disconnect_cb == true){
|
|
||||||
atomic_set(&aicwf_deinit_atomic, 1);
|
|
||||||
up(&aicwf_deinit_sem);
|
|
||||||
}
|
|
||||||
aicwf_usb_state_change(usb_dev, USB_DOWN_ST);
|
aicwf_usb_state_change(usb_dev, USB_DOWN_ST);
|
||||||
//aicwf_usb_cancel_all_urbs(usb_dev);//AIDEN
|
//aicwf_usb_cancel_all_urbs(usb_dev);//AIDEN
|
||||||
}
|
}
|
||||||
@@ -2341,7 +2313,8 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid
|
|||||||
usb_dev->chipid = PRODUCT_ID_AIC8801;
|
usb_dev->chipid = PRODUCT_ID_AIC8801;
|
||||||
AICWFDBG(LOGINFO, "%s USE AIC8801\r\n", __func__);
|
AICWFDBG(LOGINFO, "%s USE AIC8801\r\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}else if(pid == USB_PRODUCT_ID_AIC8800DC || pid == USB_PRODUCT_ID_TENDA
|
}else if(pid == USB_PRODUCT_ID_AIC8800DC || pid == USB_PRODUCT_ID_AIC8800DE
|
||||||
|
|| pid == USB_PRODUCT_ID_TENDA
|
||||||
|| pid == USB_PRODUCT_ID_TENDA_U2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS1
|
|| pid == USB_PRODUCT_ID_TENDA_U2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS1
|
||||||
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS3
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS3
|
||||||
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS4 || pid == USB_PRODUCT_ID_AIC8800FC_CUS5
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS4 || pid == USB_PRODUCT_ID_AIC8800FC_CUS5
|
||||||
@@ -2360,7 +2333,8 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid
|
|||||||
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS3 || pid == USB_PRODUCT_ID_AIC8800M80_CUS4
|
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS3 || pid == USB_PRODUCT_ID_AIC8800M80_CUS4
|
||||||
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS5 || pid == USB_PRODUCT_ID_AIC8800M80_CUS6
|
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS5 || pid == USB_PRODUCT_ID_AIC8800M80_CUS6
|
||||||
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS7 || pid == USB_PRODUCT_ID_AIC8800M80_CUS8
|
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS7 || pid == USB_PRODUCT_ID_AIC8800M80_CUS8
|
||||||
|| pid == USB_PRODUCT_ID_AIC8800D80_UGREEN || pid == USB_PRODUCT_ID_MERCURY){
|
|| pid == USB_PRODUCT_ID_AIC8800D80_UGREEN || pid == USB_PRODUCT_ID_MERCURY
|
||||||
|
|| pid == USB_PRODUCT_ID_TP){
|
||||||
usb_dev->chipid = PRODUCT_ID_AIC8800D81;
|
usb_dev->chipid = PRODUCT_ID_AIC8800D81;
|
||||||
aicwf_usb_rx_aggr = true;
|
aicwf_usb_rx_aggr = true;
|
||||||
AICWFDBG(LOGINFO, "%s USE AIC8800D81\r\n", __func__);
|
AICWFDBG(LOGINFO, "%s USE AIC8800D81\r\n", __func__);
|
||||||
@@ -2670,6 +2644,7 @@ static struct usb_device_id aicwf_usb_id_table[] = {
|
|||||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D81, 0xff, 0xff, 0xff)},
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D81, 0xff, 0xff, 0xff)},
|
||||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D41, 0xff, 0xff, 0xff)},
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D41, 0xff, 0xff, 0xff)},
|
||||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DC, 0xff, 0xff, 0xff)},
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DC, 0xff, 0xff, 0xff)},
|
||||||
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DE, 0xff, 0xff, 0xff)},
|
||||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_TENDA_V2, USB_PRODUCT_ID_TENDA_TX1U_NANO, 0xff, 0xff, 0xff)},
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_TENDA_V2, USB_PRODUCT_ID_TENDA_TX1U_NANO, 0xff, 0xff, 0xff)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DW)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DW)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800M80_CUS1)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800M80_CUS1)},
|
||||||
@@ -2705,6 +2680,7 @@ static struct usb_device_id aicwf_usb_id_table[] = {
|
|||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS8)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS8)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80_UGREEN)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80_UGREEN)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_TP, USB_PRODUCT_ID_MERCURY)},
|
{USB_DEVICE(USB_VENDOR_ID_TP, USB_PRODUCT_ID_MERCURY)},
|
||||||
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_TP, USB_PRODUCT_ID_TP, 0xff, 0xff, 0xff)},
|
||||||
#endif
|
#endif
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#else
|
#else
|
||||||
#define USB_PRODUCT_ID_AIC8801 0x8801
|
#define USB_PRODUCT_ID_AIC8801 0x8801
|
||||||
#define USB_PRODUCT_ID_AIC8800DC 0x88dc
|
#define USB_PRODUCT_ID_AIC8800DC 0x88dc
|
||||||
|
#define USB_PRODUCT_ID_AIC8800DE 0x88de
|
||||||
#define USB_PRODUCT_ID_AIC8800DW 0x88dd
|
#define USB_PRODUCT_ID_AIC8800DW 0x88dd
|
||||||
#define USB_PRODUCT_ID_AIC8800D81 0x8d81
|
#define USB_PRODUCT_ID_AIC8800D81 0x8d81
|
||||||
#define USB_PRODUCT_ID_AIC8800D41 0x8d41
|
#define USB_PRODUCT_ID_AIC8800D41 0x8d41
|
||||||
|
|||||||
@@ -23,6 +23,33 @@
|
|||||||
#define _RWNX_COMPAT_H_
|
#define _RWNX_COMPAT_H_
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
|
||||||
|
/* Keep wireless API checks separate from timer, USB and other kernel APIs. */
|
||||||
|
#ifndef AICWF_CFG80211_VERSION_CODE
|
||||||
|
#define AICWF_CFG80211_VERSION_CODE LINUX_VERSION_CODE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cfg80211_ops.set_monitor_channel() gained a "struct net_device *dev"
|
||||||
|
* parameter. The change went into mainline 6.13, but it was also
|
||||||
|
* backported to the 6.12 stable series starting with 6.12.101, so a
|
||||||
|
* plain ">= 6.13.0" test misses 6.12.101 and later. Those kernels then
|
||||||
|
* compile against the old prototype, which is fatal 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 *)'
|
||||||
|
*
|
||||||
|
* Debian 13 (6.12.107) is one such kernel. The 6.12.101 threshold
|
||||||
|
* covers both the backport and mainline, and leaves 6.11 and earlier
|
||||||
|
* 6.12.x on the old prototype. Keep the check in one place so every
|
||||||
|
* consumer stays in sync.
|
||||||
|
*/
|
||||||
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 101)
|
||||||
|
#define AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
|
||||||
#error "Minimum kernel version supported is 3.10"
|
#error "Minimum kernel version supported is 3.10"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2942,7 +2942,7 @@ bool key_flag = false;
|
|||||||
* when adding a group key.
|
* when adding a group key.
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
|
static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct wireless_dev *wdev,
|
struct wireless_dev *wdev,
|
||||||
#else
|
#else
|
||||||
struct net_device *netdev,
|
struct net_device *netdev,
|
||||||
@@ -2954,7 +2954,7 @@ static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
|
|||||||
struct key_params *params)
|
struct key_params *params)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
||||||
#else
|
#else
|
||||||
struct rwnx_vif *vif = netdev_priv(netdev);
|
struct rwnx_vif *vif = netdev_priv(netdev);
|
||||||
@@ -3066,7 +3066,7 @@ static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_get_key(struct wiphy *wiphy,
|
static int rwnx_cfg80211_get_key(struct wiphy *wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct wireless_dev *wdev,
|
struct wireless_dev *wdev,
|
||||||
#else
|
#else
|
||||||
struct net_device *netdev,
|
struct net_device *netdev,
|
||||||
@@ -3090,7 +3090,7 @@ static int rwnx_cfg80211_get_key(struct wiphy *wiphy,
|
|||||||
* and @key_index, return -ENOENT if the key doesn't exist.
|
* and @key_index, return -ENOENT if the key doesn't exist.
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_del_key(struct wiphy *wiphy,
|
static int rwnx_cfg80211_del_key(struct wiphy *wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct wireless_dev *wdev,
|
struct wireless_dev *wdev,
|
||||||
#else
|
#else
|
||||||
struct net_device *netdev,
|
struct net_device *netdev,
|
||||||
@@ -3102,7 +3102,7 @@ static int rwnx_cfg80211_del_key(struct wiphy *wiphy,
|
|||||||
u8 key_index, bool pairwise, const u8 *mac_addr)
|
u8 key_index, bool pairwise, const u8 *mac_addr)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
||||||
#else
|
#else
|
||||||
struct rwnx_vif *vif = netdev_priv(netdev);
|
struct rwnx_vif *vif = netdev_priv(netdev);
|
||||||
@@ -3154,7 +3154,7 @@ static int rwnx_cfg80211_set_default_key(struct wiphy *wiphy,
|
|||||||
* @set_default_mgmt_key: set the default management frame key on an interface
|
* @set_default_mgmt_key: set the default management frame key on an interface
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
|
static int rwnx_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct wireless_dev *wdev,
|
struct wireless_dev *wdev,
|
||||||
#else
|
#else
|
||||||
struct net_device *netdev,
|
struct net_device *netdev,
|
||||||
@@ -3249,7 +3249,7 @@ static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
|||||||
key_params.seq_len = 0;
|
key_params.seq_len = 0;
|
||||||
key_params.cipher = sme->crypto.cipher_group;
|
key_params.cipher = sme->crypto.cipher_group;
|
||||||
rwnx_cfg80211_add_key(wiphy,
|
rwnx_cfg80211_add_key(wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
&rwnx_vif->wdev,
|
&rwnx_vif->wdev,
|
||||||
#else
|
#else
|
||||||
dev,
|
dev,
|
||||||
@@ -3480,7 +3480,7 @@ static int rwnx_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *d
|
|||||||
* @add_station: Add a new station.
|
* @add_station: Add a new station.
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct wireless_dev *wdev,
|
struct wireless_dev *wdev,
|
||||||
#else
|
#else
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
@@ -3493,7 +3493,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
|||||||
struct station_parameters *params)
|
struct station_parameters *params)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
||||||
#else
|
#else
|
||||||
struct rwnx_vif *rwnx_vif = netdev_priv(dev);
|
struct rwnx_vif *rwnx_vif = netdev_priv(dev);
|
||||||
@@ -3589,7 +3589,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
|||||||
sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
|
sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
|
||||||
#endif
|
#endif
|
||||||
cfg80211_new_sta(
|
cfg80211_new_sta(
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
&rwnx_vif->wdev,
|
&rwnx_vif->wdev,
|
||||||
#else
|
#else
|
||||||
rwnx_vif->ndev,
|
rwnx_vif->ndev,
|
||||||
@@ -3620,7 +3620,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
|||||||
(params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "")
|
(params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "")
|
||||||
|
|
||||||
netdev_info(
|
netdev_info(
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
wdev->netdev,
|
wdev->netdev,
|
||||||
#else
|
#else
|
||||||
dev,
|
dev,
|
||||||
@@ -3651,7 +3651,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
|||||||
* @del_station: Remove a station
|
* @del_station: Remove a station
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct wireless_dev *wdev,
|
struct wireless_dev *wdev,
|
||||||
#else
|
#else
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
@@ -3666,7 +3666,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
||||||
#else
|
#else
|
||||||
struct rwnx_vif *rwnx_vif = netdev_priv(dev);
|
struct rwnx_vif *rwnx_vif = netdev_priv(dev);
|
||||||
@@ -3711,7 +3711,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
|||||||
|
|
||||||
if(found) {
|
if(found) {
|
||||||
netdev_info(
|
netdev_info(
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
wdev->netdev,
|
wdev->netdev,
|
||||||
#else
|
#else
|
||||||
dev,
|
dev,
|
||||||
@@ -3731,7 +3731,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
|||||||
}
|
}
|
||||||
if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP || rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
|
if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP || rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
|
||||||
cfg80211_del_sta(
|
cfg80211_del_sta(
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
&rwnx_vif->wdev,
|
&rwnx_vif->wdev,
|
||||||
#else
|
#else
|
||||||
rwnx_vif->ndev,
|
rwnx_vif->ndev,
|
||||||
@@ -3962,7 +3962,7 @@ void apm_probe_sta_work_process(struct work_struct *work)
|
|||||||
* cfg80211_check_station_change() to validate the information.
|
* cfg80211_check_station_change() to validate the information.
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct wireless_dev *wdev,
|
struct wireless_dev *wdev,
|
||||||
#else
|
#else
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
@@ -3975,7 +3975,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
|||||||
struct station_parameters *params)
|
struct station_parameters *params)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
||||||
#else
|
#else
|
||||||
struct rwnx_vif *vif = netdev_priv(dev);
|
struct rwnx_vif *vif = netdev_priv(dev);
|
||||||
@@ -3988,7 +3988,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
|||||||
/* Add the TDLS station */
|
/* Add the TDLS station */
|
||||||
if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
|
if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
|
||||||
{
|
{
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
||||||
#else
|
#else
|
||||||
struct rwnx_vif *rwnx_vif = netdev_priv(dev);
|
struct rwnx_vif *rwnx_vif = netdev_priv(dev);
|
||||||
@@ -4064,7 +4064,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
|||||||
(params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "")
|
(params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "")
|
||||||
|
|
||||||
netdev_info(
|
netdev_info(
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
wdev->netdev,
|
wdev->netdev,
|
||||||
#else
|
#else
|
||||||
dev,
|
dev,
|
||||||
@@ -4353,7 +4353,7 @@ static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
|
|||||||
/* delete any remaining STA*/
|
/* delete any remaining STA*/
|
||||||
while (!list_empty(&rwnx_vif->ap.sta_list)) {
|
while (!list_empty(&rwnx_vif->ap.sta_list)) {
|
||||||
rwnx_cfg80211_del_station_compat(wiphy,
|
rwnx_cfg80211_del_station_compat(wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
&rwnx_vif->wdev,
|
&rwnx_vif->wdev,
|
||||||
#else
|
#else
|
||||||
dev,
|
dev,
|
||||||
@@ -4420,7 +4420,7 @@ cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy, struct net_device *dev,
|
static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy, struct net_device *dev,
|
||||||
struct cfg80211_chan_def *chandef)
|
struct cfg80211_chan_def *chandef)
|
||||||
#else
|
#else
|
||||||
@@ -4480,7 +4480,7 @@ static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
struct cfg80211_chan_def *chandef)
|
struct cfg80211_chan_def *chandef)
|
||||||
@@ -4553,7 +4553,7 @@ void rwnx_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
|
|||||||
* have changed. The actual parameter values are available in
|
* have changed. The actual parameter values are available in
|
||||||
* struct wiphy. If returning an error, no value should be changed.
|
* struct wiphy. If returning an error, no value should be changed.
|
||||||
*/
|
*/
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||||
static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, u32 changed)
|
static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, u32 changed)
|
||||||
#else
|
#else
|
||||||
static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
|
static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
|
||||||
@@ -4574,7 +4574,7 @@ static int rwnx_cfg80211_set_tx_power(struct wiphy *wiphy,
|
|||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
|
||||||
struct wireless_dev *wdev,
|
struct wireless_dev *wdev,
|
||||||
#endif
|
#endif
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||||
int radio_idx,
|
int radio_idx,
|
||||||
#endif
|
#endif
|
||||||
enum nl80211_tx_power_setting type, int mbm)
|
enum nl80211_tx_power_setting type, int mbm)
|
||||||
@@ -4611,10 +4611,10 @@ static int rwnx_cfg80211_get_tx_power(struct wiphy *wiphy,
|
|||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
|
||||||
struct wireless_dev *wdev,
|
struct wireless_dev *wdev,
|
||||||
#endif
|
#endif
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||||
int radio_idx,
|
int radio_idx,
|
||||||
#endif
|
#endif
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 14, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 14, 0)
|
||||||
unsigned int link_id,
|
unsigned int link_id,
|
||||||
#endif
|
#endif
|
||||||
int *mbm)
|
int *mbm)
|
||||||
@@ -4857,7 +4857,17 @@ rwnx_cfg80211_remain_on_channel(struct wiphy *wiphy,
|
|||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||||
enum nl80211_channel_type channel_type,
|
enum nl80211_channel_type channel_type,
|
||||||
#endif
|
#endif
|
||||||
unsigned int duration, u64 *cookie)
|
unsigned int duration, u64 *cookie
|
||||||
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 2, 0)
|
||||||
|
/*
|
||||||
|
* 7.2 added an optional receive address filter for the off-channel
|
||||||
|
* period. cfg80211 refuses a non-NULL one unless the driver sets
|
||||||
|
* NL80211_EXT_FEATURE_ROC_ADDR_FILTER, which this one does not, so it
|
||||||
|
* is always NULL here. mac80211 ignores it in the same way.
|
||||||
|
*/
|
||||||
|
, const u8 *rx_addr
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return rwnx_cfg80211_remain_on_channel_(wiphy,
|
return rwnx_cfg80211_remain_on_channel_(wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
|
||||||
@@ -4999,7 +5009,7 @@ static int rwnx_cfg80211_get_channel(struct wiphy *wiphy,
|
|||||||
if (rwnx_vif->vif_index == rwnx_hw->monitor_vif)
|
if (rwnx_vif->vif_index == rwnx_hw->monitor_vif)
|
||||||
{
|
{
|
||||||
//retrieve channel from firmware
|
//retrieve channel from firmware
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
rwnx_cfg80211_set_monitor_channel(wiphy, wdev->netdev, NULL);
|
rwnx_cfg80211_set_monitor_channel(wiphy, wdev->netdev, NULL);
|
||||||
#else
|
#else
|
||||||
rwnx_cfg80211_set_monitor_channel(wiphy, NULL);
|
rwnx_cfg80211_set_monitor_channel(wiphy, NULL);
|
||||||
@@ -5197,7 +5207,7 @@ int rwnx_cfg80211_start_radar_detection(struct wiphy *wiphy,
|
|||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
|
||||||
, u32 cac_time_ms
|
, u32 cac_time_ms
|
||||||
#endif
|
#endif
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0))
|
#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 0))
|
||||||
, int link_id
|
, int link_id
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
@@ -5981,7 +5991,7 @@ int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif,
|
|||||||
* @get_station: get station information for the station identified by @mac
|
* @get_station: get station information for the station identified by @mac
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_get_station(struct wiphy *wiphy,
|
static int rwnx_cfg80211_get_station(struct wiphy *wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct wireless_dev *wdev,
|
struct wireless_dev *wdev,
|
||||||
#else
|
#else
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
@@ -5993,7 +6003,7 @@ static int rwnx_cfg80211_get_station(struct wiphy *wiphy,
|
|||||||
#endif
|
#endif
|
||||||
struct station_info *sinfo)
|
struct station_info *sinfo)
|
||||||
{
|
{
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
||||||
#else
|
#else
|
||||||
struct rwnx_vif *vif = netdev_priv(dev);
|
struct rwnx_vif *vif = netdev_priv(dev);
|
||||||
@@ -6031,14 +6041,14 @@ static int rwnx_cfg80211_get_station(struct wiphy *wiphy,
|
|||||||
* @dump_station: dump station callback -- resume dump at index @idx
|
* @dump_station: dump station callback -- resume dump at index @idx
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_dump_station(struct wiphy *wiphy,
|
static int rwnx_cfg80211_dump_station(struct wiphy *wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct wireless_dev *wdev,
|
struct wireless_dev *wdev,
|
||||||
#else
|
#else
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
#endif
|
#endif
|
||||||
int idx, u8 *mac, struct station_info *sinfo)
|
int idx, u8 *mac, struct station_info *sinfo)
|
||||||
{
|
{
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
||||||
#else
|
#else
|
||||||
struct rwnx_vif *rwnx_vif = netdev_priv(dev);
|
struct rwnx_vif *rwnx_vif = netdev_priv(dev);
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ void aicwf_p2p_alive_timeout(struct timer_list *t);
|
|||||||
int rwnx_send_check_p2p(struct cfg80211_scan_request *param);
|
int rwnx_send_check_p2p(struct cfg80211_scan_request *param);
|
||||||
void apm_staloss_work_process(struct work_struct *work);
|
void apm_staloss_work_process(struct work_struct *work);
|
||||||
void apm_probe_sta_work_process(struct work_struct *work);
|
void apm_probe_sta_work_process(struct work_struct *work);
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
struct cfg80211_chan_def *chandef);
|
struct cfg80211_chan_def *chandef);
|
||||||
|
|||||||
@@ -825,7 +825,9 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_USE_WIRELESS_EXT
|
||||||
putbss:
|
putbss:
|
||||||
|
#endif
|
||||||
if (bss != NULL)
|
if (bss != NULL)
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
|
||||||
cfg80211_put_bss(bss);
|
cfg80211_put_bss(bss);
|
||||||
|
|||||||
@@ -4849,7 +4849,13 @@ int rwnx_send_dbg_trigger_req(struct rwnx_hw *rwnx_hw, char *msg)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Set parameters for the MM_DBG_TRIGGER_REQ message */
|
/* Set parameters for the MM_DBG_TRIGGER_REQ message */
|
||||||
strncpy(req->error, msg, sizeof(req->error));
|
/*
|
||||||
|
* strncpy() is gone in 7.2. req->error is a fixed 64-byte field of a
|
||||||
|
* firmware message that is not NUL-terminated, and the message came
|
||||||
|
* from kzalloc(), so copying at most the field size is all strncpy()
|
||||||
|
* did here.
|
||||||
|
*/
|
||||||
|
memcpy(req->error, msg, strnlen(msg, sizeof(req->error)));
|
||||||
|
|
||||||
/* Send the MM_DBG_TRIGGER_REQ message to LMAC FW */
|
/* Send the MM_DBG_TRIGGER_REQ message to LMAC FW */
|
||||||
return rwnx_send_msg(rwnx_hw, req, 0, -1, NULL);
|
return rwnx_send_msg(rwnx_hw, req, 0, -1, NULL);
|
||||||
|
|||||||
@@ -1669,7 +1669,8 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
|
|||||||
if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC ||
|
if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC ||
|
||||||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){
|
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){
|
||||||
#ifndef ANDROID_PLATFORM
|
#ifndef ANDROID_PLATFORM
|
||||||
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800DC");
|
if (strlcat(aic_fw_path, "/aic8800DC", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||||
|
return -ENAMETOOLONG;
|
||||||
#endif
|
#endif
|
||||||
AICWFDBG(LOGINFO, "testmode=%d\n", testmode);
|
AICWFDBG(LOGINFO, "testmode=%d\n", testmode);
|
||||||
if (chip_sub_id == 0) {
|
if (chip_sub_id == 0) {
|
||||||
@@ -1808,7 +1809,8 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
|
|||||||
}
|
}
|
||||||
} else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) {
|
} else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) {
|
||||||
#ifndef ANDROID_PLATFORM
|
#ifndef ANDROID_PLATFORM
|
||||||
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80N");
|
if (strlcat(aic_fw_path, "/aic8800D80N", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||||
|
return -ENAMETOOLONG;
|
||||||
#endif
|
#endif
|
||||||
if (testmode == FW_NORMAL_MODE) {
|
if (testmode == FW_NORMAL_MODE) {
|
||||||
ret = aicwf_plat_patch_load_8800d80n(rwnx_hw);
|
ret = aicwf_plat_patch_load_8800d80n(rwnx_hw);
|
||||||
@@ -1838,7 +1840,8 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
|
|||||||
}
|
}
|
||||||
else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN) {
|
else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN) {
|
||||||
#ifndef ANDROID_PLATFORM
|
#ifndef ANDROID_PLATFORM
|
||||||
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800DLN");
|
if (strlcat(aic_fw_path, "/aic8800DLN", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||||
|
return -ENAMETOOLONG;
|
||||||
#endif
|
#endif
|
||||||
if (testmode == FW_NORMAL_MODE) {
|
if (testmode == FW_NORMAL_MODE) {
|
||||||
aicwf_patch_config_8800dln(rwnx_hw);
|
aicwf_patch_config_8800dln(rwnx_hw);
|
||||||
|
|||||||
@@ -1475,7 +1475,7 @@ static void rwnx_radar_cac_work(struct work_struct *ws)
|
|||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
||||||
&ctxt->chan_def,
|
&ctxt->chan_def,
|
||||||
#endif
|
#endif
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||||
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0);
|
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0);
|
||||||
#else
|
#else
|
||||||
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
|
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
|
||||||
@@ -1617,7 +1617,7 @@ void rwnx_radar_cancel_cac(struct rwnx_radar *radar)
|
|||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
||||||
&ctxt->chan_def,
|
&ctxt->chan_def,
|
||||||
#endif
|
#endif
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||||
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0);
|
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0);
|
||||||
#else
|
#else
|
||||||
NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
|
NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
|
||||||
|
|||||||
@@ -2283,6 +2283,11 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
|
|||||||
if(hw_rxhdr->flags_upload)
|
if(hw_rxhdr->flags_upload)
|
||||||
status |= RX_STAT_FORWARD;
|
status |= RX_STAT_FORWARD;
|
||||||
|
|
||||||
|
#ifndef CONFIG_RWNX_MON_DATA
|
||||||
|
if (status & RX_STAT_MONITOR)
|
||||||
|
status &= ~RX_STAT_FORWARD;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Check if we need to delete the buffer */
|
/* Check if we need to delete the buffer */
|
||||||
if (status & RX_STAT_DELETE) {
|
if (status & RX_STAT_DELETE) {
|
||||||
/* Remove the SK buffer from the rxbuf_elems table */
|
/* Remove the SK buffer from the rxbuf_elems table */
|
||||||
@@ -2345,13 +2350,24 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
|
|||||||
} else {
|
} else {
|
||||||
#ifdef CONFIG_RWNX_MON_DATA
|
#ifdef CONFIG_RWNX_MON_DATA
|
||||||
skb_monitor = skb_copy_expand(skb, rtap_len, 0, GFP_ATOMIC);
|
skb_monitor = skb_copy_expand(skb, rtap_len, 0, GFP_ATOMIC);
|
||||||
|
if (skb_monitor) {
|
||||||
skb_monitor->data += (msdu_offset + 2); //sdio/usb word allign
|
skb_monitor->data += (msdu_offset + 2); //sdio/usb word allign
|
||||||
|
|
||||||
//Save frame length
|
//Save frame length
|
||||||
frm_len = le32_to_cpu(hw_rxhdr->hwvect.len);
|
frm_len = le32_to_cpu(hw_rxhdr->hwvect.len);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!skb_monitor) {
|
||||||
|
if (status == RX_STAT_MONITOR) {
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto check_len_update;
|
||||||
|
}
|
||||||
|
|
||||||
//skb_reset_tail_pointer(skb);
|
//skb_reset_tail_pointer(skb);
|
||||||
//skb->len = 0;
|
//skb->len = 0;
|
||||||
skb_reset_tail_pointer(skb_monitor);
|
skb_reset_tail_pointer(skb_monitor);
|
||||||
@@ -2394,7 +2410,7 @@ check_len_update:
|
|||||||
hdr = (struct ieee80211_hdr *)(skb->data + msdu_offset);
|
hdr = (struct ieee80211_hdr *)(skb->data + msdu_offset);
|
||||||
rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx);
|
rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx);
|
||||||
if (rwnx_vif) {
|
if (rwnx_vif) {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||||
cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, -1, GFP_ATOMIC);
|
cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, -1, GFP_ATOMIC);
|
||||||
#else
|
#else
|
||||||
cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC);
|
cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC);
|
||||||
@@ -2741,7 +2757,7 @@ check_len_update:
|
|||||||
|
|
||||||
if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) {
|
if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) {
|
||||||
printk("aicwf: 4addr flag error\n");
|
printk("aicwf: 4addr flag error\n");
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||||
cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
|
cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
|
||||||
sta->mac_addr, -1, GFP_ATOMIC);
|
sta->mac_addr, -1, GFP_ATOMIC);
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ rwnx_prep_tdls_direct(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
|||||||
|
|
||||||
switch (action_code) {
|
switch (action_code) {
|
||||||
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
|
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
skb_put(skb, 1 + sizeof(mgmt->u.action.tdls_discover_resp));
|
skb_put(skb, 2 + sizeof(mgmt->u.action.tdls_discover_resp));
|
||||||
mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
|
mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
|
||||||
mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
|
mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
|
||||||
mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token;
|
mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token;
|
||||||
|
|||||||
@@ -1991,7 +1991,7 @@ free_use:
|
|||||||
|
|
||||||
netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev)
|
netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
int rtap_len, ret, idx, tmp_len;
|
int rtap_len, ret, idx;
|
||||||
struct ieee80211_radiotap_header *rtap_hdr; // net/ieee80211_radiotap.h
|
struct ieee80211_radiotap_header *rtap_hdr; // net/ieee80211_radiotap.h
|
||||||
struct ieee80211_radiotap_iterator iterator; // net/cfg80211.h
|
struct ieee80211_radiotap_iterator iterator; // net/cfg80211.h
|
||||||
u8_l *rtap_buf = (u8_l *)skb->data;
|
u8_l *rtap_buf = (u8_l *)skb->data;
|
||||||
@@ -2012,10 +2012,30 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
|
|||||||
bool offchan = false;
|
bool offchan = false;
|
||||||
int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX;
|
int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX;
|
||||||
|
|
||||||
rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf);
|
|
||||||
rtap_len = ieee80211_get_radiotap_len(rtap_buf);//max_length
|
|
||||||
frame_len = skb->len;
|
frame_len = skb->len;
|
||||||
|
|
||||||
|
if (unlikely(skb->len < sizeof(*rtap_hdr))) {
|
||||||
|
AICWFDBG(LOGERROR, "%s radiotap header is truncated\n", __func__);
|
||||||
|
goto free_tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf);
|
||||||
|
if (unlikely(rtap_hdr->it_version)) {
|
||||||
|
AICWFDBG(LOGERROR, "%s itv \r\n", __func__);
|
||||||
|
goto free_tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtap_len = ieee80211_get_radiotap_len(rtap_buf);//max_length
|
||||||
|
if (unlikely(rtap_len < sizeof(*rtap_hdr))) {
|
||||||
|
AICWFDBG(LOGERROR, "%s rtap_len < sizeof(struct ieee80211_radiotap_header) \r\n", __func__);
|
||||||
|
goto free_tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(skb->len < rtap_len)) {
|
||||||
|
AICWFDBG(LOGERROR, "%s skb->len < rtap_len \r\n", __func__);
|
||||||
|
goto free_tag;
|
||||||
|
}
|
||||||
|
|
||||||
AICWFDBG(LOGINFO, "rwnx_start_monitor_if_xmit, skb_len=%d, rtap_len=%d\n", skb->len, rtap_len);
|
AICWFDBG(LOGINFO, "rwnx_start_monitor_if_xmit, skb_len=%d, rtap_len=%d\n", skb->len, rtap_len);
|
||||||
//rwnx_data_dump((char*)__func__, skb->data, skb->len);
|
//rwnx_data_dump((char*)__func__, skb->data, skb->len);
|
||||||
if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) ||
|
if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) ||
|
||||||
@@ -2023,23 +2043,6 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
|
|||||||
g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){
|
g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){
|
||||||
nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC;
|
nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (unlikely(rtap_hdr->it_version)){
|
|
||||||
AICWFDBG(LOGERROR, "%s itv \r\n", __func__);
|
|
||||||
goto free_tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(skb->len < rtap_len)){
|
|
||||||
AICWFDBG(LOGERROR, "%s skb->len < rtap_len \r\n", __func__);
|
|
||||||
goto free_tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(rtap_len < sizeof(struct ieee80211_radiotap_header))){
|
|
||||||
AICWFDBG(LOGERROR, "%s rtap_len < sizeof(struct ieee80211_radiotap_header) \r\n", __func__);
|
|
||||||
goto free_tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame_len -= rtap_len;
|
frame_len -= rtap_len;
|
||||||
pframe = rtap_buf + rtap_len;
|
pframe = rtap_buf + rtap_len;
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
|||||||
u64 *cookie);
|
u64 *cookie);
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||||
#ifdef CONFIG_RWNX_MON_XMIT
|
#ifdef CONFIG_RWNX_MON_XMIT
|
||||||
int rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev);
|
netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb,
|
||||||
|
struct net_device *dev);
|
||||||
#endif
|
#endif
|
||||||
int rwnx_txdatacfm(void *pthis, void *host_id);
|
int rwnx_txdatacfm(void *pthis, void *host_id);
|
||||||
|
|
||||||
|
|||||||
@@ -39,36 +39,14 @@ typedef struct {
|
|||||||
#define AIC_PATCH_OFST(mem) ((size_t) &((aic_patch_t *)0)->mem)
|
#define AIC_PATCH_OFST(mem) ((size_t) &((aic_patch_t *)0)->mem)
|
||||||
#define AIC_PATCH_ADDR(mem) ((u32) (aic_patch_str_base + AIC_PATCH_OFST(mem)))
|
#define AIC_PATCH_ADDR(mem) ((u32) (aic_patch_str_base + AIC_PATCH_OFST(mem)))
|
||||||
|
|
||||||
#define USER_PWROFST_COVER_CALIB_FLAG (0x01U << 0)
|
/*
|
||||||
#define USER_CHAN_MAX_TXPWR_EN_FLAG (0x01U << 1)
|
* Issue #58 legacy-loader test.
|
||||||
#define USER_TX_USE_ANA_F_FLAG (0x01U << 2)
|
*
|
||||||
#define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3)
|
* Keep this table aligned with the SDK V3 D80 firmware imported from Radxa
|
||||||
#define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4)
|
* commit 254d47e6a131dbed5ba32131972f4719f3e1c7fe. Newer loader patches use
|
||||||
#define USER_LOFT_CALIB_DISABLE_FLAG (0x01U << 6)
|
* different RX aggregation settings and a user_ext_flags field that is not
|
||||||
#define USER_CAPA_CALIB_DISABLE_FLAG (0x01U << 7)
|
* part of this firmware generation.
|
||||||
#define USER_PWR_CALIB_DISABLE_FLAG (0x01U << 8)
|
*/
|
||||||
#define USER_IPA_CALIB_DISABLE_FLAG (0x01U << 13)
|
|
||||||
|
|
||||||
#define USER_EXT_FLAGS_DEFAULT_D80 (USER_PWROFST_COVER_CALIB_FLAG)
|
|
||||||
|
|
||||||
#define CFG_USER_PWROFST_COVER_CALIB_EN (1)
|
|
||||||
#if (defined(CONFIG_POWER_LIMIT))
|
|
||||||
#define CFG_USER_CHAN_MAX_TXPWR_EN (1)
|
|
||||||
#else
|
|
||||||
#define CFG_USER_CHAN_MAX_TXPWR_EN (0)
|
|
||||||
#endif
|
|
||||||
#define CFG_USER_TX_USE_ANA_F_EN (0)
|
|
||||||
#if (defined(CONFIG_PRBREQ_REPORT))
|
|
||||||
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (1)
|
|
||||||
#else
|
|
||||||
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (0)
|
|
||||||
#endif
|
|
||||||
#define CFG_USER_HE_MU_EDCA_UPDATE_DISABLE (0)
|
|
||||||
#define CFG_USER_LOFT_CALIB_DISABLE_DISABLE (0)
|
|
||||||
#define CFG_USER_CAPA_CALIB_DISABLE_DISABLE (0)
|
|
||||||
#define CFG_USER_PWR_CALIB_DISABLE_DISABLE (0)
|
|
||||||
#define CFG_USER_IPA_CALIB_DISABLE_DISABLE (0)
|
|
||||||
|
|
||||||
u32 patch_tbl_d80[][2] =
|
u32 patch_tbl_d80[][2] =
|
||||||
{
|
{
|
||||||
#ifdef USE_5G
|
#ifdef USE_5G
|
||||||
@@ -76,54 +54,7 @@ u32 patch_tbl_d80[][2] =
|
|||||||
#else
|
#else
|
||||||
{0x00b4, 0xf3010000},
|
{0x00b4, 0xf3010000},
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_PLATFORM_HI
|
{0x0170, 0x00000002},//rx aggr counter
|
||||||
{0x0170, 0x00010001},//rx aggr counter
|
|
||||||
#else
|
|
||||||
{0x0170, 0x0001000A},//rx aggr counter
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{0x0188,
|
|
||||||
(USER_EXT_FLAGS_DEFAULT_D80 |
|
|
||||||
#if CFG_USER_CHAN_MAX_TXPWR_EN
|
|
||||||
USER_CHAN_MAX_TXPWR_EN_FLAG |
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_TX_USE_ANA_F_EN
|
|
||||||
USER_TX_USE_ANA_F_FLAG |
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE
|
|
||||||
USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG |
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_HE_MU_EDCA_UPDATE_DISABLE
|
|
||||||
USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG |
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_LOFT_CALIB_DISABLE_DISABLE
|
|
||||||
USER_LOFT_CALIB_DISABLE_FLAG |
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_CAPA_CALIB_DISABLE_DISABLE
|
|
||||||
USER_CAPA_CALIB_DISABLE_FLAG |
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_PWR_CALIB_DISABLE_DISABLE
|
|
||||||
USER_PWR_CALIB_DISABLE_FLAG |
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_IPA_CALIB_DISABLE_DISABLE
|
|
||||||
USER_IPA_CALIB_DISABLE_FLAG |
|
|
||||||
#endif
|
|
||||||
0) & ~(
|
|
||||||
#if !CFG_USER_PWROFST_COVER_CALIB_EN
|
|
||||||
USER_PWROFST_COVER_CALIB_FLAG |
|
|
||||||
#endif
|
|
||||||
0)
|
|
||||||
}, // user_ext_flags
|
|
||||||
|
|
||||||
#ifdef CONFIG_RADAR_OR_IR_DETECT
|
|
||||||
{0x0019c,0x00000900},
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_WOWLAN
|
|
||||||
{0x019c,0x01000000},
|
|
||||||
#ifdef ANDROID_PLATFORM
|
|
||||||
{0x01A0, 0x01000001},
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//adap test
|
//adap test
|
||||||
@@ -144,16 +75,11 @@ u32 syscfg_tbl_8800d80[][2] = {
|
|||||||
|
|
||||||
extern int adap_test;
|
extern int adap_test;
|
||||||
|
|
||||||
#define NEW_PATCH_BUFFER_MAP 1
|
|
||||||
|
|
||||||
int aicwf_patch_config_8800d80(struct aic_usb_dev *usb_dev)
|
int aicwf_patch_config_8800d80(struct aic_usb_dev *usb_dev)
|
||||||
{
|
{
|
||||||
u32 rd_patch_addr;
|
u32 rd_patch_addr;
|
||||||
u32 aic_patch_addr;
|
u32 aic_patch_addr;
|
||||||
u32 config_base, aic_patch_str_base;
|
u32 config_base, aic_patch_str_base;
|
||||||
#if (NEW_PATCH_BUFFER_MAP)
|
|
||||||
u32 patch_buff_addr, patch_buff_base, rd_version_addr, rd_version_val;
|
|
||||||
#endif
|
|
||||||
uint32_t start_addr = 0x001D7000;
|
uint32_t start_addr = 0x001D7000;
|
||||||
u32 patch_addr = start_addr;
|
u32 patch_addr = start_addr;
|
||||||
u32 patch_cnt = sizeof(patch_tbl_d80) / 4 / 2;
|
u32 patch_cnt = sizeof(patch_tbl_d80) / 4 / 2;
|
||||||
@@ -190,32 +116,6 @@ int aicwf_patch_config_8800d80(struct aic_usb_dev *usb_dev)
|
|||||||
AICWFDBG(LOGERROR, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata);
|
AICWFDBG(LOGERROR, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata);
|
||||||
aic_patch_str_base = rd_patch_addr_cfm.memdata;
|
aic_patch_str_base = rd_patch_addr_cfm.memdata;
|
||||||
|
|
||||||
#if (NEW_PATCH_BUFFER_MAP)
|
|
||||||
if (chip_id == CHIP_REV_U01) {
|
|
||||||
rd_version_addr = RAM_FMAC_FW_ADDR_8800D80 + 0x01C;
|
|
||||||
} else {
|
|
||||||
rd_version_addr = RAM_FMAC_FW_ADDR_8800D80_U02 + 0x01C;
|
|
||||||
}
|
|
||||||
if ((ret = rwnx_send_dbg_mem_read_req(usb_dev, rd_version_addr, &rd_patch_addr_cfm))) {
|
|
||||||
AICWFDBG(LOGERROR, "version val[0x%x] rd fail: %d\n", rd_version_addr, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
rd_version_val = rd_patch_addr_cfm.memdata;
|
|
||||||
AICWFDBG(LOGINFO, "rd_version_val=%08X\n", rd_version_val);
|
|
||||||
usb_dev->fw_version_uint = rd_version_val;
|
|
||||||
if (rd_version_val > 0x06090100) {
|
|
||||||
patch_buff_addr = rd_patch_addr + 12;
|
|
||||||
ret = rwnx_send_dbg_mem_read_req(usb_dev, patch_buff_addr, &rd_patch_addr_cfm);
|
|
||||||
if (ret) {
|
|
||||||
AICWFDBG(LOGERROR, "patch buf rd fail\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
AICWFDBG(LOGINFO, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata);
|
|
||||||
patch_buff_base = rd_patch_addr_cfm.memdata;
|
|
||||||
patch_addr = start_addr = patch_buff_base;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(magic_num), AIC_PATCH_MAGIG_NUM))) {
|
if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(magic_num), AIC_PATCH_MAGIG_NUM))) {
|
||||||
AICWFDBG(LOGERROR, "maigic_num[0x%x] write fail: %d\n", AIC_PATCH_ADDR(magic_num), ret);
|
AICWFDBG(LOGERROR, "maigic_num[0x%x] write fail: %d\n", AIC_PATCH_ADDR(magic_num), ret);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -346,10 +246,11 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){
|
|||||||
}
|
}
|
||||||
chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16);
|
chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16);
|
||||||
printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id);
|
printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id);
|
||||||
if (chip_mcu_id) {
|
printk("AIC8800D80 legacy: using Radxa SDK V3 loader profile\n");
|
||||||
|
if (chip_mcu_id == 1) {
|
||||||
ret = rwnx_send_dbg_mem_read_req(usb_dev, cache_mem_addr, &rd_mem_addr_cfm);
|
ret = rwnx_send_dbg_mem_read_req(usb_dev, cache_mem_addr, &rd_mem_addr_cfm);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk("%x rd fail: %d\n", mem_addr, ret);
|
printk("%x rd fail: %d\n", cache_mem_addr, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
rd_mem_addr_cfm.memdata |= 0x01;
|
rd_mem_addr_cfm.memdata |= 0x01;
|
||||||
@@ -358,6 +259,7 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){
|
|||||||
printk("%x write fail: %d\n", cache_mem_addr, ret);
|
printk("%x write fail: %d\n", cache_mem_addr, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
printk("AIC8800D80 MCU1: enabled Bluetooth cache fix\n");
|
||||||
}
|
}
|
||||||
#if 1
|
#if 1
|
||||||
syscfg_num = sizeof(syscfg_tbl_8800d80) / sizeof(u32) / 2;
|
syscfg_num = sizeof(syscfg_tbl_8800d80) / sizeof(u32) / 2;
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
ifneq ($(KERNELRELEASE),)
|
||||||
|
|
||||||
|
obj-m += aic_zlp_quirk.o
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
KVER ?= $(shell uname -r)
|
||||||
|
KDIR ?= /lib/modules/$(KVER)/build
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
all:
|
||||||
|
$(MAKE) -C $(KDIR) M=$(CURDIR) modules
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C $(KDIR) M=$(CURDIR) clean
|
||||||
|
|
||||||
|
endif
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
|
#include <linux/atomic.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/kprobes.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/ptrace.h>
|
||||||
|
#include <linux/usb.h>
|
||||||
|
|
||||||
|
#define AIC_USB_VENDOR_ID 0x368b
|
||||||
|
#define AIC_USB_PRODUCT_ID 0x8d81
|
||||||
|
#define USB_BT_SUBCLASS 0x01
|
||||||
|
#define USB_BT_PROTOCOL 0x01
|
||||||
|
|
||||||
|
static atomic64_t injection_count = ATOMIC64_INIT(0);
|
||||||
|
static const char *hook_name = "none";
|
||||||
|
|
||||||
|
static int injections_get(char *buffer, const struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
(void)kp;
|
||||||
|
|
||||||
|
return scnprintf(buffer, PAGE_SIZE, "%lld\n",
|
||||||
|
(long long)atomic64_read(&injection_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct kernel_param_ops injections_ops = {
|
||||||
|
.get = injections_get,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_param_cb(injections, &injections_ops, NULL, 0444);
|
||||||
|
MODULE_PARM_DESC(injections, "Number of AIC ACL bulk OUT URBs modified");
|
||||||
|
|
||||||
|
static int hook_get(char *buffer, const struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
(void)kp;
|
||||||
|
|
||||||
|
return scnprintf(buffer, PAGE_SIZE, "%s\n", hook_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct kernel_param_ops hook_ops = {
|
||||||
|
.get = hook_get,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_param_cb(hook, &hook_ops, NULL, 0444);
|
||||||
|
MODULE_PARM_DESC(hook, "Active injection hook");
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_KPROBES)
|
||||||
|
|
||||||
|
enum aic_zlp_hook {
|
||||||
|
AIC_ZLP_HOOK_NONE,
|
||||||
|
AIC_ZLP_HOOK_BTUSB_RETURN,
|
||||||
|
AIC_ZLP_HOOK_USB_SUBMIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
static enum aic_zlp_hook active_hook;
|
||||||
|
|
||||||
|
static bool is_aic_bulk_out(const struct urb *urb)
|
||||||
|
{
|
||||||
|
const struct usb_device *udev;
|
||||||
|
|
||||||
|
if (!urb)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
udev = urb->dev;
|
||||||
|
if (!udev)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (le16_to_cpu(udev->descriptor.idVendor) != AIC_USB_VENDOR_ID ||
|
||||||
|
le16_to_cpu(udev->descriptor.idProduct) != AIC_USB_PRODUCT_ID)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return usb_pipetype(urb->pipe) == PIPE_BULK &&
|
||||||
|
usb_pipeout(urb->pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_bluetooth_acl_endpoint(const struct urb *urb)
|
||||||
|
{
|
||||||
|
const struct usb_endpoint_descriptor *ep;
|
||||||
|
struct usb_host_interface *alt;
|
||||||
|
struct usb_interface *intf;
|
||||||
|
unsigned int endpoint;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!is_aic_bulk_out(urb))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
intf = usb_ifnum_to_if(urb->dev, 0);
|
||||||
|
if (!intf)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
alt = READ_ONCE(intf->cur_altsetting);
|
||||||
|
if (!alt ||
|
||||||
|
alt->desc.bInterfaceClass != USB_CLASS_WIRELESS_CONTROLLER ||
|
||||||
|
alt->desc.bInterfaceSubClass != USB_BT_SUBCLASS ||
|
||||||
|
alt->desc.bInterfaceProtocol != USB_BT_PROTOCOL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
endpoint = usb_pipeendpoint(urb->pipe);
|
||||||
|
for (i = 0; i < alt->desc.bNumEndpoints; i++) {
|
||||||
|
ep = &alt->endpoint[i].desc;
|
||||||
|
if (usb_endpoint_is_bulk_out(ep) &&
|
||||||
|
usb_endpoint_num(ep) == endpoint)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void enable_zlp(struct urb *urb)
|
||||||
|
{
|
||||||
|
long long count;
|
||||||
|
|
||||||
|
if (urb->transfer_flags & URB_ZERO_PACKET)
|
||||||
|
return;
|
||||||
|
|
||||||
|
urb->transfer_flags |= URB_ZERO_PACKET;
|
||||||
|
count = atomic64_inc_return(&injection_count);
|
||||||
|
|
||||||
|
if (count == 1)
|
||||||
|
pr_info("enabled ZLP on the first 368b:8d81 ACL bulk OUT URB\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int alloc_bulk_urb_ret_handler(struct kretprobe_instance *ri,
|
||||||
|
struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
struct urb *urb;
|
||||||
|
|
||||||
|
(void)ri;
|
||||||
|
|
||||||
|
urb = (struct urb *)regs_return_value(regs);
|
||||||
|
if (!is_aic_bulk_out(urb))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
enable_zlp(urb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct kretprobe alloc_bulk_urb_probe = {
|
||||||
|
.kp.symbol_name = "btusb:alloc_bulk_urb",
|
||||||
|
.handler = alloc_bulk_urb_ret_handler,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int usb_submit_urb_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
struct urb *urb;
|
||||||
|
|
||||||
|
(void)p;
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARM)
|
||||||
|
urb = (struct urb *)regs->ARM_r0;
|
||||||
|
#else
|
||||||
|
urb = (struct urb *)regs_get_kernel_argument(regs, 0);
|
||||||
|
#endif
|
||||||
|
if (is_bluetooth_acl_endpoint(urb))
|
||||||
|
enable_zlp(urb);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct kprobe usb_submit_urb_probe = {
|
||||||
|
.symbol_name = "usb_submit_urb",
|
||||||
|
.pre_handler = usb_submit_urb_pre_handler,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init aic_zlp_quirk_init(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = register_kretprobe(&alloc_bulk_urb_probe);
|
||||||
|
if (!ret) {
|
||||||
|
active_hook = AIC_ZLP_HOOK_BTUSB_RETURN;
|
||||||
|
hook_name = "btusb:alloc_bulk_urb";
|
||||||
|
pr_info("attached to system btusb for USB device 368b:8d81\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_warn("btusb return hook unavailable (%d), trying USB submit fallback\n",
|
||||||
|
ret);
|
||||||
|
|
||||||
|
ret = register_kprobe(&usb_submit_urb_probe);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("cannot attach to usb_submit_urb: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
active_hook = AIC_ZLP_HOOK_USB_SUBMIT;
|
||||||
|
hook_name = "usb_submit_urb";
|
||||||
|
pr_info("attached USB submit fallback for device 368b:8d81 interface 0\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit aic_zlp_quirk_exit(void)
|
||||||
|
{
|
||||||
|
unsigned long missed = 0;
|
||||||
|
|
||||||
|
if (active_hook == AIC_ZLP_HOOK_BTUSB_RETURN) {
|
||||||
|
unregister_kretprobe(&alloc_bulk_urb_probe);
|
||||||
|
missed = alloc_bulk_urb_probe.nmissed;
|
||||||
|
} else if (active_hook == AIC_ZLP_HOOK_USB_SUBMIT) {
|
||||||
|
unregister_kprobe(&usb_submit_urb_probe);
|
||||||
|
missed = usb_submit_urb_probe.nmissed;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_info("detached %s after %lld injections (%lu missed hits)\n",
|
||||||
|
hook_name, (long long)atomic64_read(&injection_count), missed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static int __init aic_zlp_quirk_init(void)
|
||||||
|
{
|
||||||
|
pr_err("CONFIG_KPROBES is disabled in this kernel\n");
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit aic_zlp_quirk_exit(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
module_init(aic_zlp_quirk_init);
|
||||||
|
module_exit(aic_zlp_quirk_exit);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Shen Mintao <cx330.shen@autocore.ai>");
|
||||||
|
MODULE_DESCRIPTION("AIC 8800D80 standard btusb ACL bulk TX ZLP quirk");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_VERSION("1.0");
|
||||||
|
MODULE_SOFTDEP("pre: btusb");
|
||||||
|
MODULE_ALIAS("usb:v368Bp8D81d*dc*dsc*dp*ic*isc*ip*in*");
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
# AIC POWERLIMIT 2025/0623/1700
|
|
||||||
# Max tx power reference: Linux wireless regulatory database for CRDA
|
|
||||||
# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt
|
|
||||||
# If loss_value in aic_userconfig.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment
|
|
||||||
|
|
||||||
# Table 1:
|
|
||||||
## 2.4G, 20M,#6#
|
|
||||||
## START
|
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
|
||||||
CH01 16 14 14 16 16 15
|
|
||||||
CH02 16 14 14 16 16 16
|
|
||||||
CH03 16 14 14 16 16 16
|
|
||||||
CH04 16 14 14 16 16 16
|
|
||||||
CH05 16 14 14 16 16 16
|
|
||||||
CH06 16 14 14 16 16 16
|
|
||||||
CH07 16 14 14 16 16 16
|
|
||||||
CH08 16 14 14 16 16 16
|
|
||||||
CH09 16 14 14 16 16 16
|
|
||||||
CH10 16 14 14 16 16 16
|
|
||||||
CH11 16 14 14 16 16 16
|
|
||||||
CH12 15 14 14 16 16 12
|
|
||||||
CH13 13 14 14 16 16 12
|
|
||||||
CH14 NA NA NA 16 NA 12
|
|
||||||
## END
|
|
||||||
|
|
||||||
# Table 2:
|
|
||||||
## 2.4G, 40M,#6#
|
|
||||||
## START
|
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
|
||||||
CH01 NA NA NA NA NA NA
|
|
||||||
CH02 NA NA NA NA NA NA
|
|
||||||
CH03 16 13 14 16 16 16
|
|
||||||
CH04 16 13 14 16 16 16
|
|
||||||
CH05 16 13 14 16 16 16
|
|
||||||
CH06 16 13 14 16 16 16
|
|
||||||
CH07 16 13 14 16 16 16
|
|
||||||
CH08 16 13 14 16 16 16
|
|
||||||
CH09 16 11 14 16 16 16
|
|
||||||
CH10 16 11 14 16 16 16
|
|
||||||
CH11 16 11 14 16 16 16
|
|
||||||
CH12 NA NA NA NA NA NA
|
|
||||||
CH13 NA NA NA NA NA NA
|
|
||||||
CH14 NA NA NA NA NA NA
|
|
||||||
## END
|
|
||||||
|
|
||||||
# Table 3:
|
|
||||||
## 5G, 20M,#6#
|
|
||||||
## START
|
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
|
||||||
# 5G Band 1
|
|
||||||
CH36 15 16 16 16 16 15
|
|
||||||
CH40 15 16 16 16 16 15
|
|
||||||
CH44 15 16 16 16 16 15
|
|
||||||
CH48 15 16 16 16 16 15
|
|
||||||
# 5G Band 2
|
|
||||||
CH52 15 16 16 16 16 15
|
|
||||||
CH56 15 16 16 16 16 15
|
|
||||||
CH60 15 16 16 16 16 15
|
|
||||||
CH64 15 16 16 16 16 15
|
|
||||||
# 5G Band 3
|
|
||||||
CH100 NA 16 16 16 16 15
|
|
||||||
CH104 NA 16 16 16 16 15
|
|
||||||
CH108 NA 16 16 16 16 15
|
|
||||||
CH112 NA 16 16 16 16 15
|
|
||||||
CH116 NA 16 16 16 16 15
|
|
||||||
CH120 NA 16 16 16 16 15
|
|
||||||
CH124 NA 16 16 16 16 15
|
|
||||||
CH128 NA 16 16 16 16 15
|
|
||||||
CH132 NA 16 16 16 16 15
|
|
||||||
CH136 NA 16 16 16 16 15
|
|
||||||
CH140 NA 16 16 16 16 15
|
|
||||||
CH144 NA NA 16 16 16 15
|
|
||||||
# 5G Band 4
|
|
||||||
CH149 20 16 8 NA 20 11
|
|
||||||
CH153 20 16 8 NA 20 11
|
|
||||||
CH157 20 16 8 NA 20 11
|
|
||||||
CH161 20 16 8 NA 20 11
|
|
||||||
CH165 20 16 8 NA 20 11
|
|
||||||
## END
|
|
||||||
|
|
||||||
# Table 4:
|
|
||||||
## 5G, 40M,#6#
|
|
||||||
## START
|
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
|
||||||
# 5G Band 1
|
|
||||||
CH38 15 16 16 16 20 15
|
|
||||||
CH46 15 16 16 16 20 15
|
|
||||||
# 5G Band 2
|
|
||||||
CH54 15 16 16 16 20 15
|
|
||||||
CH62 15 16 16 16 20 15
|
|
||||||
# 5G Band 3
|
|
||||||
CH102 NA 16 16 16 20 15
|
|
||||||
CH110 NA 16 16 16 20 15
|
|
||||||
CH118 NA 16 16 16 20 15
|
|
||||||
CH126 NA 16 16 16 20 15
|
|
||||||
CH134 NA 16 16 16 20 15
|
|
||||||
CH142 NA 16 NA 16 20 15
|
|
||||||
# 5G Band 4
|
|
||||||
CH151 16 15 8 NA 18 11
|
|
||||||
CH159 17 16 8 NA 17 11
|
|
||||||
## END
|
|
||||||
|
|
||||||
# Table 5:
|
|
||||||
## 5G, 80M,#6#
|
|
||||||
## START
|
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
|
||||||
# 5G Band 1
|
|
||||||
CH42 15 16 16 16 20 15
|
|
||||||
# 5G Band 2
|
|
||||||
CH58 15 16 16 16 20 15
|
|
||||||
# 5G Band 3
|
|
||||||
CH106 NA 16 16 16 20 15
|
|
||||||
CH122 NA 16 16 16 20 15
|
|
||||||
CH138 NA 16 NA NA 20 15
|
|
||||||
# 5G Band 4
|
|
||||||
CH155 15 14 8 NA 16 11
|
|
||||||
## END
|
|
||||||
@@ -67,23 +67,9 @@ lvl_11ax_mcs9_5g=13
|
|||||||
lvl_11ax_mcs10_5g=12
|
lvl_11ax_mcs10_5g=12
|
||||||
lvl_11ax_mcs11_5g=12
|
lvl_11ax_mcs11_5g=12
|
||||||
|
|
||||||
# txpwr_lvl_adj
|
|
||||||
lvl_adj_enable=0
|
|
||||||
lvl_adj_2g4_chan_1_4=0
|
|
||||||
lvl_adj_2g4_chan_5_9=0
|
|
||||||
lvl_adj_2g4_chan_10_13=0
|
|
||||||
lvl_adj_5g_chan_42=0
|
|
||||||
lvl_adj_5g_chan_58=0
|
|
||||||
lvl_adj_5g_chan_106=0
|
|
||||||
lvl_adj_5g_chan_122=0
|
|
||||||
lvl_adj_5g_chan_138=0
|
|
||||||
lvl_adj_5g_chan_155=0
|
|
||||||
|
|
||||||
# txpwr_loss
|
# txpwr_loss
|
||||||
loss_enable_2g4=0
|
loss_enable=0
|
||||||
loss_value_2g4=2
|
loss_value=2
|
||||||
loss_enable_5g=0
|
|
||||||
loss_value_5g=5
|
|
||||||
|
|
||||||
# txpwr_ofst
|
# txpwr_ofst
|
||||||
ofst_enable=0
|
ofst_enable=0
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
# AIC USERCONFIG 2022/0803/1707
|
|
||||||
|
|
||||||
# txpwr_lvl
|
|
||||||
enable=1
|
|
||||||
lvl_11b_11ag_1m_2g4=20
|
|
||||||
lvl_11b_11ag_2m_2g4=20
|
|
||||||
lvl_11b_11ag_5m5_2g4=20
|
|
||||||
lvl_11b_11ag_11m_2g4=20
|
|
||||||
lvl_11b_11ag_6m_2g4=20
|
|
||||||
lvl_11b_11ag_9m_2g4=20
|
|
||||||
lvl_11b_11ag_12m_2g4=20
|
|
||||||
lvl_11b_11ag_18m_2g4=20
|
|
||||||
lvl_11b_11ag_24m_2g4=20
|
|
||||||
lvl_11b_11ag_36m_2g4=19
|
|
||||||
lvl_11b_11ag_48m_2g4=18
|
|
||||||
lvl_11b_11ag_54m_2g4=17
|
|
||||||
lvl_11n_11ac_mcs0_2g4=20
|
|
||||||
lvl_11n_11ac_mcs1_2g4=20
|
|
||||||
lvl_11n_11ac_mcs2_2g4=20
|
|
||||||
lvl_11n_11ac_mcs3_2g4=20
|
|
||||||
lvl_11n_11ac_mcs4_2g4=20
|
|
||||||
lvl_11n_11ac_mcs5_2g4=19
|
|
||||||
lvl_11n_11ac_mcs6_2g4=18
|
|
||||||
lvl_11n_11ac_mcs7_2g4=17
|
|
||||||
lvl_11n_11ac_mcs8_2g4=17
|
|
||||||
lvl_11n_11ac_mcs9_2g4=16
|
|
||||||
lvl_11ax_mcs0_2g4=20
|
|
||||||
lvl_11ax_mcs1_2g4=20
|
|
||||||
lvl_11ax_mcs2_2g4=20
|
|
||||||
lvl_11ax_mcs3_2g4=20
|
|
||||||
lvl_11ax_mcs4_2g4=20
|
|
||||||
lvl_11ax_mcs5_2g4=19
|
|
||||||
lvl_11ax_mcs6_2g4=18
|
|
||||||
lvl_11ax_mcs7_2g4=17
|
|
||||||
lvl_11ax_mcs8_2g4=17
|
|
||||||
lvl_11ax_mcs9_2g4=16
|
|
||||||
lvl_11ax_mcs10_2g4=15
|
|
||||||
lvl_11ax_mcs11_2g4=15
|
|
||||||
lvl_11a_6m_5g=19
|
|
||||||
lvl_11a_9m_5g=19
|
|
||||||
lvl_11a_12m_5g=19
|
|
||||||
lvl_11a_18m_5g=18
|
|
||||||
lvl_11a_24m_5g=18
|
|
||||||
lvl_11a_36m_5g=18
|
|
||||||
lvl_11a_48m_5g=18
|
|
||||||
lvl_11a_54m_5g=18
|
|
||||||
lvl_11n_11ac_mcs0_5g=19
|
|
||||||
lvl_11n_11ac_mcs1_5g=19
|
|
||||||
lvl_11n_11ac_mcs2_5g=19
|
|
||||||
lvl_11n_11ac_mcs3_5g=18
|
|
||||||
lvl_11n_11ac_mcs4_5g=18
|
|
||||||
lvl_11n_11ac_mcs5_5g=18
|
|
||||||
lvl_11n_11ac_mcs6_5g=18
|
|
||||||
lvl_11n_11ac_mcs7_5g=17
|
|
||||||
lvl_11n_11ac_mcs8_5g=15
|
|
||||||
lvl_11n_11ac_mcs9_5g=15
|
|
||||||
lvl_11ax_mcs0_5g=19
|
|
||||||
lvl_11ax_mcs1_5g=19
|
|
||||||
lvl_11ax_mcs2_5g=19
|
|
||||||
lvl_11ax_mcs3_5g=18
|
|
||||||
lvl_11ax_mcs4_5g=18
|
|
||||||
lvl_11ax_mcs5_5g=18
|
|
||||||
lvl_11ax_mcs6_5g=18
|
|
||||||
lvl_11ax_mcs7_5g=17
|
|
||||||
lvl_11ax_mcs8_5g=15
|
|
||||||
lvl_11ax_mcs9_5g=15
|
|
||||||
lvl_11ax_mcs10_5g=13
|
|
||||||
lvl_11ax_mcs11_5g=13
|
|
||||||
|
|
||||||
# txpwr_lvl_adj
|
|
||||||
lvl_adj_enable=0
|
|
||||||
lvl_adj_2g4_chan_1_4=0
|
|
||||||
lvl_adj_2g4_chan_5_9=0
|
|
||||||
lvl_adj_2g4_chan_10_13=0
|
|
||||||
lvl_adj_5g_chan_42=0
|
|
||||||
lvl_adj_5g_chan_58=0
|
|
||||||
lvl_adj_5g_chan_106=0
|
|
||||||
lvl_adj_5g_chan_122=0
|
|
||||||
lvl_adj_5g_chan_138=0
|
|
||||||
lvl_adj_5g_chan_155=0
|
|
||||||
|
|
||||||
# txpwr_loss
|
|
||||||
loss_enable_2g4=0
|
|
||||||
loss_value_2g4=2
|
|
||||||
loss_enable_5g=0
|
|
||||||
loss_value_5g=5
|
|
||||||
|
|
||||||
# txpwr_ofst
|
|
||||||
ofst_enable=0
|
|
||||||
ofst_2g4_11b_chan_1_4=0
|
|
||||||
ofst_2g4_11b_chan_5_9=0
|
|
||||||
ofst_2g4_11b_chan_10_13=0
|
|
||||||
ofst_2g4_ofdm_highrate_chan_1_4=0
|
|
||||||
ofst_2g4_ofdm_highrate_chan_5_9=0
|
|
||||||
ofst_2g4_ofdm_highrate_chan_10_13=0
|
|
||||||
ofst_2g4_ofdm_lowrate_chan_1_4=0
|
|
||||||
ofst_2g4_ofdm_lowrate_chan_5_9=0
|
|
||||||
ofst_2g4_ofdm_lowrate_chan_10_13=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_42=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_58=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_106=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_122=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_138=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_155=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_42=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_58=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_106=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_122=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_138=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_155=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_42=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_58=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_106=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_122=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_138=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_155=0
|
|
||||||
|
|
||||||
# xtal cap
|
|
||||||
xtal_enable=0
|
|
||||||
xtal_cap=24
|
|
||||||
xtal_cap_fine=31
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
# AIC USERCONFIG 2022/0803/1707
|
|
||||||
|
|
||||||
# txpwr_lvl
|
|
||||||
enable=1
|
|
||||||
lvl_11b_11ag_1m_2g4=18
|
|
||||||
lvl_11b_11ag_2m_2g4=18
|
|
||||||
lvl_11b_11ag_5m5_2g4=18
|
|
||||||
lvl_11b_11ag_11m_2g4=18
|
|
||||||
lvl_11b_11ag_6m_2g4=18
|
|
||||||
lvl_11b_11ag_9m_2g4=18
|
|
||||||
lvl_11b_11ag_12m_2g4=18
|
|
||||||
lvl_11b_11ag_18m_2g4=18
|
|
||||||
lvl_11b_11ag_24m_2g4=18
|
|
||||||
lvl_11b_11ag_36m_2g4=18
|
|
||||||
lvl_11b_11ag_48m_2g4=18
|
|
||||||
lvl_11b_11ag_54m_2g4=17
|
|
||||||
lvl_11n_11ac_mcs0_2g4=20
|
|
||||||
lvl_11n_11ac_mcs1_2g4=20
|
|
||||||
lvl_11n_11ac_mcs2_2g4=20
|
|
||||||
lvl_11n_11ac_mcs3_2g4=20
|
|
||||||
lvl_11n_11ac_mcs4_2g4=20
|
|
||||||
lvl_11n_11ac_mcs5_2g4=19
|
|
||||||
lvl_11n_11ac_mcs6_2g4=18
|
|
||||||
lvl_11n_11ac_mcs7_2g4=18
|
|
||||||
lvl_11n_11ac_mcs8_2g4=17
|
|
||||||
lvl_11n_11ac_mcs9_2g4=16
|
|
||||||
lvl_11ax_mcs0_2g4=20
|
|
||||||
lvl_11ax_mcs1_2g4=20
|
|
||||||
lvl_11ax_mcs2_2g4=20
|
|
||||||
lvl_11ax_mcs3_2g4=20
|
|
||||||
lvl_11ax_mcs4_2g4=20
|
|
||||||
lvl_11ax_mcs5_2g4=19
|
|
||||||
lvl_11ax_mcs6_2g4=18
|
|
||||||
lvl_11ax_mcs7_2g4=18
|
|
||||||
lvl_11ax_mcs8_2g4=17
|
|
||||||
lvl_11ax_mcs9_2g4=17
|
|
||||||
lvl_11ax_mcs10_2g4=16
|
|
||||||
lvl_11ax_mcs11_2g4=16
|
|
||||||
lvl_11a_6m_5g=18
|
|
||||||
lvl_11a_9m_5g=18
|
|
||||||
lvl_11a_12m_5g=18
|
|
||||||
lvl_11a_18m_5g=18
|
|
||||||
lvl_11a_24m_5g=18
|
|
||||||
lvl_11a_36m_5g=18
|
|
||||||
lvl_11a_48m_5g=18
|
|
||||||
lvl_11a_54m_5g=18
|
|
||||||
lvl_11n_11ac_mcs0_5g=20
|
|
||||||
lvl_11n_11ac_mcs1_5g=19
|
|
||||||
lvl_11n_11ac_mcs2_5g=19
|
|
||||||
lvl_11n_11ac_mcs3_5g=18
|
|
||||||
lvl_11n_11ac_mcs4_5g=18
|
|
||||||
lvl_11n_11ac_mcs5_5g=18
|
|
||||||
lvl_11n_11ac_mcs6_5g=18
|
|
||||||
lvl_11n_11ac_mcs7_5g=17
|
|
||||||
lvl_11n_11ac_mcs8_5g=16
|
|
||||||
lvl_11n_11ac_mcs9_5g=16
|
|
||||||
lvl_11ax_mcs0_5g=20
|
|
||||||
lvl_11ax_mcs1_5g=19
|
|
||||||
lvl_11ax_mcs2_5g=19
|
|
||||||
lvl_11ax_mcs3_5g=18
|
|
||||||
lvl_11ax_mcs4_5g=18
|
|
||||||
lvl_11ax_mcs5_5g=18
|
|
||||||
lvl_11ax_mcs6_5g=18
|
|
||||||
lvl_11ax_mcs7_5g=17
|
|
||||||
lvl_11ax_mcs8_5g=16
|
|
||||||
lvl_11ax_mcs9_5g=16
|
|
||||||
lvl_11ax_mcs10_5g=15
|
|
||||||
lvl_11ax_mcs11_5g=15
|
|
||||||
|
|
||||||
# txpwr_lvl_adj
|
|
||||||
lvl_adj_enable=0
|
|
||||||
lvl_adj_2g4_chan_1_4=0
|
|
||||||
lvl_adj_2g4_chan_5_9=0
|
|
||||||
lvl_adj_2g4_chan_10_13=0
|
|
||||||
lvl_adj_5g_chan_42=0
|
|
||||||
lvl_adj_5g_chan_58=0
|
|
||||||
lvl_adj_5g_chan_106=0
|
|
||||||
lvl_adj_5g_chan_122=0
|
|
||||||
lvl_adj_5g_chan_138=0
|
|
||||||
lvl_adj_5g_chan_155=0
|
|
||||||
|
|
||||||
# txpwr_loss
|
|
||||||
loss_enable_2g4=0
|
|
||||||
loss_value_2g4=2
|
|
||||||
loss_enable_5g=0
|
|
||||||
loss_value_5g=5
|
|
||||||
|
|
||||||
# txpwr_ofst
|
|
||||||
ofst_enable=0
|
|
||||||
ofst_2g4_11b_chan_1_4=0
|
|
||||||
ofst_2g4_11b_chan_5_9=0
|
|
||||||
ofst_2g4_11b_chan_10_13=0
|
|
||||||
ofst_2g4_ofdm_highrate_chan_1_4=0
|
|
||||||
ofst_2g4_ofdm_highrate_chan_5_9=0
|
|
||||||
ofst_2g4_ofdm_highrate_chan_10_13=0
|
|
||||||
ofst_2g4_ofdm_lowrate_chan_1_4=0
|
|
||||||
ofst_2g4_ofdm_lowrate_chan_5_9=0
|
|
||||||
ofst_2g4_ofdm_lowrate_chan_10_13=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_42=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_58=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_106=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_122=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_138=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_155=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_42=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_58=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_106=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_122=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_138=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_155=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_42=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_58=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_106=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_122=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_138=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_155=0
|
|
||||||
|
|
||||||
# xtal cap
|
|
||||||
xtal_enable=0
|
|
||||||
xtal_cap=24
|
|
||||||
xtal_cap_fine=31
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
# AIC USERCONFIG 2022/0803/1707
|
|
||||||
|
|
||||||
# txpwr_lvl
|
|
||||||
enable=1
|
|
||||||
lvl_11b_11ag_1m_2g4=20
|
|
||||||
lvl_11b_11ag_2m_2g4=20
|
|
||||||
lvl_11b_11ag_5m5_2g4=20
|
|
||||||
lvl_11b_11ag_11m_2g4=20
|
|
||||||
lvl_11b_11ag_6m_2g4=20
|
|
||||||
lvl_11b_11ag_9m_2g4=20
|
|
||||||
lvl_11b_11ag_12m_2g4=20
|
|
||||||
lvl_11b_11ag_18m_2g4=20
|
|
||||||
lvl_11b_11ag_24m_2g4=20
|
|
||||||
lvl_11b_11ag_36m_2g4=19
|
|
||||||
lvl_11b_11ag_48m_2g4=18
|
|
||||||
lvl_11b_11ag_54m_2g4=17
|
|
||||||
lvl_11n_11ac_mcs0_2g4=20
|
|
||||||
lvl_11n_11ac_mcs1_2g4=20
|
|
||||||
lvl_11n_11ac_mcs2_2g4=20
|
|
||||||
lvl_11n_11ac_mcs3_2g4=20
|
|
||||||
lvl_11n_11ac_mcs4_2g4=20
|
|
||||||
lvl_11n_11ac_mcs5_2g4=19
|
|
||||||
lvl_11n_11ac_mcs6_2g4=18
|
|
||||||
lvl_11n_11ac_mcs7_2g4=17
|
|
||||||
lvl_11n_11ac_mcs8_2g4=17
|
|
||||||
lvl_11n_11ac_mcs9_2g4=16
|
|
||||||
lvl_11ax_mcs0_2g4=20
|
|
||||||
lvl_11ax_mcs1_2g4=20
|
|
||||||
lvl_11ax_mcs2_2g4=20
|
|
||||||
lvl_11ax_mcs3_2g4=20
|
|
||||||
lvl_11ax_mcs4_2g4=20
|
|
||||||
lvl_11ax_mcs5_2g4=19
|
|
||||||
lvl_11ax_mcs6_2g4=18
|
|
||||||
lvl_11ax_mcs7_2g4=17
|
|
||||||
lvl_11ax_mcs8_2g4=17
|
|
||||||
lvl_11ax_mcs9_2g4=16
|
|
||||||
lvl_11ax_mcs10_2g4=15
|
|
||||||
lvl_11ax_mcs11_2g4=15
|
|
||||||
lvl_11a_6m_5g=19
|
|
||||||
lvl_11a_9m_5g=19
|
|
||||||
lvl_11a_12m_5g=19
|
|
||||||
lvl_11a_18m_5g=18
|
|
||||||
lvl_11a_24m_5g=18
|
|
||||||
lvl_11a_36m_5g=18
|
|
||||||
lvl_11a_48m_5g=18
|
|
||||||
lvl_11a_54m_5g=18
|
|
||||||
lvl_11n_11ac_mcs0_5g=19
|
|
||||||
lvl_11n_11ac_mcs1_5g=19
|
|
||||||
lvl_11n_11ac_mcs2_5g=19
|
|
||||||
lvl_11n_11ac_mcs3_5g=18
|
|
||||||
lvl_11n_11ac_mcs4_5g=18
|
|
||||||
lvl_11n_11ac_mcs5_5g=18
|
|
||||||
lvl_11n_11ac_mcs6_5g=18
|
|
||||||
lvl_11n_11ac_mcs7_5g=17
|
|
||||||
lvl_11n_11ac_mcs8_5g=15
|
|
||||||
lvl_11n_11ac_mcs9_5g=15
|
|
||||||
lvl_11ax_mcs0_5g=19
|
|
||||||
lvl_11ax_mcs1_5g=19
|
|
||||||
lvl_11ax_mcs2_5g=19
|
|
||||||
lvl_11ax_mcs3_5g=18
|
|
||||||
lvl_11ax_mcs4_5g=18
|
|
||||||
lvl_11ax_mcs5_5g=18
|
|
||||||
lvl_11ax_mcs6_5g=18
|
|
||||||
lvl_11ax_mcs7_5g=17
|
|
||||||
lvl_11ax_mcs8_5g=15
|
|
||||||
lvl_11ax_mcs9_5g=15
|
|
||||||
lvl_11ax_mcs10_5g=14
|
|
||||||
lvl_11ax_mcs11_5g=14
|
|
||||||
|
|
||||||
# txpwr_lvl_adj
|
|
||||||
lvl_adj_enable=0
|
|
||||||
lvl_adj_2g4_chan_1_4=0
|
|
||||||
lvl_adj_2g4_chan_5_9=0
|
|
||||||
lvl_adj_2g4_chan_10_13=0
|
|
||||||
lvl_adj_5g_chan_42=0
|
|
||||||
lvl_adj_5g_chan_58=0
|
|
||||||
lvl_adj_5g_chan_106=0
|
|
||||||
lvl_adj_5g_chan_122=0
|
|
||||||
lvl_adj_5g_chan_138=0
|
|
||||||
lvl_adj_5g_chan_155=0
|
|
||||||
|
|
||||||
# txpwr_loss
|
|
||||||
loss_enable_2g4=0
|
|
||||||
loss_value_2g4=2
|
|
||||||
loss_enable_5g=0
|
|
||||||
loss_value_5g=5
|
|
||||||
|
|
||||||
# txpwr_ofst
|
|
||||||
ofst_enable=0
|
|
||||||
ofst_2g4_11b_chan_1_4=0
|
|
||||||
ofst_2g4_11b_chan_5_9=0
|
|
||||||
ofst_2g4_11b_chan_10_13=0
|
|
||||||
ofst_2g4_ofdm_highrate_chan_1_4=0
|
|
||||||
ofst_2g4_ofdm_highrate_chan_5_9=0
|
|
||||||
ofst_2g4_ofdm_highrate_chan_10_13=0
|
|
||||||
ofst_2g4_ofdm_lowrate_chan_1_4=0
|
|
||||||
ofst_2g4_ofdm_lowrate_chan_5_9=0
|
|
||||||
ofst_2g4_ofdm_lowrate_chan_10_13=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_42=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_58=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_106=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_122=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_138=0
|
|
||||||
ofst_5g_ofdm_lowrate_chan_155=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_42=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_58=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_106=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_122=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_138=0
|
|
||||||
ofst_5g_ofdm_highrate_chan_155=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_42=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_58=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_106=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_122=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_138=0
|
|
||||||
ofst_5g_ofdm_midrate_chan_155=0
|
|
||||||
|
|
||||||
# xtal cap
|
|
||||||
xtal_enable=0
|
|
||||||
xtal_cap=24
|
|
||||||
xtal_cap_fine=31
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,117 +1,117 @@
|
|||||||
# AIC POWERLIMIT 2025/0623/1700
|
# AIC POWERLIMIT 2024/1108/1900
|
||||||
# Max tx power reference: Linux wireless regulatory database for CRDA
|
# Max tx power reference: Linux wireless regulatory database for CRDA
|
||||||
# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt
|
# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt
|
||||||
# If loss_value in aic_userconfig.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment
|
# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment
|
||||||
|
|
||||||
# Table 1:
|
# Table 1:
|
||||||
## 2.4G, 20M,#6#
|
## 2.4G, 20M,#5#
|
||||||
## START
|
## START
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
## SRRC FCC ETSI JP UNSET
|
||||||
CH01 16 14 14 16 16 15
|
CH01 15 15 15 15 15
|
||||||
CH02 16 14 14 16 16 16
|
CH02 16 16 16 16 16
|
||||||
CH03 16 14 14 16 16 16
|
CH03 16 16 16 16 16
|
||||||
CH04 16 14 14 16 16 16
|
CH04 16 16 16 16 16
|
||||||
CH05 16 14 14 16 16 16
|
CH05 16 16 16 16 16
|
||||||
CH06 16 14 14 16 16 16
|
CH06 16 16 16 16 16
|
||||||
CH07 16 14 14 16 16 16
|
CH07 16 16 16 16 16
|
||||||
CH08 16 14 14 16 16 16
|
CH08 16 16 16 16 16
|
||||||
CH09 16 14 14 16 16 16
|
CH09 16 16 16 16 16
|
||||||
CH10 16 14 14 16 16 16
|
CH10 16 16 16 16 16
|
||||||
CH11 16 14 14 16 16 16
|
CH11 16 16 16 16 16
|
||||||
CH12 15 14 14 16 16 12
|
CH12 12 12 12 12 12
|
||||||
CH13 13 14 14 16 16 12
|
CH13 12 12 12 12 12
|
||||||
CH14 NA NA NA 16 NA 12
|
CH14 NA NA NA 12 12
|
||||||
## END
|
## END
|
||||||
|
|
||||||
# Table 2:
|
# Table 2:
|
||||||
## 2.4G, 40M,#6#
|
## 2.4G, 40M,#5#
|
||||||
## START
|
## START
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
## SRRC FCC ETSI JP UNSET
|
||||||
CH01 NA NA NA NA NA NA
|
CH01 NA NA NA NA NA
|
||||||
CH02 NA NA NA NA NA NA
|
CH02 NA NA NA NA NA
|
||||||
CH03 16 13 14 16 16 16
|
CH03 16 16 16 16 16
|
||||||
CH04 16 13 14 16 16 16
|
CH04 16 16 16 16 16
|
||||||
CH05 16 13 14 16 16 16
|
CH05 16 16 16 16 16
|
||||||
CH06 16 13 14 16 16 16
|
CH06 16 16 16 16 16
|
||||||
CH07 16 13 14 16 16 16
|
CH07 16 16 16 16 16
|
||||||
CH08 16 13 14 16 16 16
|
CH08 16 16 16 16 16
|
||||||
CH09 16 11 14 16 16 16
|
CH09 16 16 16 16 16
|
||||||
CH10 16 11 14 16 16 16
|
CH10 16 16 16 16 16
|
||||||
CH11 16 11 14 16 16 16
|
CH11 16 16 16 16 16
|
||||||
CH12 NA NA NA NA NA NA
|
CH12 NA NA NA NA NA
|
||||||
CH13 NA NA NA NA NA NA
|
CH13 NA NA NA NA NA
|
||||||
CH14 NA NA NA NA NA NA
|
CH14 NA NA NA NA NA
|
||||||
## END
|
## END
|
||||||
|
|
||||||
# Table 3:
|
# Table 3:
|
||||||
## 5G, 20M,#6#
|
## 5G, 20M,#5#
|
||||||
## START
|
## START
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
## SRRC FCC ETSI JP UNSET
|
||||||
# 5G Band 1
|
# 5G Band 1
|
||||||
CH36 15 16 16 16 16 15
|
CH36 15 16 16 16 15
|
||||||
CH40 15 16 16 16 16 15
|
CH40 15 16 16 16 15
|
||||||
CH44 15 16 16 16 16 15
|
CH44 15 16 16 16 15
|
||||||
CH48 15 16 16 16 16 15
|
CH48 15 16 16 16 15
|
||||||
# 5G Band 2
|
# 5G Band 2
|
||||||
CH52 15 16 16 16 16 15
|
CH52 15 16 16 16 15
|
||||||
CH56 15 16 16 16 16 15
|
CH56 15 16 16 16 15
|
||||||
CH60 15 16 16 16 16 15
|
CH60 15 16 16 16 15
|
||||||
CH64 15 16 16 16 16 15
|
CH64 15 16 16 16 15
|
||||||
# 5G Band 3
|
# 5G Band 3
|
||||||
CH100 NA 16 16 16 16 15
|
CH100 NA 16 16 16 15
|
||||||
CH104 NA 16 16 16 16 15
|
CH104 NA 16 16 16 15
|
||||||
CH108 NA 16 16 16 16 15
|
CH108 NA 16 16 16 15
|
||||||
CH112 NA 16 16 16 16 15
|
CH112 NA 16 16 16 15
|
||||||
CH116 NA 16 16 16 16 15
|
CH116 NA 16 16 16 15
|
||||||
CH120 NA 16 16 16 16 15
|
CH120 NA 16 16 16 15
|
||||||
CH124 NA 16 16 16 16 15
|
CH124 NA 16 16 16 15
|
||||||
CH128 NA 16 16 16 16 15
|
CH128 NA 16 16 16 15
|
||||||
CH132 NA 16 16 16 16 15
|
CH132 NA 16 16 16 15
|
||||||
CH136 NA 16 16 16 16 15
|
CH136 NA 16 16 16 15
|
||||||
CH140 NA 16 16 16 16 15
|
CH140 NA 16 16 16 15
|
||||||
CH144 NA NA 16 16 16 15
|
CH144 NA NA 16 16 15
|
||||||
# 5G Band 4
|
# 5G Band 4
|
||||||
CH149 20 16 8 NA 20 11
|
CH149 16 16 11 NA 11
|
||||||
CH153 20 16 8 NA 20 11
|
CH153 16 16 11 NA 11
|
||||||
CH157 20 16 8 NA 20 11
|
CH157 16 16 11 NA 11
|
||||||
CH161 20 16 8 NA 20 11
|
CH161 16 16 11 NA 11
|
||||||
CH165 20 16 8 NA 20 11
|
CH165 16 16 11 NA 11
|
||||||
## END
|
## END
|
||||||
|
|
||||||
# Table 4:
|
# Table 4:
|
||||||
## 5G, 40M,#6#
|
## 5G, 40M,#5#
|
||||||
## START
|
## START
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
## SRRC FCC ETSI JP UNSET
|
||||||
# 5G Band 1
|
# 5G Band 1
|
||||||
CH38 15 16 16 16 20 15
|
CH38 15 16 16 16 15
|
||||||
CH46 15 16 16 16 20 15
|
CH46 15 16 16 16 15
|
||||||
# 5G Band 2
|
# 5G Band 2
|
||||||
CH54 15 16 16 16 20 15
|
CH54 15 16 16 16 15
|
||||||
CH62 15 16 16 16 20 15
|
CH62 15 16 16 16 15
|
||||||
# 5G Band 3
|
# 5G Band 3
|
||||||
CH102 NA 16 16 16 20 15
|
CH102 NA 16 16 16 15
|
||||||
CH110 NA 16 16 16 20 15
|
CH110 NA 16 16 16 15
|
||||||
CH118 NA 16 16 16 20 15
|
CH118 NA 16 16 16 15
|
||||||
CH126 NA 16 16 16 20 15
|
CH126 NA 16 16 16 15
|
||||||
CH134 NA 16 16 16 20 15
|
CH134 NA 16 16 16 15
|
||||||
CH142 NA 16 NA 16 20 15
|
CH142 NA 16 NA 16 15
|
||||||
# 5G Band 4
|
# 5G Band 4
|
||||||
CH151 16 15 8 NA 18 11
|
CH151 16 16 11 NA 11
|
||||||
CH159 17 16 8 NA 17 11
|
CH159 16 16 11 NA 11
|
||||||
## END
|
## END
|
||||||
|
|
||||||
# Table 5:
|
# Table 5:
|
||||||
## 5G, 80M,#6#
|
## 5G, 80M,#5#
|
||||||
## START
|
## START
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
## SRRC FCC ETSI JP UNSET
|
||||||
# 5G Band 1
|
# 5G Band 1
|
||||||
CH42 15 16 16 16 20 15
|
CH42 15 16 16 16 15
|
||||||
# 5G Band 2
|
# 5G Band 2
|
||||||
CH58 15 16 16 16 20 15
|
CH58 15 16 16 16 15
|
||||||
# 5G Band 3
|
# 5G Band 3
|
||||||
CH106 NA 16 16 16 20 15
|
CH106 NA 16 16 16 15
|
||||||
CH122 NA 16 16 16 20 15
|
CH122 NA 16 16 16 15
|
||||||
CH138 NA 16 NA NA 20 15
|
CH138 NA 16 NA NA 15
|
||||||
# 5G Band 4
|
# 5G Band 4
|
||||||
CH155 15 14 8 NA 16 11
|
CH155 16 16 11 NA 11
|
||||||
## END
|
## END
|
||||||
@@ -1,117 +1,117 @@
|
|||||||
# AIC POWERLIMIT 2025/0623/1700
|
# AIC POWERLIMIT 2024/1108/1900
|
||||||
# Max tx power reference: Linux wireless regulatory database for CRDA
|
# Max tx power reference: Linux wireless regulatory database for CRDA
|
||||||
# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt
|
# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt
|
||||||
# If loss_value in aic_userconfig.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment
|
# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment
|
||||||
|
|
||||||
# Table 1:
|
# Table 1:
|
||||||
## 2.4G, 20M,#6#
|
## 2.4G, 20M,#5#
|
||||||
## START
|
## START
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
## SRRC FCC ETSI JP UNSET
|
||||||
CH01 16 14 14 16 16 15
|
CH01 15 15 15 15 15
|
||||||
CH02 16 14 14 16 16 16
|
CH02 16 16 16 16 16
|
||||||
CH03 16 14 14 16 16 16
|
CH03 16 16 16 16 16
|
||||||
CH04 16 14 14 16 16 16
|
CH04 16 16 16 16 16
|
||||||
CH05 16 14 14 16 16 16
|
CH05 16 16 16 16 16
|
||||||
CH06 16 14 14 16 16 16
|
CH06 16 16 16 16 16
|
||||||
CH07 16 14 14 16 16 16
|
CH07 16 16 16 16 16
|
||||||
CH08 16 14 14 16 16 16
|
CH08 16 16 16 16 16
|
||||||
CH09 16 14 14 16 16 16
|
CH09 16 16 16 16 16
|
||||||
CH10 16 14 14 16 16 16
|
CH10 16 16 16 16 16
|
||||||
CH11 16 14 14 16 16 16
|
CH11 16 16 16 16 16
|
||||||
CH12 15 14 14 16 16 12
|
CH12 12 12 12 12 12
|
||||||
CH13 13 14 14 16 16 12
|
CH13 12 12 12 12 12
|
||||||
CH14 NA NA NA 16 NA 12
|
CH14 NA NA NA 12 12
|
||||||
## END
|
## END
|
||||||
|
|
||||||
# Table 2:
|
# Table 2:
|
||||||
## 2.4G, 40M,#6#
|
## 2.4G, 40M,#5#
|
||||||
## START
|
## START
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
## SRRC FCC ETSI JP UNSET
|
||||||
CH01 NA NA NA NA NA NA
|
CH01 NA NA NA NA NA
|
||||||
CH02 NA NA NA NA NA NA
|
CH02 NA NA NA NA NA
|
||||||
CH03 16 13 14 16 16 16
|
CH03 16 16 16 16 16
|
||||||
CH04 16 13 14 16 16 16
|
CH04 16 16 16 16 16
|
||||||
CH05 16 13 14 16 16 16
|
CH05 16 16 16 16 16
|
||||||
CH06 16 13 14 16 16 16
|
CH06 16 16 16 16 16
|
||||||
CH07 16 13 14 16 16 16
|
CH07 16 16 16 16 16
|
||||||
CH08 16 13 14 16 16 16
|
CH08 16 16 16 16 16
|
||||||
CH09 16 11 14 16 16 16
|
CH09 16 16 16 16 16
|
||||||
CH10 16 11 14 16 16 16
|
CH10 16 16 16 16 16
|
||||||
CH11 16 11 14 16 16 16
|
CH11 16 16 16 16 16
|
||||||
CH12 NA NA NA NA NA NA
|
CH12 NA NA NA NA NA
|
||||||
CH13 NA NA NA NA NA NA
|
CH13 NA NA NA NA NA
|
||||||
CH14 NA NA NA NA NA NA
|
CH14 NA NA NA NA NA
|
||||||
## END
|
## END
|
||||||
|
|
||||||
# Table 3:
|
# Table 3:
|
||||||
## 5G, 20M,#6#
|
## 5G, 20M,#5#
|
||||||
## START
|
## START
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
## SRRC FCC ETSI JP UNSET
|
||||||
# 5G Band 1
|
# 5G Band 1
|
||||||
CH36 15 16 16 16 16 15
|
CH36 15 16 16 16 15
|
||||||
CH40 15 16 16 16 16 15
|
CH40 15 16 16 16 15
|
||||||
CH44 15 16 16 16 16 15
|
CH44 15 16 16 16 15
|
||||||
CH48 15 16 16 16 16 15
|
CH48 15 16 16 16 15
|
||||||
# 5G Band 2
|
# 5G Band 2
|
||||||
CH52 15 16 16 16 16 15
|
CH52 15 16 16 16 15
|
||||||
CH56 15 16 16 16 16 15
|
CH56 15 16 16 16 15
|
||||||
CH60 15 16 16 16 16 15
|
CH60 15 16 16 16 15
|
||||||
CH64 15 16 16 16 16 15
|
CH64 15 16 16 16 15
|
||||||
# 5G Band 3
|
# 5G Band 3
|
||||||
CH100 NA 16 16 16 16 15
|
CH100 NA 16 16 16 15
|
||||||
CH104 NA 16 16 16 16 15
|
CH104 NA 16 16 16 15
|
||||||
CH108 NA 16 16 16 16 15
|
CH108 NA 16 16 16 15
|
||||||
CH112 NA 16 16 16 16 15
|
CH112 NA 16 16 16 15
|
||||||
CH116 NA 16 16 16 16 15
|
CH116 NA 16 16 16 15
|
||||||
CH120 NA 16 16 16 16 15
|
CH120 NA 16 16 16 15
|
||||||
CH124 NA 16 16 16 16 15
|
CH124 NA 16 16 16 15
|
||||||
CH128 NA 16 16 16 16 15
|
CH128 NA 16 16 16 15
|
||||||
CH132 NA 16 16 16 16 15
|
CH132 NA 16 16 16 15
|
||||||
CH136 NA 16 16 16 16 15
|
CH136 NA 16 16 16 15
|
||||||
CH140 NA 16 16 16 16 15
|
CH140 NA 16 16 16 15
|
||||||
CH144 NA NA 16 16 16 15
|
CH144 NA NA 16 16 15
|
||||||
# 5G Band 4
|
# 5G Band 4
|
||||||
CH149 20 16 8 NA 20 11
|
CH149 16 16 11 NA 11
|
||||||
CH153 20 16 8 NA 20 11
|
CH153 16 16 11 NA 11
|
||||||
CH157 20 16 8 NA 20 11
|
CH157 16 16 11 NA 11
|
||||||
CH161 20 16 8 NA 20 11
|
CH161 16 16 11 NA 11
|
||||||
CH165 20 16 8 NA 20 11
|
CH165 16 16 11 NA 11
|
||||||
## END
|
## END
|
||||||
|
|
||||||
# Table 4:
|
# Table 4:
|
||||||
## 5G, 40M,#6#
|
## 5G, 40M,#5#
|
||||||
## START
|
## START
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
## SRRC FCC ETSI JP UNSET
|
||||||
# 5G Band 1
|
# 5G Band 1
|
||||||
CH38 15 16 16 16 20 15
|
CH38 15 16 16 16 15
|
||||||
CH46 15 16 16 16 20 15
|
CH46 15 16 16 16 15
|
||||||
# 5G Band 2
|
# 5G Band 2
|
||||||
CH54 15 16 16 16 20 15
|
CH54 15 16 16 16 15
|
||||||
CH62 15 16 16 16 20 15
|
CH62 15 16 16 16 15
|
||||||
# 5G Band 3
|
# 5G Band 3
|
||||||
CH102 NA 16 16 16 20 15
|
CH102 NA 16 16 16 15
|
||||||
CH110 NA 16 16 16 20 15
|
CH110 NA 16 16 16 15
|
||||||
CH118 NA 16 16 16 20 15
|
CH118 NA 16 16 16 15
|
||||||
CH126 NA 16 16 16 20 15
|
CH126 NA 16 16 16 15
|
||||||
CH134 NA 16 16 16 20 15
|
CH134 NA 16 16 16 15
|
||||||
CH142 NA 16 NA 16 20 15
|
CH142 NA 16 NA 16 15
|
||||||
# 5G Band 4
|
# 5G Band 4
|
||||||
CH151 16 15 8 NA 18 11
|
CH151 16 16 11 NA 11
|
||||||
CH159 17 16 8 NA 17 11
|
CH159 16 16 11 NA 11
|
||||||
## END
|
## END
|
||||||
|
|
||||||
# Table 5:
|
# Table 5:
|
||||||
## 5G, 80M,#6#
|
## 5G, 80M,#5#
|
||||||
## START
|
## START
|
||||||
## SRRC FCC ETSI JP KCC UNSET
|
## SRRC FCC ETSI JP UNSET
|
||||||
# 5G Band 1
|
# 5G Band 1
|
||||||
CH42 15 16 16 16 20 15
|
CH42 15 16 16 16 15
|
||||||
# 5G Band 2
|
# 5G Band 2
|
||||||
CH58 15 16 16 16 20 15
|
CH58 15 16 16 16 15
|
||||||
# 5G Band 3
|
# 5G Band 3
|
||||||
CH106 NA 16 16 16 20 15
|
CH106 NA 16 16 16 15
|
||||||
CH122 NA 16 16 16 20 15
|
CH122 NA 16 16 16 15
|
||||||
CH138 NA 16 NA NA 20 15
|
CH138 NA 16 NA NA 15
|
||||||
# 5G Band 4
|
# 5G Band 4
|
||||||
CH155 15 14 8 NA 16 11
|
CH155 16 16 11 NA 11
|
||||||
## END
|
## END
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+93
-46
@@ -326,6 +326,7 @@ check_kernel_build_tree() {
|
|||||||
cleanup_legacy_bluetooth_config() {
|
cleanup_legacy_bluetooth_config() {
|
||||||
local legacy_conf="/etc/modprobe.d/aic8800-bt.conf"
|
local legacy_conf="/etc/modprobe.d/aic8800-bt.conf"
|
||||||
local legacy_udev="/etc/udev/rules.d/90-aic8800-mode-switch.rules"
|
local legacy_udev="/etc/udev/rules.d/90-aic8800-mode-switch.rules"
|
||||||
|
local legacy_package
|
||||||
local changed=false
|
local changed=false
|
||||||
|
|
||||||
if [ -f "$legacy_conf" ] && grep -Eq '^[[:space:]]*(softdep|alias)[^#]*aic_btusb([[:space:]]|$)' "$legacy_conf"; then
|
if [ -f "$legacy_conf" ] && grep -Eq '^[[:space:]]*(softdep|alias)[^#]*aic_btusb([[:space:]]|$)' "$legacy_conf"; then
|
||||||
@@ -358,6 +359,21 @@ cleanup_legacy_bluetooth_config() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Remove the two issue #63 diagnostic DKMS packages before the production
|
||||||
|
# quirk is installed as part of aic8800/1.0.0. A patched btusb may remain
|
||||||
|
# active in memory until reboot, but DKMS restores the distribution module
|
||||||
|
# on disk when its test package is removed.
|
||||||
|
for legacy_package in "btusb-aic-zlp/0.1" "aic-zlp-quirk/0.1"; do
|
||||||
|
if dkms status 2>/dev/null | grep -q "^${legacy_package},"; then
|
||||||
|
print_info "Removing superseded test package ${legacy_package}..."
|
||||||
|
if dkms remove "$legacy_package" --all >> "$LOG_FILE" 2>&1; then
|
||||||
|
changed=true
|
||||||
|
else
|
||||||
|
print_warning "Could not remove ${legacy_package}; remove it manually before reboot."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
if [ "$changed" = true ]; then
|
if [ "$changed" = true ]; then
|
||||||
print_success "Legacy Bluetooth configuration cleaned up."
|
print_success "Legacy Bluetooth configuration cleaned up."
|
||||||
fi
|
fi
|
||||||
@@ -393,12 +409,7 @@ install_firmware() {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
print_success "Firmware installed for all chip variants:"
|
print_success "Firmware installed for all supported chip variants."
|
||||||
print_info " - aic8800D80 (standard)"
|
|
||||||
print_info " - aic8800D80N (N variant)"
|
|
||||||
print_info " - aic8800D80X2 (X2 variant)"
|
|
||||||
print_info " - aic8800DC/DW (DC/DW series)"
|
|
||||||
print_info " - aic8800DLN (DLN variant)"
|
|
||||||
|
|
||||||
# Install udev rules
|
# Install udev rules
|
||||||
local rules_source="${SCRIPT_DIR}/aic.rules"
|
local rules_source="${SCRIPT_DIR}/aic.rules"
|
||||||
@@ -415,7 +426,7 @@ install_firmware() {
|
|||||||
print_warning "Udev rules file not found: $rules_source"
|
print_warning "Udev rules file not found: $rules_source"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Install usb_modeswitch configuration
|
# Install usb_modeswitch configuration for AIC8800D80 "Pandora" clone
|
||||||
local modeswitch_source="${SCRIPT_DIR}/usb_modeswitch/1111_1111"
|
local modeswitch_source="${SCRIPT_DIR}/usb_modeswitch/1111_1111"
|
||||||
local modeswitch_dest="/etc/usb_modeswitch.d/1111:1111"
|
local modeswitch_dest="/etc/usb_modeswitch.d/1111:1111"
|
||||||
|
|
||||||
@@ -465,6 +476,11 @@ BUILT_MODULE_NAME[1]="aic_load_fw"
|
|||||||
BUILT_MODULE_LOCATION[1]="drivers/aic8800/aic_load_fw"
|
BUILT_MODULE_LOCATION[1]="drivers/aic8800/aic_load_fw"
|
||||||
DEST_MODULE_LOCATION[1]="/updates/dkms"
|
DEST_MODULE_LOCATION[1]="/updates/dkms"
|
||||||
|
|
||||||
|
# Quirk ZLP para Bluetooth ACL bulk TX (somente 368b:8d81)
|
||||||
|
BUILT_MODULE_NAME[2]="aic_zlp_quirk"
|
||||||
|
BUILT_MODULE_LOCATION[2]="drivers/aic8800/aic_zlp_quirk"
|
||||||
|
DEST_MODULE_LOCATION[2]="/updates/dkms"
|
||||||
|
|
||||||
AUTOINSTALL="yes"
|
AUTOINSTALL="yes"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@@ -574,6 +590,20 @@ refresh_initramfs() {
|
|||||||
# Module Loading
|
# Module Loading
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
|
aic_zlp_target_present() {
|
||||||
|
local device
|
||||||
|
|
||||||
|
for device in /sys/bus/usb/devices/*; do
|
||||||
|
[ -r "$device/idVendor" ] || continue
|
||||||
|
[ -r "$device/idProduct" ] || continue
|
||||||
|
[ "$(cat "$device/idVendor")" = "368b" ] || continue
|
||||||
|
[ "$(cat "$device/idProduct")" = "8d81" ] || continue
|
||||||
|
return 0
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
load_module() {
|
load_module() {
|
||||||
print_step "Loading kernel modules..."
|
print_step "Loading kernel modules..."
|
||||||
|
|
||||||
@@ -582,14 +612,16 @@ load_module() {
|
|||||||
depmod -a >> "$LOG_FILE" 2>&1
|
depmod -a >> "$LOG_FILE" 2>&1
|
||||||
|
|
||||||
if lsmod | grep -q "$MODULE_NAME"; then
|
if lsmod | grep -q "$MODULE_NAME"; then
|
||||||
print_info "WiFi module already loaded. Reloading..."
|
print_info "Wi-Fi module already loaded. Reloading..."
|
||||||
modprobe -r "$MODULE_NAME" >> "$LOG_FILE" 2>&1 || true
|
modprobe -r "$MODULE_NAME" >> "$LOG_FILE" 2>&1 || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Load the WiFi module
|
# aic8800_fdrv depends on aic_load_fw, which initializes both Wi-Fi-only
|
||||||
|
# adapters and the Bluetooth firmware on combo adapters. If a standard HCI
|
||||||
|
# USB interface appears afterwards, the kernel USB modalias loads btusb.
|
||||||
print_info "Loading $MODULE_NAME..."
|
print_info "Loading $MODULE_NAME..."
|
||||||
if modprobe "$MODULE_NAME" >> "$LOG_FILE" 2>&1; then
|
if modprobe "$MODULE_NAME" >> "$LOG_FILE" 2>&1; then
|
||||||
print_success "WiFi module loaded successfully."
|
print_success "Wi-Fi module loaded successfully."
|
||||||
|
|
||||||
# Verify module is loaded
|
# Verify module is loaded
|
||||||
print_info "Waiting for module to initialize..."
|
print_info "Waiting for module to initialize..."
|
||||||
@@ -603,24 +635,29 @@ load_module() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ "$module_loaded" = true ]; then
|
if [ "$module_loaded" = true ]; then
|
||||||
print_success "WiFi module is active in kernel."
|
print_success "Wi-Fi module is active in kernel."
|
||||||
else
|
else
|
||||||
print_warning "WiFi module may not be fully initialized yet."
|
print_warning "Wi-Fi module may not be fully initialized yet."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
print_warning "WiFi module installed but could not be loaded immediately."
|
print_warning "Wi-Fi module installed but could not be loaded immediately."
|
||||||
print_info "This may be due to Secure Boot or missing hardware."
|
print_info "This may be due to Secure Boot or missing hardware."
|
||||||
print_info "Try rebooting or check: sudo dmesg | grep aic8800"
|
print_info "Try rebooting or check: sudo dmesg | grep aic8800"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Load the standard Bluetooth driver (btusb)
|
print_info "Combo adapters use the standard btusb driver when their Bluetooth interface appears."
|
||||||
# The aic_load_fw module uploads the Bluetooth firmware, then btusb handles the BT interface
|
|
||||||
print_info "Loading standard Bluetooth driver (btusb)..."
|
# The module has a USB alias and normally autoloads when 368b:8d81 appears.
|
||||||
if modprobe btusb >> "$LOG_FILE" 2>&1; then
|
# Explicitly load it here as well when that device was already present before
|
||||||
print_success "Bluetooth driver (btusb) loaded successfully."
|
# DKMS installation and therefore did not generate a new modalias event.
|
||||||
|
if aic_zlp_target_present; then
|
||||||
|
print_info "Loading the 368b:8d81 Bluetooth ACL ZLP quirk..."
|
||||||
|
if modprobe aic_zlp_quirk >> "$LOG_FILE" 2>&1; then
|
||||||
|
print_success "Device-scoped Bluetooth ZLP quirk is active."
|
||||||
else
|
else
|
||||||
print_warning "Could not load btusb driver automatically."
|
print_warning "The ZLP quirk could not attach; system btusb remains unchanged."
|
||||||
print_info "You can manually load it with: sudo modprobe btusb"
|
print_info "Check CONFIG_KPROBES, Secure Boot, and: sudo dmesg | grep aic_zlp_quirk"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,21 +678,33 @@ verify_installation() {
|
|||||||
print_warning "DKMS status unclear: $dkms_status"
|
print_warning "DKMS status unclear: $dkms_status"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if WiFi module is loaded
|
# Check if the Wi-Fi module is loaded
|
||||||
if lsmod | grep -q "$MODULE_NAME"; then
|
if lsmod | grep -q "$MODULE_NAME"; then
|
||||||
print_success "WiFi kernel module is loaded."
|
print_success "Wi-Fi kernel module is loaded."
|
||||||
else
|
else
|
||||||
print_info "WiFi module not currently loaded (this is OK if no hardware is connected)."
|
print_info "Wi-Fi module not currently loaded (this is OK if no hardware is connected)."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if Bluetooth is available via standard btusb
|
if lsmod | awk '{print $1}' | grep -qx 'btusb' || compgen -G '/sys/class/bluetooth/hci*' > /dev/null; then
|
||||||
if lsmod | grep -q "btusb"; then
|
print_success "A Bluetooth controller or the standard btusb module is present."
|
||||||
print_success "Bluetooth kernel module (btusb) is loaded."
|
|
||||||
else
|
else
|
||||||
print_info "Bluetooth module (btusb) not currently loaded (this is OK if no hardware is connected)."
|
print_info "No Bluetooth controller is present (normal for Wi-Fi-only adapters or when no combo adapter is connected)."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if aic_zlp_target_present; then
|
||||||
|
if lsmod | awk '{print $1}' | grep -qx 'aic_zlp_quirk'; then
|
||||||
|
local zlp_hook="unknown"
|
||||||
|
if [ -r /sys/module/aic_zlp_quirk/parameters/hook ]; then
|
||||||
|
zlp_hook=$(cat /sys/module/aic_zlp_quirk/parameters/hook)
|
||||||
|
fi
|
||||||
|
print_success "Bluetooth ACL ZLP quirk is loaded (hook: $zlp_hook)."
|
||||||
|
else
|
||||||
|
print_warning "USB device 368b:8d81 is present but aic_zlp_quirk is not loaded."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_info "Bluetooth ZLP quirk is installed but inactive (no 368b:8d81 device present)."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Show all loaded AIC modules
|
|
||||||
echo ""
|
echo ""
|
||||||
print_info "Loaded AIC modules:"
|
print_info "Loaded AIC modules:"
|
||||||
lsmod | grep aic || echo " (none)"
|
lsmod | grep aic || echo " (none)"
|
||||||
@@ -679,14 +728,13 @@ verify_installation() {
|
|||||||
iwconfig 2>/dev/null | grep -E "wlan|IEEE" || echo "No wireless interfaces detected (hardware may not be connected)"
|
iwconfig 2>/dev/null | grep -E "wlan|IEEE" || echo "No wireless interfaces detected (hardware may not be connected)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for Bluetooth interfaces
|
print_info "Checking for Bluetooth interfaces on combo adapters..."
|
||||||
print_info "Checking for Bluetooth interfaces..."
|
if command -v bluetoothctl &> /dev/null; then
|
||||||
if command -v hciconfig &> /dev/null; then
|
bluetoothctl list 2>/dev/null || echo "No Bluetooth interfaces detected (normal for Wi-Fi-only adapters)"
|
||||||
hciconfig 2>/dev/null || echo "No Bluetooth interfaces detected (hardware may not be connected)"
|
elif command -v hciconfig &> /dev/null; then
|
||||||
elif command -v bluetoothctl &> /dev/null; then
|
hciconfig 2>/dev/null || echo "No Bluetooth interfaces detected (normal for Wi-Fi-only adapters)"
|
||||||
bluetoothctl list 2>/dev/null || echo "No Bluetooth interfaces detected (hardware may not be connected)"
|
|
||||||
else
|
else
|
||||||
echo "Bluetooth tools not installed (install bluez package for Bluetooth support)"
|
echo "Bluetooth tools not installed (install BlueZ to manage a combo adapter)"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -702,14 +750,15 @@ show_final_instructions() {
|
|||||||
echo ""
|
echo ""
|
||||||
echo -e "${CYAN}Important Information:${NC}"
|
echo -e "${CYAN}Important Information:${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "✓ WiFi driver installed via DKMS"
|
echo "✓ Wi-Fi driver and firmware loader installed via DKMS"
|
||||||
echo "✓ Bluetooth supported via standard btusb driver (after firmware upload)"
|
echo "✓ Combo adapters use the standard Linux btusb driver"
|
||||||
|
echo "✓ Device-scoped Bluetooth ACL ZLP quirk installed for 368b:8d81"
|
||||||
echo "✓ Automatic rebuild enabled for kernel updates"
|
echo "✓ Automatic rebuild enabled for kernel updates"
|
||||||
echo "✓ Firmware installed in /lib/firmware/"
|
echo "✓ Firmware installed in /lib/firmware/"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${CYAN}Next Steps:${NC}"
|
echo -e "${CYAN}Next Steps:${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "1. Connect your AIC8800D80 USB WiFi/Bluetooth adapter"
|
echo "1. Connect your AIC8800 USB Wi-Fi or Wi-Fi/Bluetooth adapter"
|
||||||
echo ""
|
echo ""
|
||||||
echo "2. Check if the adapter is detected:"
|
echo "2. Check if the adapter is detected:"
|
||||||
echo " ${BLUE}lsusb | grep -i aic${NC}"
|
echo " ${BLUE}lsusb | grep -i aic${NC}"
|
||||||
@@ -718,14 +767,14 @@ show_final_instructions() {
|
|||||||
echo ""
|
echo ""
|
||||||
echo "3. View kernel messages about the driver:"
|
echo "3. View kernel messages about the driver:"
|
||||||
echo " ${BLUE}sudo dmesg | grep aic8800${NC}"
|
echo " ${BLUE}sudo dmesg | grep aic8800${NC}"
|
||||||
echo " ${BLUE}sudo dmesg | grep btusb${NC}"
|
echo " ${BLUE}sudo dmesg | grep -iE 'bluetooth|btusb|hci'${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "4. Connect to a WiFi network:"
|
echo "4. Connect to a WiFi network:"
|
||||||
echo " ${BLUE}nmcli device wifi list${NC}"
|
echo " ${BLUE}nmcli device wifi list${NC}"
|
||||||
echo " ${BLUE}nmcli device wifi connect \"SSID\" password \"PASSWORD\"${NC}"
|
echo " ${BLUE}nmcli device wifi connect \"SSID\" password \"PASSWORD\"${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "5. Check Bluetooth status:"
|
echo "5. For a combo adapter, check Bluetooth:"
|
||||||
echo " ${BLUE}bluetoothctl show${NC}"
|
echo " ${BLUE}bluetoothctl list${NC}"
|
||||||
echo " ${BLUE}bluetoothctl scan on${NC}"
|
echo " ${BLUE}bluetoothctl scan on${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${CYAN}Troubleshooting:${NC}"
|
echo -e "${CYAN}Troubleshooting:${NC}"
|
||||||
@@ -734,14 +783,12 @@ show_final_instructions() {
|
|||||||
echo " ${BLUE}dkms status${NC}"
|
echo " ${BLUE}dkms status${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "• Check loaded modules:"
|
echo "• Check loaded modules:"
|
||||||
echo " ${BLUE}lsmod | grep aic${NC}"
|
echo " ${BLUE}lsmod | grep -E 'aic|btusb'${NC}"
|
||||||
|
echo " ${BLUE}cat /sys/module/aic_zlp_quirk/parameters/{hook,injections}${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "• Manually load the WiFi module:"
|
echo "• Manually load the Wi-Fi module and firmware loader:"
|
||||||
echo " ${BLUE}sudo modprobe aic8800_fdrv${NC}"
|
echo " ${BLUE}sudo modprobe aic8800_fdrv${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "• Manually load the Bluetooth module:"
|
|
||||||
echo " ${BLUE}sudo modprobe btusb${NC}"
|
|
||||||
echo ""
|
|
||||||
echo "• View detailed logs:"
|
echo "• View detailed logs:"
|
||||||
echo " ${BLUE}cat $LOG_FILE${NC}"
|
echo " ${BLUE}cat $LOG_FILE${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
# AIC8800D80 legacy MCU revision 1 support
|
||||||
|
|
||||||
|
The `legacy-mcu1` branch is the maintained compatibility profile for the older
|
||||||
|
AIC8800D80 MCU revision tracked in
|
||||||
|
[issue #58](https://github.com/shenmintao/aic8800d80/issues/58), with related
|
||||||
|
reports in issues #14, #64, and #65. It is intended only for devices that log:
|
||||||
|
|
||||||
|
```text
|
||||||
|
chip_id=7, chip_mcu_id=1
|
||||||
|
```
|
||||||
|
|
||||||
|
Affected adapters have been observed entering through `a69c:572f` or a similar
|
||||||
|
mass-storage ID, changing to `a69c:8d80` for firmware loading, and failing when
|
||||||
|
the SDK V5 FMAC upload reaches address `0x170400`.
|
||||||
|
|
||||||
|
## Root cause
|
||||||
|
|
||||||
|
The affected MCU revision cannot accept the complete SDK V5 FMAC image in its
|
||||||
|
available upload window. With an upload base of `0x120000`, the deterministic
|
||||||
|
failure at `0x170400` gives a limit of about `0x50400` (328,704) bytes.
|
||||||
|
|
||||||
|
| Firmware | Size | End address (exclusive) | Relative to `0x170400` |
|
||||||
|
| --- | ---: | ---: | ---: |
|
||||||
|
| SDK V5 FMAC on `main` | 358,072 bytes | `0x1776B8` | 29,368 bytes over |
|
||||||
|
| SDK V3 FMAC on this branch | 327,037 bytes | `0x16FD7D` | 1,667 bytes free |
|
||||||
|
|
||||||
|
Replacing only the FMAC image is not sufficient. Earlier mixed-firmware tests
|
||||||
|
could enumerate but failed to provide a usable radio. This branch therefore
|
||||||
|
uses the complete matching AIC8800D80 firmware set from Radxa SDK V3, fixed at
|
||||||
|
upstream commit
|
||||||
|
[`254d47e6a131dbed5ba32131972f4719f3e1c7fe`](https://github.com/radxa-pkg/aic8800/commit/254d47e6a131dbed5ba32131972f4719f3e1c7fe),
|
||||||
|
together with its matching FMAC patch table and fixed patch-buffer layout.
|
||||||
|
|
||||||
|
For `chip_mcu_id=1`, the loader also reads register `0x40100020`, sets bit 0,
|
||||||
|
and writes it back before firmware upload. This is the MCU1 Bluetooth cache fix
|
||||||
|
identified in [PR #35](https://github.com/shenmintao/aic8800d80/pull/35).
|
||||||
|
Bluetooth continues to use the kernel's standard `btusb` driver; this branch
|
||||||
|
does not contain or install `aic_btusb`.
|
||||||
|
|
||||||
|
Firmware and loader paths for D80N, D80X2, and other variants are unchanged.
|
||||||
|
The same branch now also carries the separately validated legacy DC/DW profile
|
||||||
|
documented in the [issue #71 support notes](../issue71-mcu1-v3-profile/README.md).
|
||||||
|
|
||||||
|
## Hardware validation
|
||||||
|
|
||||||
|
The final profile was validated on a Steren COM-8231+ reporting
|
||||||
|
`chip_id=7, chip_mcu_id=1`. Test commit
|
||||||
|
[`027a7a8`](https://github.com/shenmintao/aic8800d80/commit/027a7a8)
|
||||||
|
demonstrated all of the following:
|
||||||
|
|
||||||
|
- the 327,037-byte FMAC uploads completely without `cmd timed-out` or
|
||||||
|
`bin upload fail: 170400`;
|
||||||
|
- the adapter completes `a69c:572f -> a69c:8d80 -> a69c:8d81` enumeration;
|
||||||
|
- 2.4 GHz and 5 GHz Wi-Fi scan, association, DHCP, and traffic work;
|
||||||
|
- USB interfaces 0 and 1 bind to system `btusb`, while interface 2 binds to
|
||||||
|
`aic8800_fdrv`;
|
||||||
|
- the earlier HCI Reset timeout `Opcode 0x0c03 failed: -110` is gone;
|
||||||
|
- Bluetooth scan and a real connection both succeed.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
From an existing clone:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git fetch origin
|
||||||
|
git switch legacy-mcu1
|
||||||
|
git pull --ff-only
|
||||||
|
sudo ./install.sh
|
||||||
|
sudo reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
The installer replaces the installed AIC firmware. Switching Git branches
|
||||||
|
without rerunning `install.sh` does not change the active firmware.
|
||||||
|
|
||||||
|
The expected V3 FMAC can be confirmed with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
stat -c '%s bytes' /lib/firmware/aic8800D80/fmacfw_8800d80_u02.bin
|
||||||
|
sha256sum /lib/firmware/aic8800D80/fmacfw_8800d80_u02.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected output:
|
||||||
|
|
||||||
|
```text
|
||||||
|
327037 bytes
|
||||||
|
1ec680c2b63dcaa0e5d33c5fb6d1857d030f8145c05c385e243760388a61a0da
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verify
|
||||||
|
|
||||||
|
After reboot or a physical disconnect/reconnect, check the complete device:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dmesg | grep -iE 'AIC8800D80|chip_id|chip_mcu_id|fmacfw|bin upload|cmd timed-out|Bluetooth|0x0c03|error -110'
|
||||||
|
lsusb -t
|
||||||
|
iw dev
|
||||||
|
bluetoothctl list
|
||||||
|
```
|
||||||
|
|
||||||
|
The initialization log should contain:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AIC8800D80 legacy: using Radxa SDK V3 loader profile
|
||||||
|
AIC8800D80 MCU1: enabled Bluetooth cache fix
|
||||||
|
```
|
||||||
|
|
||||||
|
`lsusb -t` should show Bluetooth interfaces using `btusb` and the Wi-Fi
|
||||||
|
interface using `aic8800_fdrv`. Verify traffic through the AIC network interface
|
||||||
|
rather than an onboard Wi-Fi adapter or phone/RNDIS connection.
|
||||||
|
|
||||||
|
## Return to current firmware
|
||||||
|
|
||||||
|
Newer `chip_mcu_id=0` hardware should use `main`. Reinstall after switching so
|
||||||
|
that the V5 firmware is restored under `/lib/firmware`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git switch main
|
||||||
|
git pull --ff-only
|
||||||
|
sudo ./install.sh
|
||||||
|
sudo reboot
|
||||||
|
```
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Shen Mintao <cx330.shen@autocore.ai>
|
|
||||||
Date: Fri, 17 Jul 2026 21:00:00 +0800
|
|
||||||
Subject: [PATCH] Bluetooth: btusb: add bulk TX ZLP quirk for AIC 8800D80
|
|
||||||
|
|
||||||
The AIC 8800D80 controller can stop returning HCI Number Of Completed
|
|
||||||
Packets events during sustained AAC A2DP traffic when driven by the
|
|
||||||
generic btusb transport. Once the controller's ACL credits are
|
|
||||||
exhausted, the connection is terminated by the HCI ACL TX watchdog.
|
|
||||||
|
|
||||||
The vendor transport sets URB_ZERO_PACKET on every ACL bulk OUT URB.
|
|
||||||
Add an equivalent, device-specific quirk to btusb for the 368b:8d81
|
|
||||||
variant so that the standard kernel driver retains control of the
|
|
||||||
device.
|
|
||||||
|
|
||||||
This is intentionally limited to the USB ID from the reproducer while
|
|
||||||
the behaviour is validated on additional AIC variants.
|
|
||||||
|
|
||||||
Link: https://github.com/shenmintao/aic8800d80/issues/63
|
|
||||||
Signed-off-by: Shen Mintao <cx330.shen@autocore.ai>
|
|
||||||
---
|
|
||||||
drivers/bluetooth/btusb.c | 10 ++++++++++
|
|
||||||
1 file changed, 10 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
|
|
||||||
index 830fefb342c6..97118c095369 100644
|
|
||||||
--- a/drivers/bluetooth/btusb.c
|
|
||||||
+++ b/drivers/bluetooth/btusb.c
|
|
||||||
@@ -67,6 +67,7 @@ static bool reset = true;
|
|
||||||
#define BTUSB_INTEL_NO_WBS_SUPPORT BIT(26)
|
|
||||||
#define BTUSB_ACTIONS_SEMI BIT(27)
|
|
||||||
#define BTUSB_BARROT BIT(28)
|
|
||||||
+#define BTUSB_BULK_TX_ZLP BIT(29)
|
|
||||||
|
|
||||||
static const struct usb_device_id btusb_table[] = {
|
|
||||||
/* Generic Bluetooth USB device */
|
|
||||||
@@ -178,5 +179,9 @@ MODULE_DEVICE_TABLE(usb, btusb_table);
|
|
||||||
|
|
||||||
static const struct usb_device_id quirks_table[] = {
|
|
||||||
+ /* AIC Semiconductor AIC 8800D80 */
|
|
||||||
+ { USB_DEVICE(0x368b, 0x8d81),
|
|
||||||
+ .driver_info = BTUSB_BULK_TX_ZLP },
|
|
||||||
+
|
|
||||||
/* CSR BlueCore devices */
|
|
||||||
{ USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR },
|
|
||||||
|
|
||||||
@@ -949,6 +954,7 @@ struct btusb_data {
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
bool poll_sync;
|
|
||||||
+ bool bulk_tx_zlp;
|
|
||||||
int intr_interval;
|
|
||||||
struct work_struct work;
|
|
||||||
struct work_struct waker;
|
|
||||||
@@ -2138,6 +2144,9 @@ static struct urb *alloc_bulk_urb(struct hci_dev *hdev, struct sk_buff *skb)
|
|
||||||
usb_fill_bulk_urb(urb, data->udev, pipe,
|
|
||||||
skb->data, skb->len, btusb_tx_complete, skb);
|
|
||||||
|
|
||||||
+ if (data->bulk_tx_zlp)
|
|
||||||
+ urb->transfer_flags |= URB_ZERO_PACKET;
|
|
||||||
+
|
|
||||||
skb->dev = (void *)hdev;
|
|
||||||
|
|
||||||
return urb;
|
|
||||||
@@ -4100,6 +4109,7 @@ static int btusb_probe(struct usb_interface *intf,
|
|
||||||
|
|
||||||
data->udev = interface_to_usbdev(intf);
|
|
||||||
data->intf = intf;
|
|
||||||
+ data->bulk_tx_zlp = id->driver_info & BTUSB_BULK_TX_ZLP;
|
|
||||||
|
|
||||||
INIT_WORK(&data->work, btusb_work);
|
|
||||||
INIT_WORK(&data->waker, btusb_waker);
|
|
||||||
--
|
|
||||||
2.50.1
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
# Issue #63: system `btusb` ZLP test
|
|
||||||
|
|
||||||
This test keeps the normal `aic_load_fw + btusb` architecture. It does not
|
|
||||||
restore or install the vendor `aic_btusb` driver.
|
|
||||||
|
|
||||||
The patch adds one quirk to the standard Linux `btusb` source:
|
|
||||||
|
|
||||||
- match only AICSemi `368b:8d81`;
|
|
||||||
- set `URB_ZERO_PACKET` on Bluetooth ACL bulk OUT transfers;
|
|
||||||
- leave every other `btusb` device and code path unchanged.
|
|
||||||
|
|
||||||
The test installer downloads the standard `btusb` source matching the running
|
|
||||||
kernel's upstream version, applies the patch, and installs the resulting
|
|
||||||
`btusb.ko` through DKMS. The distribution module is not overwritten and can be
|
|
||||||
restored by removing the DKMS test package.
|
|
||||||
|
|
||||||
## Install the test module
|
|
||||||
|
|
||||||
On Fedora, make sure the test build dependencies are installed:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo dnf install dkms gcc make kernel-devel-$(uname -r) curl patch
|
|
||||||
```
|
|
||||||
|
|
||||||
Stop Bluetooth scanning and disconnect Bluetooth devices, then run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd tests/issue63-btusb-zlp
|
|
||||||
sudo ./btusb-zlp-test.sh install
|
|
||||||
./btusb-zlp-test.sh status
|
|
||||||
```
|
|
||||||
|
|
||||||
`modinfo -n btusb` should point to an `updates/dkms` path. Secure Boot systems
|
|
||||||
may require the DKMS module to be signed or enrolled before it can load.
|
|
||||||
|
|
||||||
Select AAC again and play audio for at least one hour:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bluetoothctl scan off
|
|
||||||
pactl set-card-profile bluez_card.28_6F_40_46_AB_B1 a2dp-sink-aac
|
|
||||||
```
|
|
||||||
|
|
||||||
Please capture `sudo btmon -w issue63-zlp.btsnoop` and relevant `dmesg` lines if
|
|
||||||
the connection still stalls.
|
|
||||||
|
|
||||||
## Restore the distribution module
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo ./btusb-zlp-test.sh remove
|
|
||||||
./btusb-zlp-test.sh status
|
|
||||||
```
|
|
||||||
|
|
||||||
After removal, `modinfo -n btusb` should point back to the distribution's
|
|
||||||
`kernel/drivers/bluetooth/btusb.ko` path.
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
|
|
||||||
This is an A/B diagnostic patch, not a production workaround. If AAC remains
|
|
||||||
stable, the small kernel patch can be submitted upstream. If it still fails,
|
|
||||||
the next isolated experiment should add an AIC-specific runtime-PM quirk rather
|
|
||||||
than replacing the standard Bluetooth driver.
|
|
||||||
@@ -1,196 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
PACKAGE_NAME="btusb-aic-zlp"
|
|
||||||
PACKAGE_VERSION="0.1"
|
|
||||||
KERNEL_RELEASE="${KERNEL_RELEASE:-$(uname -r)}"
|
|
||||||
UPSTREAM_VERSION="${UPSTREAM_VERSION:-$(printf '%s' "$KERNEL_RELEASE" | sed -nE 's/^([0-9]+\.[0-9]+\.[0-9]+).*/\1/p')}"
|
|
||||||
UPSTREAM_TAG="${UPSTREAM_TAG:-v${UPSTREAM_VERSION}}"
|
|
||||||
KERNEL_BUILD_DIR="/lib/modules/${KERNEL_RELEASE}/build"
|
|
||||||
SOURCE_DIR="/usr/src/${PACKAGE_NAME}-${PACKAGE_VERSION}"
|
|
||||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
PATCH_FILE="${SCRIPT_DIR}/0001-Bluetooth-btusb-add-AIC-bulk-TX-ZLP-quirk.patch"
|
|
||||||
BASE_URL="https://raw.githubusercontent.com/gregkh/linux/${UPSTREAM_TAG}/drivers/bluetooth"
|
|
||||||
|
|
||||||
log() {
|
|
||||||
printf '[btusb-zlp-test] %s\n' "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
die() {
|
|
||||||
printf '[btusb-zlp-test] ERROR: %s\n' "$*" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
require_root() {
|
|
||||||
[ "$(id -u)" -eq 0 ] || die "run this command as root"
|
|
||||||
}
|
|
||||||
|
|
||||||
require_command() {
|
|
||||||
command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
stop_bluetooth() {
|
|
||||||
if command -v systemctl >/dev/null 2>&1; then
|
|
||||||
systemctl stop bluetooth.service 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
start_bluetooth() {
|
|
||||||
if command -v systemctl >/dev/null 2>&1; then
|
|
||||||
systemctl start bluetooth.service 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
rollback_test_install() {
|
|
||||||
log "rolling back to the distribution btusb module"
|
|
||||||
dkms remove -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" --all >/dev/null 2>&1 || true
|
|
||||||
rm -rf -- "${SOURCE_DIR}"
|
|
||||||
depmod -a "${KERNEL_RELEASE}" || true
|
|
||||||
modprobe btusb || true
|
|
||||||
start_bluetooth
|
|
||||||
}
|
|
||||||
|
|
||||||
activate_test_module() {
|
|
||||||
stop_bluetooth
|
|
||||||
|
|
||||||
if ! modprobe -r btusb; then
|
|
||||||
rollback_test_install
|
|
||||||
die "could not unload btusb; disconnect active Bluetooth devices and retry"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! modprobe btusb; then
|
|
||||||
rollback_test_install
|
|
||||||
die "the patched btusb could not load; the distribution module was restored"
|
|
||||||
fi
|
|
||||||
|
|
||||||
start_bluetooth
|
|
||||||
}
|
|
||||||
|
|
||||||
write_build_files() {
|
|
||||||
cat > "${SOURCE_DIR}/Makefile" <<'EOF'
|
|
||||||
KVER ?= $(shell uname -r)
|
|
||||||
KDIR ?= /lib/modules/$(KVER)/build
|
|
||||||
|
|
||||||
obj-m += btusb.o
|
|
||||||
btusb-y := drivers/bluetooth/btusb.o
|
|
||||||
ccflags-y += -I$(src)/drivers/bluetooth
|
|
||||||
|
|
||||||
all:
|
|
||||||
$(MAKE) -C $(KDIR) M=$(CURDIR) modules
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(MAKE) -C $(KDIR) M=$(CURDIR) clean
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat > "${SOURCE_DIR}/dkms.conf" <<'EOF'
|
|
||||||
PACKAGE_NAME="btusb-aic-zlp"
|
|
||||||
PACKAGE_VERSION="0.1"
|
|
||||||
MAKE[0]="make KVER=${kernelver}"
|
|
||||||
CLEAN="make KVER=${kernelver} clean"
|
|
||||||
BUILT_MODULE_NAME[0]="btusb"
|
|
||||||
BUILT_MODULE_LOCATION[0]="."
|
|
||||||
DEST_MODULE_LOCATION[0]="/updates/dkms"
|
|
||||||
AUTOINSTALL="no"
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
download_sources() {
|
|
||||||
local file
|
|
||||||
|
|
||||||
install -d "${SOURCE_DIR}/drivers/bluetooth"
|
|
||||||
|
|
||||||
for file in btusb.c btintel.h btbcm.h btrtl.h btmtk.h; do
|
|
||||||
log "downloading ${file} from Linux ${UPSTREAM_TAG}"
|
|
||||||
curl --fail --location --silent --show-error \
|
|
||||||
"${BASE_URL}/${file}" \
|
|
||||||
--output "${SOURCE_DIR}/drivers/bluetooth/${file}"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
install_test_module() {
|
|
||||||
require_root
|
|
||||||
require_command curl
|
|
||||||
require_command dkms
|
|
||||||
require_command make
|
|
||||||
require_command modprobe
|
|
||||||
require_command patch
|
|
||||||
|
|
||||||
[ -n "${UPSTREAM_VERSION}" ] || die "could not derive an upstream version from ${KERNEL_RELEASE}"
|
|
||||||
[ -r "${KERNEL_BUILD_DIR}/Makefile" ] || die "kernel build tree not found: ${KERNEL_BUILD_DIR}"
|
|
||||||
[ -r "${PATCH_FILE}" ] || die "patch file not found: ${PATCH_FILE}"
|
|
||||||
|
|
||||||
if command -v lsusb >/dev/null 2>&1 && ! lsusb -d 368b:8d81 >/dev/null 2>&1; then
|
|
||||||
die "the test patch is restricted to USB device 368b:8d81, which is not connected"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if dkms status -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" 2>/dev/null | grep -q .; then
|
|
||||||
log "removing an earlier test build"
|
|
||||||
dkms remove -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" --all || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -rf -- "${SOURCE_DIR}"
|
|
||||||
download_sources
|
|
||||||
write_build_files
|
|
||||||
|
|
||||||
log "applying the AIC bulk TX ZLP quirk"
|
|
||||||
patch --directory "${SOURCE_DIR}" --strip 1 --input "${PATCH_FILE}"
|
|
||||||
|
|
||||||
log "building patched system btusb for ${KERNEL_RELEASE}"
|
|
||||||
dkms add -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}"
|
|
||||||
dkms build -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" -k "${KERNEL_RELEASE}"
|
|
||||||
dkms install -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" \
|
|
||||||
-k "${KERNEL_RELEASE}" --force
|
|
||||||
depmod -a "${KERNEL_RELEASE}"
|
|
||||||
|
|
||||||
activate_test_module
|
|
||||||
|
|
||||||
log "loaded module: $(modinfo -n btusb)"
|
|
||||||
log "test AAC playback for at least one hour; use '$0 remove' to restore the distribution module"
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_test_module() {
|
|
||||||
require_root
|
|
||||||
require_command dkms
|
|
||||||
require_command modprobe
|
|
||||||
|
|
||||||
stop_bluetooth
|
|
||||||
modprobe -r btusb || {
|
|
||||||
start_bluetooth
|
|
||||||
die "could not unload btusb; disconnect active Bluetooth devices and retry"
|
|
||||||
}
|
|
||||||
|
|
||||||
dkms remove -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" --all || true
|
|
||||||
rm -rf -- "${SOURCE_DIR}"
|
|
||||||
depmod -a "${KERNEL_RELEASE}"
|
|
||||||
|
|
||||||
modprobe btusb || {
|
|
||||||
start_bluetooth
|
|
||||||
die "the distribution btusb module could not be loaded"
|
|
||||||
}
|
|
||||||
start_bluetooth
|
|
||||||
|
|
||||||
log "restored module: $(modinfo -n btusb)"
|
|
||||||
}
|
|
||||||
|
|
||||||
show_status() {
|
|
||||||
printf 'kernel: %s\n' "${KERNEL_RELEASE}"
|
|
||||||
printf 'upstream tag: %s\n' "${UPSTREAM_TAG}"
|
|
||||||
printf 'btusb module: %s\n' "$(modinfo -n btusb 2>/dev/null || printf 'not found')"
|
|
||||||
printf 'dkms status: %s\n' "$(dkms status -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" 2>/dev/null || printf 'not installed')"
|
|
||||||
}
|
|
||||||
|
|
||||||
case "${1:-}" in
|
|
||||||
install)
|
|
||||||
install_test_module
|
|
||||||
;;
|
|
||||||
remove)
|
|
||||||
remove_test_module
|
|
||||||
;;
|
|
||||||
status)
|
|
||||||
show_status
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
printf 'Usage: %s {install|remove|status}\n' "$0" >&2
|
|
||||||
exit 2
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
KVER ?= $(shell uname -r)
|
||||||
|
KDIR ?= /lib/modules/$(KVER)/build
|
||||||
|
|
||||||
|
obj-m += aic_zlp_quirk.o
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
all:
|
||||||
|
$(MAKE) -C $(KDIR) M=$(CURDIR) modules
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C $(KDIR) M=$(CURDIR) clean
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
# Issue #63: standard `btusb` ACL ZLP support
|
||||||
|
|
||||||
|
The `aic_zlp_quirk` companion module supplies the Bluetooth ACL bulk TX
|
||||||
|
zero-length-packet behavior confirmed in
|
||||||
|
[issue #63](https://github.com/shenmintao/aic8800d80/issues/63). It is now part
|
||||||
|
of the normal `aic8800` DKMS build rather than a replacement for the
|
||||||
|
distribution's Bluetooth driver.
|
||||||
|
|
||||||
|
The validated failure was specific and reproducible: AAC playback through USB
|
||||||
|
device `368b:8d81` stalled after about one minute, while SBC remained stable.
|
||||||
|
Adding `URB_ZERO_PACKET` to the ACL bulk OUT URBs kept AAC connected for more
|
||||||
|
than one hour. The standalone module was then verified with the system
|
||||||
|
`btusb`, no loaded `aic_btusb`, and 2,113 observed ZLP injections.
|
||||||
|
|
||||||
|
## Architecture and scope
|
||||||
|
|
||||||
|
The module first tries to attach a kretprobe to the standard `btusb` function
|
||||||
|
that allocates ACL bulk OUT URBs. The target is module-qualified as
|
||||||
|
`btusb:alloc_bulk_urb`, avoiding similarly named symbols in unrelated USB
|
||||||
|
drivers.
|
||||||
|
|
||||||
|
Some distribution builds inline that private function. When the preferred hook
|
||||||
|
is unavailable, the module falls back to the stable `usb_submit_urb` entry
|
||||||
|
point. The fallback changes an URB only when all of these checks pass:
|
||||||
|
|
||||||
|
- USB device is exactly `368b:8d81`;
|
||||||
|
- the transfer is bulk OUT;
|
||||||
|
- the endpoint belongs to Bluetooth interface 0 (`e0/01/01`).
|
||||||
|
|
||||||
|
Both paths add only `URB_ZERO_PACKET`. Wi-Fi interfaces and unrelated USB
|
||||||
|
devices are unchanged. If neither probe can be installed or kprobes are
|
||||||
|
disabled, the module refuses to load and system `btusb` remains unchanged.
|
||||||
|
|
||||||
|
The module carries a USB modalias for `368b:8d81`, so it is inactive on other
|
||||||
|
hardware and normally autoloads only when the validated device appears.
|
||||||
|
|
||||||
|
## Install from the unified branch
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git fetch origin
|
||||||
|
git switch test/unified-wifi-bt-zlp
|
||||||
|
git pull --ff-only
|
||||||
|
sudo ./install.sh
|
||||||
|
sudo reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
The installer removes the earlier `btusb-aic-zlp/0.1` and
|
||||||
|
`aic-zlp-quirk/0.1` diagnostic DKMS packages when present. To remove them
|
||||||
|
manually before installation, use:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dkms remove btusb-aic-zlp/0.1 --all
|
||||||
|
sudo dkms remove aic-zlp-quirk/0.1 --all
|
||||||
|
sudo depmod -a
|
||||||
|
```
|
||||||
|
|
||||||
|
The unified installer also removes active configuration left by the obsolete
|
||||||
|
custom `aic_btusb` transport.
|
||||||
|
|
||||||
|
## Verify
|
||||||
|
|
||||||
|
Confirm that system `btusb` owns Bluetooth interfaces 0/1 and that the quirk is
|
||||||
|
loaded:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lsusb -t
|
||||||
|
lsmod | grep -E '^(btusb|aic_zlp_quirk|aic_btusb)\b'
|
||||||
|
modinfo -n btusb
|
||||||
|
modinfo -n aic_zlp_quirk
|
||||||
|
cat /sys/module/aic_zlp_quirk/parameters/hook
|
||||||
|
cat /sys/module/aic_zlp_quirk/parameters/injections
|
||||||
|
sudo ./diagnose_bt.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected results include:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Bluetooth interfaces 0/1: btusb
|
||||||
|
aic_btusb: not loaded
|
||||||
|
aic_zlp_quirk: loaded
|
||||||
|
active hook: btusb:alloc_bulk_urb
|
||||||
|
```
|
||||||
|
|
||||||
|
`active hook: usb_submit_urb` is also valid when the compiler inlined the
|
||||||
|
preferred function. During Bluetooth traffic, the `injections` value must
|
||||||
|
increase.
|
||||||
|
|
||||||
|
For the promotion test, select AAC and play audio for at least one hour while
|
||||||
|
also confirming that Wi-Fi scan, association, DHCP, and real traffic remain
|
||||||
|
working.
|
||||||
|
|
||||||
|
## Isolated retest helper
|
||||||
|
|
||||||
|
`aic-zlp-quirk-test.sh` remains available only for isolated issue #63 retests.
|
||||||
|
It builds the same canonical source from
|
||||||
|
`drivers/aic8800/aic_zlp_quirk/aic_zlp_quirk.c` as a separate DKMS package. A
|
||||||
|
normal installation should use the repository-level `install.sh` instead.
|
||||||
|
|
||||||
|
## Kernel requirements
|
||||||
|
|
||||||
|
- matching kernel headers;
|
||||||
|
- `CONFIG_KPROBES=y` and kretprobe support;
|
||||||
|
- standard `btusb` plus either its `alloc_bulk_urb` symbol or the USB core
|
||||||
|
`usb_submit_urb` symbol;
|
||||||
|
- a valid module signature when Secure Boot policy requires one.
|
||||||
|
|
||||||
|
The preferred function has the same signature in Linux 5.15, 6.1, 6.6, 6.12,
|
||||||
|
6.18, and 7.1.3, although compilers may inline it. DKMS builds one module for
|
||||||
|
each installed kernel from the single canonical source file.
|
||||||
+239
@@ -0,0 +1,239 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PACKAGE_NAME="aic-zlp-quirk"
|
||||||
|
PACKAGE_VERSION="0.1"
|
||||||
|
MODULE_NAME="aic_zlp_quirk"
|
||||||
|
KERNEL_RELEASE="${KERNEL_RELEASE:-$(uname -r)}"
|
||||||
|
KERNEL_BUILD_DIR="/lib/modules/${KERNEL_RELEASE}/build"
|
||||||
|
SOURCE_DIR="/usr/src/${PACKAGE_NAME}-${PACKAGE_VERSION}"
|
||||||
|
MODULES_LOAD_FILE="/etc/modules-load.d/${PACKAGE_NAME}.conf"
|
||||||
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/../.." && pwd)"
|
||||||
|
QUIRK_SOURCE="${REPO_ROOT}/drivers/aic8800/aic_zlp_quirk/aic_zlp_quirk.c"
|
||||||
|
|
||||||
|
log() {
|
||||||
|
printf '[aic-zlp-quirk-test] %s\n' "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die() {
|
||||||
|
printf '[aic-zlp-quirk-test] ERROR: %s\n' "$*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
require_root() {
|
||||||
|
[ "$(id -u)" -eq 0 ] || die "run this command as root"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_command() {
|
||||||
|
command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_bluetooth() {
|
||||||
|
if command -v systemctl >/dev/null 2>&1; then
|
||||||
|
systemctl stop bluetooth.service 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
start_bluetooth() {
|
||||||
|
if command -v systemctl >/dev/null 2>&1; then
|
||||||
|
systemctl start bluetooth.service 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
module_loaded() {
|
||||||
|
[ -d "/sys/module/$1" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
legacy_btusb_loaded() {
|
||||||
|
module_loaded aic_btusb
|
||||||
|
}
|
||||||
|
|
||||||
|
patched_btusb_installed() {
|
||||||
|
dkms status -m btusb-aic-zlp -v 0.1 2>/dev/null | grep -q .
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_sources() {
|
||||||
|
install -d "${SOURCE_DIR}"
|
||||||
|
install -m 0644 "${QUIRK_SOURCE}" "${SOURCE_DIR}/"
|
||||||
|
install -m 0644 "${SCRIPT_DIR}/Makefile" "${SOURCE_DIR}/"
|
||||||
|
install -m 0644 "${SCRIPT_DIR}/dkms.conf" "${SOURCE_DIR}/"
|
||||||
|
}
|
||||||
|
|
||||||
|
rollback_install() {
|
||||||
|
log "rolling back the ZLP companion module"
|
||||||
|
rm -f -- "${MODULES_LOAD_FILE}"
|
||||||
|
modprobe -r "${MODULE_NAME}" >/dev/null 2>&1 || true
|
||||||
|
dkms remove -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" --all >/dev/null 2>&1 || true
|
||||||
|
rm -rf -- "${SOURCE_DIR}"
|
||||||
|
depmod -a "${KERNEL_RELEASE}" >/dev/null 2>&1 || true
|
||||||
|
start_bluetooth
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_standard_btusb() {
|
||||||
|
if legacy_btusb_loaded; then
|
||||||
|
die "obsolete aic_btusb is loaded; run 'sudo modprobe -r aic_btusb' and remove its old autoload configuration first"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if patched_btusb_installed; then
|
||||||
|
die "the patched btusb test package is still installed; remove it before testing the companion module"
|
||||||
|
fi
|
||||||
|
|
||||||
|
modprobe btusb || die "could not load the system btusb module"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_module() {
|
||||||
|
require_root
|
||||||
|
require_command dkms
|
||||||
|
require_command make
|
||||||
|
require_command modprobe
|
||||||
|
require_command depmod
|
||||||
|
|
||||||
|
[ -r "${KERNEL_BUILD_DIR}/Makefile" ] || \
|
||||||
|
die "kernel build tree not found: ${KERNEL_BUILD_DIR}"
|
||||||
|
|
||||||
|
if command -v lsusb >/dev/null 2>&1 && ! lsusb -d 368b:8d81 >/dev/null 2>&1; then
|
||||||
|
die "this test is restricted to USB device 368b:8d81, which is not connected"
|
||||||
|
fi
|
||||||
|
|
||||||
|
verify_standard_btusb
|
||||||
|
|
||||||
|
if module_loaded "${MODULE_NAME}"; then
|
||||||
|
log "unloading the earlier companion module"
|
||||||
|
if ! modprobe -r "${MODULE_NAME}"; then
|
||||||
|
die "could not unload the earlier ${MODULE_NAME} module"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
trap rollback_install ERR
|
||||||
|
|
||||||
|
if dkms status -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" 2>/dev/null | grep -q .; then
|
||||||
|
log "removing an earlier companion-module build"
|
||||||
|
dkms remove -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" --all
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf -- "${SOURCE_DIR}"
|
||||||
|
copy_sources
|
||||||
|
|
||||||
|
log "building the ZLP companion module for ${KERNEL_RELEASE}"
|
||||||
|
dkms add -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}"
|
||||||
|
dkms build -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" -k "${KERNEL_RELEASE}"
|
||||||
|
dkms install -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" \
|
||||||
|
-k "${KERNEL_RELEASE}" --force
|
||||||
|
depmod -a "${KERNEL_RELEASE}"
|
||||||
|
|
||||||
|
printf '%s\n' "${MODULE_NAME}" > "${MODULES_LOAD_FILE}"
|
||||||
|
|
||||||
|
stop_bluetooth
|
||||||
|
if ! modprobe "${MODULE_NAME}"; then
|
||||||
|
trap - ERR
|
||||||
|
rollback_install
|
||||||
|
die "the companion module could not attach; the system btusb was left unchanged"
|
||||||
|
fi
|
||||||
|
start_bluetooth
|
||||||
|
trap - ERR
|
||||||
|
|
||||||
|
log "loaded module: $(modinfo -n "${MODULE_NAME}")"
|
||||||
|
log "system btusb remains active; test AAC playback for at least one hour"
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_module() {
|
||||||
|
require_root
|
||||||
|
require_command dkms
|
||||||
|
require_command modprobe
|
||||||
|
require_command depmod
|
||||||
|
|
||||||
|
stop_bluetooth
|
||||||
|
rm -f -- "${MODULES_LOAD_FILE}"
|
||||||
|
if module_loaded "${MODULE_NAME}" && ! modprobe -r "${MODULE_NAME}"; then
|
||||||
|
start_bluetooth
|
||||||
|
die "could not unload ${MODULE_NAME}; no files were removed"
|
||||||
|
fi
|
||||||
|
if dkms status -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" 2>/dev/null | grep -q .; then
|
||||||
|
if ! dkms remove -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" --all; then
|
||||||
|
start_bluetooth
|
||||||
|
die "DKMS removal failed; source files were left in place"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
rm -rf -- "${SOURCE_DIR}"
|
||||||
|
depmod -a "${KERNEL_RELEASE}"
|
||||||
|
start_bluetooth
|
||||||
|
|
||||||
|
log "removed the companion module; the distribution btusb was never replaced"
|
||||||
|
}
|
||||||
|
|
||||||
|
show_aic_binding() {
|
||||||
|
local device
|
||||||
|
local driver
|
||||||
|
|
||||||
|
for device in /sys/bus/usb/devices/*; do
|
||||||
|
[ -r "${device}/idVendor" ] || continue
|
||||||
|
[ -r "${device}/idProduct" ] || continue
|
||||||
|
[ "$(cat "${device}/idVendor")" = "368b" ] || continue
|
||||||
|
[ "$(cat "${device}/idProduct")" = "8d81" ] || continue
|
||||||
|
|
||||||
|
driver="not bound"
|
||||||
|
if [ -L "${device}:1.0/driver" ]; then
|
||||||
|
driver="$(basename "$(readlink -f "${device}:1.0/driver")")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'AIC BT driver: %s\n' "${driver}"
|
||||||
|
return
|
||||||
|
done
|
||||||
|
|
||||||
|
printf 'AIC BT driver: device not found\n'
|
||||||
|
}
|
||||||
|
|
||||||
|
show_status() {
|
||||||
|
local loaded="no"
|
||||||
|
local injections="unavailable"
|
||||||
|
local hook="unavailable"
|
||||||
|
local integrated_dkms_status
|
||||||
|
local standalone_dkms_status
|
||||||
|
|
||||||
|
if module_loaded "${MODULE_NAME}"; then
|
||||||
|
loaded="yes"
|
||||||
|
if [ -r "/sys/module/${MODULE_NAME}/parameters/injections" ]; then
|
||||||
|
injections="$(cat "/sys/module/${MODULE_NAME}/parameters/injections")"
|
||||||
|
fi
|
||||||
|
if [ -r "/sys/module/${MODULE_NAME}/parameters/hook" ]; then
|
||||||
|
hook="$(cat "/sys/module/${MODULE_NAME}/parameters/hook")"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
standalone_dkms_status="$(dkms status -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" 2>/dev/null || true)"
|
||||||
|
if [ -z "${standalone_dkms_status}" ]; then
|
||||||
|
standalone_dkms_status="not installed"
|
||||||
|
fi
|
||||||
|
integrated_dkms_status="$(dkms status -m aic8800 -v 1.0.0 2>/dev/null || true)"
|
||||||
|
if [ -z "${integrated_dkms_status}" ]; then
|
||||||
|
integrated_dkms_status="not installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'kernel: %s\n' "${KERNEL_RELEASE}"
|
||||||
|
printf 'btusb module: %s\n' "$(modinfo -n btusb 2>/dev/null || printf 'not found')"
|
||||||
|
printf 'quirk module: %s\n' "$(modinfo -n "${MODULE_NAME}" 2>/dev/null || printf 'not found')"
|
||||||
|
printf 'quirk loaded: %s\n' "${loaded}"
|
||||||
|
printf 'active hook: %s\n' "${hook}"
|
||||||
|
printf 'ZLP injections:%s\n' " ${injections}"
|
||||||
|
printf 'legacy aic_btusb: %s\n' "$(legacy_btusb_loaded && printf 'loaded' || printf 'not loaded')"
|
||||||
|
printf 'integrated DKMS: %s\n' "${integrated_dkms_status}"
|
||||||
|
printf 'standalone DKMS: %s\n' "${standalone_dkms_status}"
|
||||||
|
show_aic_binding
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
install)
|
||||||
|
install_module
|
||||||
|
;;
|
||||||
|
remove)
|
||||||
|
remove_module
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf 'Usage: %s {install|remove|status}\n' "$0" >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
PACKAGE_NAME="aic-zlp-quirk"
|
||||||
|
PACKAGE_VERSION="0.1"
|
||||||
|
|
||||||
|
MAKE[0]="make KVER=${kernelver}"
|
||||||
|
CLEAN="make KVER=${kernelver} clean"
|
||||||
|
|
||||||
|
BUILT_MODULE_NAME[0]="aic_zlp_quirk"
|
||||||
|
DEST_MODULE_LOCATION[0]="/updates/dkms"
|
||||||
|
|
||||||
|
AUTOINSTALL="yes"
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
# AIC8800DC/DW legacy MCU revision 1 support
|
||||||
|
|
||||||
|
The `legacy-mcu1` branch is the maintained compatibility profile for older
|
||||||
|
AIC8800DC/DW devices tracked in
|
||||||
|
[issue #71](https://github.com/shenmintao/aic8800d80/issues/71). It follows the
|
||||||
|
same method as the successful issue #58 D80 profile: use a complete, matched
|
||||||
|
legacy firmware and loader rather than mixing firmware generations.
|
||||||
|
|
||||||
|
The branch keeps the current USB transport, cfg80211 integration, device IDs,
|
||||||
|
DKMS installer, and modern-kernel compatibility. For AIC8800DC/DW it restores
|
||||||
|
the complete firmware directory and matching loader from immediately before
|
||||||
|
SDK V5 commit `d66e5cb`. That loader includes the MCU1 cache fix and flash DPD
|
||||||
|
validation used by the reporter's previously working driver.
|
||||||
|
|
||||||
|
The first issue #71 test proved that the DPD result stored in flash was valid,
|
||||||
|
but the V5 main application still timed out at `DBG_START_APP_REQ`. Test commit
|
||||||
|
[`dbfbfa0`](https://github.com/shenmintao/aic8800d80/commit/dbfbfa0) restored the
|
||||||
|
complete profile matching the reporter's known-good firmware hashes, after
|
||||||
|
which the reporter confirmed that the TX1U Nano worked.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git fetch origin
|
||||||
|
git switch legacy-mcu1
|
||||||
|
git pull --ff-only
|
||||||
|
sudo ./install.sh
|
||||||
|
sudo poweroff
|
||||||
|
```
|
||||||
|
|
||||||
|
After shutdown, unplug the TX1U Nano or remove host power for at least 10
|
||||||
|
seconds before reconnecting and booting.
|
||||||
|
|
||||||
|
## Verify
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git rev-parse --short HEAD
|
||||||
|
md5sum /lib/firmware/aic8800DC/fmacfw_patch_8800dc_u02.bin
|
||||||
|
md5sum /lib/firmware/aic8800DC/fmacfw_patch_tbl_8800dc_u02.bin
|
||||||
|
lsusb
|
||||||
|
lsusb -t
|
||||||
|
iw dev
|
||||||
|
sudo journalctl -k -b --no-pager | tee issue71-v3-profile.log
|
||||||
|
sudo journalctl -k -b --no-pager | grep -iE 'issue71|chip_id|chip_mcu_id|chip_sub_id|DPD|calib|patch.*tbl|start app|firmware version|interface|wlan|timed-out|err_lmac'
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected firmware values and log markers include:
|
||||||
|
|
||||||
|
```text
|
||||||
|
bfd8ea1d174242e7ec823813b6c5d849 fmacfw_patch_8800dc_u02.bin
|
||||||
|
7b5fde609392c2e6c2c5874838dda718 fmacfw_patch_tbl_8800dc_u02.bin
|
||||||
|
chip_id=7, chip_mcu_id=1, chip_sub_id=1
|
||||||
|
issue71: using complete pre-SDK-V5/V3 DC/DW firmware and loader profile
|
||||||
|
issue71: legacy V3 flash DPD result is valid
|
||||||
|
misc ram valid, skip calib process
|
||||||
|
FMACFW_PATCH_TBL_8800DC_U02_DESCRIBE_BASE = 187c00
|
||||||
|
Start app: 00150000, 5
|
||||||
|
Firmware Version: ...
|
||||||
|
New interface create wlan0
|
||||||
|
```
|
||||||
|
|
||||||
|
There should be no command timeout, `err_lmac_reqs`, or failed USB probe after
|
||||||
|
the main application starts.
|
||||||
|
|
||||||
|
Confirm scanning, association, DHCP, gateway and Internet reachability, real
|
||||||
|
traffic, and clean initialization after a USB unplug/replug cycle.
|
||||||
|
|
||||||
|
## Roll back
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git switch main
|
||||||
|
git pull --ff-only
|
||||||
|
sudo ./install.sh
|
||||||
|
sudo poweroff
|
||||||
|
```
|
||||||
|
|
||||||
|
Cold-power-cycle the adapter again before booting the rollback result.
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# OpenWrt backports build regression
|
||||||
|
|
||||||
|
This checks complete module compilation and MODPOST against real kernel and
|
||||||
|
wireless-stack headers. It requires an already prepared SDK/buildroot with
|
||||||
|
cfg80211/mac80211 headers and `mac80211.symvers` staged. It does not install
|
||||||
|
packages or load modules.
|
||||||
|
|
||||||
|
For the x86_64 SDK used in issue #94:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sdk=/path/to/openwrt-sdk
|
||||||
|
kernel="$sdk/build_dir/target-x86_64_musl/linux-x86_64/linux-6.12.94"
|
||||||
|
export STAGING_DIR="$sdk/staging_dir/target-x86_64_musl"
|
||||||
|
export PATH="$sdk/staging_dir/toolchain-x86_64_gcc-14.3.0_musl/bin:$PATH"
|
||||||
|
|
||||||
|
bash tests/openwrt-backports/build.sh \
|
||||||
|
"$kernel" "$STAGING_DIR/usr/include" \
|
||||||
|
"$kernel/../symvers/mac80211.symvers" 6.18.26 \
|
||||||
|
ARCH=x86_64 CROSS_COMPILE=x86_64-openwrt-linux-musl-
|
||||||
|
```
|
||||||
|
|
||||||
|
The script copies the current driver into a fresh temporary directory and
|
||||||
|
checks that all three `.ko` files are produced. Additional make arguments
|
||||||
|
can select a compiler or architecture. Use matching headers, configuration
|
||||||
|
and symbol versions throughout; changing only the version argument is not
|
||||||
|
a substitute for the matching wireless stack.
|
||||||
|
|
||||||
|
## Verified on 2026-09-17
|
||||||
|
|
||||||
|
- OpenWrt 25.12.5 x86_64 SDK: Linux 6.12.94, GCC 14.3.0, backports 6.18.26
|
||||||
|
with the mac80211 patches from OpenWrt revision `f5dae5ece4` applied:
|
||||||
|
all three modules compile and pass MODPOST with the kernel's `-Werror`.
|
||||||
|
- Original driver revision `9594c5c`, on the same kernel/backports combination:
|
||||||
|
reproduces both RX argument-count errors and the four incompatible
|
||||||
|
`set_monitor_channel`, `set_wiphy_params`, `set_tx_power`, `get_tx_power`
|
||||||
|
callbacks. This comparison uses `-Wno-error=unused-label`, as the issue's
|
||||||
|
log does, to reach those failures. The fixed build needs no such override.
|
||||||
|
- Native kernel headers 6.11.0-17, 6.17.0-14 and 7.2.0-070200, with
|
||||||
|
`CFG80211_VERSION` unset: all three modules compile and pass MODPOST.
|
||||||
|
The 7.2 check uses GCC 14 and reports compiler/attribute warnings because
|
||||||
|
those headers were built with GCC 15.
|
||||||
|
|
||||||
|
These are build checks. They do not validate an installable OpenWrt package,
|
||||||
|
firmware loading, Wi-Fi connectivity or Bluetooth operation on hardware.
|
||||||
Executable
+41
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Compile a source copy against a prepared kernel and staged wireless backport.
|
||||||
|
# Leaves the build directory for inspection; does not install or load modules.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ "$#" -lt 4 ]; then
|
||||||
|
echo "Usage: $0 KERNEL_BUILD_DIR STAGED_INCLUDE_DIR MAC80211_SYMVERS CFG80211_VERSION [make arguments...]" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
kernel_dir=$(realpath "$1")
|
||||||
|
include_dir=$(realpath "$2")
|
||||||
|
symvers=$(realpath "$3")
|
||||||
|
wireless_version=$4
|
||||||
|
shift 4
|
||||||
|
|
||||||
|
for required in "$kernel_dir/Makefile" "$kernel_dir/Module.symvers" \
|
||||||
|
"$include_dir/mac80211/net/cfg80211.h" \
|
||||||
|
"$include_dir/mac80211-backport/backport/autoconf.h" "$symvers"; do
|
||||||
|
if [ ! -f "$required" ]; then
|
||||||
|
echo "Missing build input: $required" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
repo_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
|
||||||
|
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/aic8800-backports.XXXXXX")
|
||||||
|
cp -a "$repo_dir/drivers/aic8800/." "$build_dir/"
|
||||||
|
echo "Build directory: $build_dir"
|
||||||
|
|
||||||
|
make -C "$kernel_dir" M="$build_dir" \
|
||||||
|
NOSTDINC_FLAGS="-I$include_dir/mac80211-backport/uapi -I$include_dir/mac80211-backport -I$include_dir/mac80211/uapi -I$include_dir/mac80211 -include backport/backport.h" \
|
||||||
|
KBUILD_EXTRA_SYMBOLS="$symvers" \
|
||||||
|
CFG80211_VERSION="$wireless_version" \
|
||||||
|
-j"${JOBS:-2}" "$@" modules
|
||||||
|
|
||||||
|
for module in aic_load_fw/aic_load_fw.ko aic8800_fdrv/aic8800_fdrv.ko \
|
||||||
|
aic_zlp_quirk/aic_zlp_quirk.ko; do
|
||||||
|
test -s "$build_dir/$module"
|
||||||
|
done
|
||||||
|
echo "All three modules built successfully in $build_dir"
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
# Unified Wi-Fi, Bluetooth, and ZLP branch test
|
||||||
|
|
||||||
|
This branch tests replacing the separate `main` and `bluetooth` branches with
|
||||||
|
one driver and installer. The Wi-Fi driver and firmware were already identical
|
||||||
|
on both branches. This test unifies their installer, migration, diagnostics,
|
||||||
|
packaging, and documentation, and adds the device-scoped ZLP fix from issue
|
||||||
|
#63 as a third DKMS module.
|
||||||
|
|
||||||
|
The expected architecture is:
|
||||||
|
|
||||||
|
- `aic_load_fw` initializes every supported adapter and uploads firmware.
|
||||||
|
- `aic8800_fdrv` handles Wi-Fi.
|
||||||
|
- A combo adapter exposes a Bluetooth HCI USB interface after initialization;
|
||||||
|
the standard Linux `btusb` driver binds through normal USB device matching.
|
||||||
|
- A Wi-Fi-only adapter exposes no HCI interface and does not need `btusb`.
|
||||||
|
- The retired custom `aic_btusb` module is never installed or used.
|
||||||
|
- USB device `368b:8d81` autoloads `aic_zlp_quirk`, which adds
|
||||||
|
`URB_ZERO_PACKET` only to its Bluetooth ACL bulk OUT transfers.
|
||||||
|
- The distribution's original `btusb.ko` is never replaced.
|
||||||
|
|
||||||
|
The installer deliberately does not force-load `btusb` and does not globally
|
||||||
|
unblock Bluetooth through rfkill.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git fetch origin
|
||||||
|
git switch test/unified-wifi-bt-zlp
|
||||||
|
git pull --ff-only
|
||||||
|
sudo ./install.sh
|
||||||
|
sudo reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test a Wi-Fi-only adapter
|
||||||
|
|
||||||
|
Confirm that:
|
||||||
|
|
||||||
|
1. The Wi-Fi interface is created.
|
||||||
|
2. Scanning, association, DHCP, and real traffic work.
|
||||||
|
3. No `aic_btusb` module is loaded.
|
||||||
|
4. The absence of `btusb` or an HCI controller is treated as normal.
|
||||||
|
|
||||||
|
## Test a Wi-Fi/Bluetooth combo adapter
|
||||||
|
|
||||||
|
Confirm that:
|
||||||
|
|
||||||
|
1. Wi-Fi scanning, association, DHCP, and real traffic work.
|
||||||
|
2. `aic_load_fw` uploads the firmware before the HCI interface is used.
|
||||||
|
3. The Bluetooth USB interface is bound to the standard `btusb` driver.
|
||||||
|
4. `bluetoothctl` can power on, scan, pair, and exchange real traffic.
|
||||||
|
5. No `aic_btusb` module, alias, soft dependency, or udev binding rule remains.
|
||||||
|
|
||||||
|
## Test the `368b:8d81` ZLP path
|
||||||
|
|
||||||
|
In addition to the combo-adapter checks, confirm that:
|
||||||
|
|
||||||
|
1. `aic_zlp_quirk` loads automatically and system `btusb` owns interfaces 0/1.
|
||||||
|
2. `hook` reports `btusb:alloc_bulk_urb` or `usb_submit_urb`.
|
||||||
|
3. The `injections` counter increases during Bluetooth audio traffic.
|
||||||
|
4. AAC playback remains connected for at least one hour.
|
||||||
|
5. Wi-Fi scan, association, and traffic remain unaffected during the test.
|
||||||
|
|
||||||
|
## Collect results
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git rev-parse --short HEAD
|
||||||
|
lsusb
|
||||||
|
lsusb -t
|
||||||
|
lsmod | grep -E 'aic|btusb|bluetooth'
|
||||||
|
iw dev
|
||||||
|
bluetoothctl list
|
||||||
|
cat /sys/module/aic_zlp_quirk/parameters/{hook,injections} 2>/dev/null || true
|
||||||
|
sudo ./diagnose_bt.sh | tee unified-wifi-bt-diagnostic.log
|
||||||
|
sudo journalctl -k -b --no-pager | tee unified-wifi-bt-kernel.log
|
||||||
|
```
|
||||||
|
|
||||||
|
Please attach both logs and identify whether the tested adapter is Wi-Fi-only
|
||||||
|
or a combo device.
|
||||||
|
|
||||||
|
## Roll back during testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git switch main
|
||||||
|
git pull --ff-only
|
||||||
|
sudo ./install.sh
|
||||||
|
sudo reboot
|
||||||
|
```
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
# Sends vendor-specific SCSI CDB to trigger mode switch from
|
# Sends vendor-specific SCSI CDB to trigger mode switch from
|
||||||
# USB Mass Storage to WiFi+BT mode.
|
# USB Mass Storage to WiFi+BT mode.
|
||||||
#
|
#
|
||||||
# The 16-byte CDB is: FD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F2
|
# The two 16-byte CDBs end in F3 and F2 respectively. Each is wrapped in a
|
||||||
# Wrapped in a standard 31-byte SCSI CBW (Command Block Wrapper).
|
# standard 31-byte SCSI CBW (Command Block Wrapper), and must be sent in order.
|
||||||
#
|
#
|
||||||
# Install as: /etc/usb_modeswitch.d/1111:1111
|
# Install as: /etc/usb_modeswitch.d/1111:1111
|
||||||
# (The filename must contain a colon on Linux; this file is named
|
# (The filename must contain a colon on Linux; this file is named
|
||||||
@@ -13,4 +13,6 @@ DefaultVendor=0x1111
|
|||||||
DefaultProduct=0x1111
|
DefaultProduct=0x1111
|
||||||
TargetVendor=0xa69c
|
TargetVendor=0xa69c
|
||||||
TargetProduct=0x8d80
|
TargetProduct=0x8d80
|
||||||
MessageContent="555342438765432100000000000010fd0000000000000000000000000000f2"
|
MessageContent="555342438765432100000000000010fd0000000000000000000000000000f3"
|
||||||
|
MessageContent2="555342438765432100000000000010fd0000000000000000000000000000f2"
|
||||||
|
NeedResponse=1
|
||||||
|
|||||||
Reference in New Issue
Block a user