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 |
@@ -0,0 +1,11 @@
|
|||||||
|
fw/aic8800D80/*.txt 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
|
||||||
+8
-1
@@ -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`)
|
||||||
|
|||||||
+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.
|
||||||
|
|
||||||
> **Bluetooth Support**: The [`bluetooth`](https://github.com/shenmintao/aic8800d80/tree/bluetooth) branch fully supports Bluetooth. This main branch only provides Wi-Fi functionality. Please switch to the `bluetooth` branch if you need Bluetooth support.
|
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,3 +156,52 @@ If the device is still not active, check the kernel logs for any errors related
|
|||||||
sudo dmesg
|
sudo dmesg
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Bluetooth on Combo Adapters
|
||||||
|
|
||||||
|
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 the expected modules and controller with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lsmod | grep -E 'aic_load_fw|aic8800_fdrv|aic_zlp_quirk|btusb'
|
||||||
|
lsusb -t
|
||||||
|
bluetoothctl list
|
||||||
|
```
|
||||||
|
|
||||||
|
To scan after a controller appears:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bluetoothctl
|
||||||
|
power on
|
||||||
|
scan on
|
||||||
|
```
|
||||||
|
|
||||||
|
If Bluetooth is missing or reports HCI timeouts, run the read-only diagnostic
|
||||||
|
script and attach its output together with the current boot log:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod +x diagnose_bt.sh
|
||||||
|
sudo ./diagnose_bt.sh
|
||||||
|
sudo journalctl -k -b --no-pager
|
||||||
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
For `368b:8d81`, verify the ZLP hook and its injection counter while Bluetooth
|
||||||
|
traffic is active:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat /sys/module/aic_zlp_quirk/parameters/hook
|
||||||
|
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.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
# 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"
|
||||||
@@ -6,3 +8,7 @@ KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5726", SYMLINK+="ten
|
|||||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5727", SYMLINK+="tendaudiskv4", RUN+="/usr/bin/eject /dev/%k"
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5727", SYMLINK+="tendaudiskv4", RUN+="/usr/bin/eject /dev/%k"
|
||||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572a", SYMLINK+="tendaudiskv5", RUN+="/usr/bin/eject /dev/%k"
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572a", SYMLINK+="tendaudiskv5", 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}=="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"
|
||||||
|
|
||||||
|
# AIC8800D80 "Pandora" clone: switch 1111:1111 to its operational USB ID.
|
||||||
|
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'"
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# Intro
|
||||||
|
|
||||||
|
Hello.
|
||||||
|
|
||||||
|
Some instructions how to build rpm file and then install rpm file on Bazzite.
|
||||||
|
|
||||||
|
I saw video on Youtube about Asrock AMD BC-250, then I bought this motherboard.
|
||||||
|
|
||||||
|
On printables I found a case and recomendations about WIFI BT stick.
|
||||||
|
|
||||||
|
There is only one problem - Bazzite has read-only filesystem.
|
||||||
|
|
||||||
|
# How to build from spec file.
|
||||||
|
|
||||||
|
|
||||||
|
Install the build tools, the development package for the running kernel, and
|
||||||
|
the runtime mode-switch tools. Reboot once so the layered packages are active.
|
||||||
|
|
||||||
|
~~~bash
|
||||||
|
sudo rpm-ostree install rpm-build rpmdevtools gcc make "kernel-devel-$(uname -r)" usb_modeswitch util-linux
|
||||||
|
sudo systemctl reboot
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Prepare rpmbuild folder
|
||||||
|
|
||||||
|
~~~bash
|
||||||
|
cd $HOME
|
||||||
|
rpmdev-setuptree
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Copy aic8800d80.spec to rpmbuild/SPECS
|
||||||
|
|
||||||
|
~~~bash
|
||||||
|
cd $HOME/rpmbuild/SPECS
|
||||||
|
curl -LO -s https://raw.githubusercontent.com/shenmintao/aic8800d80/refs/heads/main/bazzite/aic8800d80.spec
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Prepare and download required files.
|
||||||
|
|
||||||
|
~~~bash
|
||||||
|
spectool -g -R $HOME/rpmbuild/SPECS/aic8800d80.spec
|
||||||
|
rpmbuild -bs $HOME/rpmbuild/SPECS/aic8800d80.spec
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Build SRPM package
|
||||||
|
|
||||||
|
~~~bash
|
||||||
|
rpmbuild --define "kver $(uname -r)" -bb $HOME/rpmbuild/SPECS/aic8800d80.spec
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Install RPM package
|
||||||
|
|
||||||
|
~~~bash
|
||||||
|
rpm_path=$(find "$HOME/rpmbuild/RPMS/$(uname -m)" -maxdepth 1 -name 'aic8800d80-*.rpm' -printf '%T@ %p\n' | sort -nr | head -1 | cut -d' ' -f2-)
|
||||||
|
sudo rpm-ostree install "$rpm_path"
|
||||||
|
sudo systemctl reboot
|
||||||
|
~~~
|
||||||
|
|
||||||
|
After reboot, the Wi-Fi module and firmware loader will be available. On combo
|
||||||
|
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
|
||||||
|
it after a Bazzite kernel upgrade.
|
||||||
|
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
%global commit c8327eab5be246d4b517afdba034775f00afa988
|
||||||
|
%global shortcommit %(echo %{commit} | cut -c1-7)
|
||||||
|
%global snapdate 20260924
|
||||||
|
%global debug_package %{nil}
|
||||||
|
%{!?kver:%global kver %(uname -r)}
|
||||||
|
|
||||||
|
Name: aic8800d80
|
||||||
|
# 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}
|
||||||
|
Summary: AIC8800 USB Wi-Fi, Bluetooth firmware, and ZLP quirk driver
|
||||||
|
|
||||||
|
License: GPL-2.0-only
|
||||||
|
URL: https://github.com/shenmintao/aic8800d80
|
||||||
|
Source0: %{url}/archive/%{commit}/%{name}-%{commit}.tar.gz
|
||||||
|
|
||||||
|
BuildRequires: gcc
|
||||||
|
BuildRequires: make
|
||||||
|
BuildRequires: kernel-devel-uname-r = %{kver}
|
||||||
|
|
||||||
|
Requires: kernel-uname-r = %{kver}
|
||||||
|
Requires: /usr/bin/eject
|
||||||
|
Requires: usb_modeswitch
|
||||||
|
Requires(post): /usr/sbin/depmod
|
||||||
|
Requires(postun): /usr/sbin/depmod
|
||||||
|
|
||||||
|
%description
|
||||||
|
Out-of-tree AIC8800 USB driver with Wi-Fi support, Bluetooth firmware loading,
|
||||||
|
udev mode-switch rules, and all firmware variants shipped by the upstream
|
||||||
|
repository. Combo adapters use the standard Linux btusb transport driver. A
|
||||||
|
device-scoped companion module supplies the required ACL bulk TX ZLP behavior
|
||||||
|
for USB device 368b:8d81 without replacing the distribution btusb module.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%autosetup -n %{name}-%{commit}
|
||||||
|
|
||||||
|
%build
|
||||||
|
make -C drivers/aic8800 KVER=%{kver} KDIR=/usr/src/kernels/%{kver} clean
|
||||||
|
make -C drivers/aic8800 KVER=%{kver} KDIR=/usr/src/kernels/%{kver}
|
||||||
|
|
||||||
|
%install
|
||||||
|
rm -rf %{buildroot}
|
||||||
|
|
||||||
|
install -Dpm0644 \
|
||||||
|
drivers/aic8800/aic8800_fdrv/aic8800_fdrv.ko \
|
||||||
|
%{buildroot}/usr/lib/modules/%{kver}/kernel/drivers/net/wireless/aic8800/aic8800_fdrv.ko
|
||||||
|
|
||||||
|
install -Dpm0644 \
|
||||||
|
drivers/aic8800/aic_load_fw/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 \
|
||||||
|
aic.rules \
|
||||||
|
%{buildroot}/usr/lib/udev/rules.d/90-aic8800-mode-switch.rules
|
||||||
|
|
||||||
|
install -Dpm0644 \
|
||||||
|
usb_modeswitch/1111_1111 \
|
||||||
|
%{buildroot}/etc/usb_modeswitch.d/1111:1111
|
||||||
|
|
||||||
|
install -d -m 0755 %{buildroot}/usr/lib/firmware
|
||||||
|
cp -a fw/aic8800* %{buildroot}/usr/lib/firmware/
|
||||||
|
|
||||||
|
%post
|
||||||
|
/usr/sbin/depmod -a %{kver} || :
|
||||||
|
|
||||||
|
%postun
|
||||||
|
/usr/sbin/depmod -a %{kver} || :
|
||||||
|
|
||||||
|
%files
|
||||||
|
%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/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
|
||||||
|
%config(noreplace) /etc/usb_modeswitch.d/1111:1111
|
||||||
|
/usr/lib/firmware/aic8800*
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
* Thu Sep 24 2026 Shen Mintao <shenmintao@gmail.com> - 1:1.0.0^20260924gitc8327ea-1
|
||||||
|
- 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.
|
||||||
|
- Remove obsolete Bluetooth-specific configuration from the Wi-Fi package.
|
||||||
+160
@@ -0,0 +1,160 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Diagnose Bluetooth on AIC8800 Wi-Fi/Bluetooth combo adapters.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
echo "=== AIC8800 Bluetooth diagnostics ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "1. AIC USB devices:"
|
||||||
|
if command -v lsusb >/dev/null 2>&1; then
|
||||||
|
lsusb | grep -iE 'a69c|368b|3625' || echo " No known AIC USB ID found"
|
||||||
|
else
|
||||||
|
echo " lsusb is not installed"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "2. USB interfaces and bound drivers:"
|
||||||
|
bt_interface_found=false
|
||||||
|
btusb_bound=false
|
||||||
|
zlp_target_found=false
|
||||||
|
for dev in /sys/bus/usb/devices/*; do
|
||||||
|
[ -f "$dev/idVendor" ] || continue
|
||||||
|
[ -f "$dev/idProduct" ] || continue
|
||||||
|
|
||||||
|
vid=$(cat "$dev/idVendor" 2>/dev/null)
|
||||||
|
pid=$(cat "$dev/idProduct" 2>/dev/null)
|
||||||
|
case "$vid" in
|
||||||
|
a69c|368b|3625) ;;
|
||||||
|
*) continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo " Device: $vid:$pid"
|
||||||
|
if [ "$vid" = "368b" ] && [ "$pid" = "8d81" ]; then
|
||||||
|
zlp_target_found=true
|
||||||
|
fi
|
||||||
|
for intf in "$dev"/*:*; do
|
||||||
|
[ -d "$intf" ] || continue
|
||||||
|
class=$(cat "$intf/bInterfaceClass" 2>/dev/null)
|
||||||
|
subclass=$(cat "$intf/bInterfaceSubClass" 2>/dev/null)
|
||||||
|
protocol=$(cat "$intf/bInterfaceProtocol" 2>/dev/null)
|
||||||
|
driver=$(basename "$(readlink "$intf/driver" 2>/dev/null)" 2>/dev/null)
|
||||||
|
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
|
||||||
|
done
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "3. Relevant kernel modules (combo expectation: aic_load_fw + btusb):"
|
||||||
|
lsmod | grep -E '^(aic_load_fw|aic8800_fdrv|aic_zlp_quirk|aic_btusb|btusb|bluetooth)[[:space:]]' || \
|
||||||
|
echo " No related module is currently loaded"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "4. Bluetooth controllers:"
|
||||||
|
if command -v bluetoothctl >/dev/null 2>&1; then
|
||||||
|
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. Firmware, btusb, ZLP quirk, and HCI log messages:"
|
||||||
|
dmesg 2>/dev/null | grep -iE 'fw_patch|fw_adid|aicbt|aic_zlp_quirk|bluetooth|btusb|hci' | tail -80 || true
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "6. Bluetooth rfkill state:"
|
||||||
|
if command -v rfkill >/dev/null 2>&1; then
|
||||||
|
rfkill list bluetooth 2>/dev/null || echo " No Bluetooth rfkill entry"
|
||||||
|
else
|
||||||
|
echo " rfkill is not installed"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "7. Obsolete aic_btusb installation/configuration:"
|
||||||
|
legacy_refs_found=false
|
||||||
|
mapfile -t legacy_modprobe_files < <(
|
||||||
|
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 2>/dev/null | \
|
||||||
|
grep -vE '\.aic8800-backup$' || true
|
||||||
|
)
|
||||||
|
mapfile -t legacy_udev_files < <(
|
||||||
|
grep -RIl 'aic_btusb/new_id' \
|
||||||
|
/etc/udev/rules.d /run/udev/rules.d \
|
||||||
|
/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
|
||||||
|
echo " Obsolete modprobe directive: $legacy_file"
|
||||||
|
legacy_refs_found=true
|
||||||
|
done
|
||||||
|
for legacy_file in "${legacy_udev_files[@]}"; do
|
||||||
|
echo " Obsolete udev binding rule: $legacy_file"
|
||||||
|
legacy_refs_found=true
|
||||||
|
done
|
||||||
|
if lsmod | awk '{print $1}' | grep -qx 'aic_btusb'; then
|
||||||
|
echo " Obsolete aic_btusb module is loaded"
|
||||||
|
legacy_refs_found=true
|
||||||
|
fi
|
||||||
|
if modinfo -n aic_btusb >/dev/null 2>&1; then
|
||||||
|
echo " Obsolete module file: $(modinfo -n aic_btusb 2>/dev/null)"
|
||||||
|
legacy_refs_found=true
|
||||||
|
fi
|
||||||
|
if [ "$legacy_refs_found" = false ]; then
|
||||||
|
echo " No active aic_btusb module, directive, or binding rule found (expected)"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "8. Device-scoped Bluetooth ACL ZLP quirk:"
|
||||||
|
if [ "$zlp_target_found" = true ]; then
|
||||||
|
if [ -d /sys/module/aic_zlp_quirk ]; then
|
||||||
|
zlp_hook="unknown"
|
||||||
|
zlp_injections="unavailable"
|
||||||
|
[ -r /sys/module/aic_zlp_quirk/parameters/hook ] && \
|
||||||
|
zlp_hook=$(cat /sys/module/aic_zlp_quirk/parameters/hook)
|
||||||
|
[ -r /sys/module/aic_zlp_quirk/parameters/injections ] && \
|
||||||
|
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
|
||||||
|
else
|
||||||
|
echo " Target 368b:8d81 not present; quirk is not required"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "=== Assessment ==="
|
||||||
|
if ! lsmod | awk '{print $1}' | grep -qx 'aic_load_fw'; then
|
||||||
|
echo "- aic_load_fw is not loaded; run: sudo modprobe aic8800_fdrv"
|
||||||
|
fi
|
||||||
|
if [ "$bt_interface_found" = true ] && [ "$btusb_bound" = false ]; then
|
||||||
|
echo "- A Bluetooth USB interface exists but is not bound to btusb."
|
||||||
|
echo " Check for a btusb blacklist, then try: sudo modprobe btusb"
|
||||||
|
fi
|
||||||
|
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 "- 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
|
||||||
|
|
||||||
|
echo "=== Diagnostics complete ==="
|
||||||
+79
-19
@@ -17,6 +17,29 @@ YELLOW='\033[1;33m'
|
|||||||
BLUE='\033[0;34m'
|
BLUE='\033[0;34m'
|
||||||
NC='\033[0m'
|
NC='\033[0m'
|
||||||
|
|
||||||
|
DRV_NAME="aic8800"
|
||||||
|
DRV_VERSION="1.0.0"
|
||||||
|
INSTALL_LOG="/tmp/aic8800d80_install.log"
|
||||||
|
|
||||||
|
read_dkms_conf_value() {
|
||||||
|
local key="$1"
|
||||||
|
local file="$2"
|
||||||
|
|
||||||
|
grep -E "^[[:space:]]*${key}[[:space:]]*=" "$file" 2>/dev/null \
|
||||||
|
| head -1 \
|
||||||
|
| cut -d= -f2- \
|
||||||
|
| tr -d "\"'[:space:]"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -f "./dkms.conf" ]; then
|
||||||
|
detected_name="$(read_dkms_conf_value PACKAGE_NAME ./dkms.conf)"
|
||||||
|
detected_version="$(read_dkms_conf_value PACKAGE_VERSION ./dkms.conf)"
|
||||||
|
[ -n "$detected_name" ] && DRV_NAME="$detected_name"
|
||||||
|
[ -n "$detected_version" ] && DRV_VERSION="$detected_version"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mapfile -t DKMS_SOURCE_DIRS < <(find /usr/src -maxdepth 1 -type d -name "${DRV_NAME}-*" -print 2>/dev/null | sort)
|
||||||
|
|
||||||
print_section() {
|
print_section() {
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${BLUE}━━━ $1 ━━━${NC}"
|
echo -e "${BLUE}━━━ $1 ━━━${NC}"
|
||||||
@@ -58,46 +81,73 @@ fi
|
|||||||
|
|
||||||
print_section "2. Checking DKMS directory"
|
print_section "2. Checking DKMS directory"
|
||||||
|
|
||||||
if [ -d "/usr/src/aic8800-1.0.0" ]; then
|
echo "Detected package: ${DRV_NAME}/${DRV_VERSION}"
|
||||||
echo -e "${GREEN}✓${NC} /usr/src/aic8800-1.0.0 directory exists"
|
if [ "${#DKMS_SOURCE_DIRS[@]}" -gt 0 ]; then
|
||||||
|
for source_dir in "${DKMS_SOURCE_DIRS[@]}"; do
|
||||||
|
echo -e "${GREEN}✓${NC} $source_dir directory exists"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Content:"
|
echo "Content:"
|
||||||
ls -la /usr/src/aic8800-1.0.0/
|
ls -la "$source_dir/"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
echo "Checking drivers/aic8800 inside DKMS:"
|
echo "Checking drivers/aic8800 inside DKMS:"
|
||||||
if [ -d "/usr/src/aic8800-1.0.0/drivers/aic8800" ]; then
|
if [ -d "$source_dir/drivers/aic8800" ]; then
|
||||||
echo -e "${GREEN}✓${NC} drivers/aic8800 copied to DKMS"
|
echo -e "${GREEN}✓${NC} drivers/aic8800 copied to DKMS"
|
||||||
ls -la /usr/src/aic8800-1.0.0/drivers/aic8800/
|
ls -la "$source_dir/drivers/aic8800/"
|
||||||
else
|
else
|
||||||
echo -e "${RED}✗${NC} drivers/aic8800 NOT copied correctly!"
|
echo -e "${RED}✗${NC} drivers/aic8800 NOT copied correctly!"
|
||||||
fi
|
fi
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
else
|
else
|
||||||
echo -e "${RED}✗${NC} /usr/src/aic8800-1.0.0 directory NOT FOUND"
|
echo -e "${RED}✗${NC} No /usr/src/${DRV_NAME}-* directory found"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
print_section "3. Checking DKMS build logs"
|
print_section "3. Checking DKMS build logs"
|
||||||
|
|
||||||
if [ -f "/var/lib/dkms/aic8800/1.0.0/build/make.log" ]; then
|
mapfile -t BUILD_LOGS < <(find "/var/lib/dkms/${DRV_NAME}" -type f -name make.log -print 2>/dev/null | sort)
|
||||||
echo -e "${GREEN}✓${NC} Build log found"
|
|
||||||
|
if [ "${#BUILD_LOGS[@]}" -gt 0 ]; then
|
||||||
|
for build_log in "${BUILD_LOGS[@]}"; do
|
||||||
|
echo -e "${GREEN}✓${NC} Build log found: $build_log"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Last 50 lines of make.log:"
|
echo "Last 50 lines of make.log:"
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
tail -50 /var/lib/dkms/aic8800/1.0.0/build/make.log
|
tail -50 "$build_log"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} No make.log found under /var/lib/dkms/${DRV_NAME}/"
|
||||||
|
echo "The module may not have reached the build step yet, or this DKMS version stores logs elsewhere."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$INSTALL_LOG" ]; then
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}✓${NC} Installer log found: $INSTALL_LOG"
|
||||||
|
echo "Last 50 lines of installer log:"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
tail -50 "$INSTALL_LOG"
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
else
|
else
|
||||||
echo -e "${RED}✗${NC} Build log not found in /var/lib/dkms/aic8800/1.0.0/build/make.log"
|
echo -e "${YELLOW}!${NC} Installer log not found: $INSTALL_LOG"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
print_section "4. Checking dkms.conf"
|
print_section "4. Checking dkms.conf"
|
||||||
|
|
||||||
if [ -f "/usr/src/aic8800-1.0.0/dkms.conf" ]; then
|
if [ "${#DKMS_SOURCE_DIRS[@]}" -gt 0 ]; then
|
||||||
echo -e "${GREEN}✓${NC} dkms.conf found"
|
for source_dir in "${DKMS_SOURCE_DIRS[@]}"; do
|
||||||
|
if [ -f "$source_dir/dkms.conf" ]; then
|
||||||
|
echo -e "${GREEN}✓${NC} dkms.conf found: $source_dir/dkms.conf"
|
||||||
echo ""
|
echo ""
|
||||||
echo "dkms.conf content:"
|
cat "$source_dir/dkms.conf"
|
||||||
cat /usr/src/aic8800-1.0.0/dkms.conf
|
echo ""
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} dkms.conf NOT FOUND in $source_dir"
|
||||||
|
fi
|
||||||
|
done
|
||||||
else
|
else
|
||||||
echo -e "${RED}✗${NC} dkms.conf NOT FOUND!"
|
echo -e "${RED}✗${NC} No DKMS source directory available to inspect"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "./dkms.conf" ]; then
|
if [ -f "./dkms.conf" ]; then
|
||||||
@@ -120,13 +170,23 @@ print_section "6. System information"
|
|||||||
echo "Kernel: $(uname -r)"
|
echo "Kernel: $(uname -r)"
|
||||||
echo "Architecture: $(uname -m)"
|
echo "Architecture: $(uname -m)"
|
||||||
echo ""
|
echo ""
|
||||||
echo "GCC version:"
|
echo "Compiler version:"
|
||||||
gcc --version | head -1
|
if command -v gcc >/dev/null 2>&1; then
|
||||||
|
gcc --version | head -1
|
||||||
|
elif command -v clang >/dev/null 2>&1; then
|
||||||
|
clang --version | head -1
|
||||||
|
else
|
||||||
|
echo "No gcc or clang found"
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
echo "Installed kernel headers:"
|
echo "Installed kernel headers:"
|
||||||
ls -d /lib/modules/$(uname -r)/build 2>/dev/null && echo "✓ Headers found" || echo "✗ Headers NOT found"
|
ls -d "/lib/modules/$(uname -r)/build" 2>/dev/null && echo "✓ Headers found" || echo "✗ Headers NOT found"
|
||||||
|
|
||||||
print_section "7. DKMS status"
|
print_section "7. DKMS status"
|
||||||
|
|
||||||
echo "DKMS modules registered:"
|
echo "DKMS modules registered:"
|
||||||
dkms status
|
if command -v dkms >/dev/null 2>&1; then
|
||||||
|
dkms status
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} dkms command not found"
|
||||||
|
fi
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
PACKAGE_NAME="aic8800"
|
PACKAGE_NAME="aic8800"
|
||||||
PACKAGE_VERSION="1.0.0"
|
PACKAGE_VERSION="1.0.0"
|
||||||
MAKE="KVER=${kernelver} 'make' -C drivers/aic8800"
|
MAKE="KVER=${kernelver} KDIR=/lib/modules/${kernelver}/build 'make' -C drivers/aic8800"
|
||||||
CLEAN="KVER=${kernelver} 'make' -C drivers/aic8800 clean"
|
CLEAN="KVER=${kernelver} KDIR=/lib/modules/${kernelver}/build 'make' -C drivers/aic8800 clean"
|
||||||
|
|
||||||
# Main module (aic8800_fdrv)
|
# Main module (aic8800_fdrv)
|
||||||
BUILT_MODULE_NAME[0]="aic8800_fdrv"
|
BUILT_MODULE_NAME[0]="aic8800_fdrv"
|
||||||
@@ -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,13 +1,16 @@
|
|||||||
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
|
||||||
export CONFIG_PREALLOC_RX_SKB = y
|
export CONFIG_PREALLOC_RX_SKB = y
|
||||||
export CONFIG_PREALLOC_TXQ = y
|
export CONFIG_PREALLOC_TXQ = y
|
||||||
|
export CONFIG_WOWLAN = n
|
||||||
###################################
|
###################################
|
||||||
|
|
||||||
########## platform support list ##########
|
########## platform support list ##########
|
||||||
@@ -47,34 +50,49 @@ endif
|
|||||||
|
|
||||||
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
||||||
KVER ?= $(shell uname -r)
|
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
|
||||||
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/)
|
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/)
|
||||||
ARCH ?= $(SUBARCH)
|
ARCH ?= $(SUBARCH)
|
||||||
CROSS_COMPILE ?=
|
CROSS_COMPILE ?=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
|
|
||||||
MAKEFLAGS +=-j$(shell nproc)
|
KERNEL_AUTOCONF := $(KDIR)/include/config/auto.conf
|
||||||
|
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)
|
||||||
|
|
||||||
|
ifeq ($(KERNEL_CC_IS_CLANG),y)
|
||||||
|
LLVM ?= 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(LLVM),)
|
||||||
|
KBUILD_EXTRA_ARGS += LLVM=$(LLVM)
|
||||||
|
endif
|
||||||
|
|
||||||
all: modules
|
all: modules
|
||||||
modules:
|
modules:
|
||||||
make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
|
make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) $(KBUILD_EXTRA_ARGS) 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
|
||||||
@@ -82,18 +96,22 @@ CONFIG_BR_SUPPORT = n
|
|||||||
CONFIG_USB_MSG_OUT_EP = y
|
CONFIG_USB_MSG_OUT_EP = y
|
||||||
CONFIG_USB_MSG_IN_EP = y
|
CONFIG_USB_MSG_IN_EP = y
|
||||||
CONFIG_USB_RX_REASSEMBLE = n
|
CONFIG_USB_RX_REASSEMBLE = n
|
||||||
CONFIG_WOWLAN = n
|
CONFIG_WOWLAN ?= n
|
||||||
|
|
||||||
#DCDW support tx aggr, D80 support both
|
#DCDW support tx aggr, D80 support both
|
||||||
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
|
||||||
CONFIG_USE_USB_ZERO_PACKET = y
|
CONFIG_USE_USB_ZERO_PACKET = y
|
||||||
CONFIG_DEBUG_FS = n
|
CONFIG_DEBUG_FS ?= n
|
||||||
CONFIG_STA_SCAN_WHEN_P2P_WORKING = y
|
CONFIG_STA_SCAN_WHEN_P2P_WORKING = y
|
||||||
CONFIG_SET_VENDOR_EXTENSION_IE = n
|
CONFIG_SET_VENDOR_EXTENSION_IE = n
|
||||||
CONFIG_VENDOR_GPIO = n
|
CONFIG_VENDOR_GPIO = n
|
||||||
@@ -114,6 +132,7 @@ CONFIG_LOFT_CALIB = n
|
|||||||
CONFIG_GKI = n
|
CONFIG_GKI = n
|
||||||
CONFIG_SCHED_SCAN = n
|
CONFIG_SCHED_SCAN = n
|
||||||
CONFIG_TEMP_COMP = n
|
CONFIG_TEMP_COMP = n
|
||||||
|
CONFIG_TEMP_CONTROL = n
|
||||||
CONFIG_POWER_LIMIT = n
|
CONFIG_POWER_LIMIT = n
|
||||||
CONFIG_EXT_FEM_8800DCDW = n
|
CONFIG_EXT_FEM_8800DCDW = n
|
||||||
# CONFIG_MCC = n for sta and p2p concurrent in same channel.
|
# CONFIG_MCC = n for sta and p2p concurrent in same channel.
|
||||||
@@ -122,6 +141,8 @@ CONFIG_LOAD_BT_PATCH_IN_FDRV = n
|
|||||||
CONFIG_DYNAMIC_PWR = n
|
CONFIG_DYNAMIC_PWR = n
|
||||||
CONFIG_DYNAMIC_PERPWR = n
|
CONFIG_DYNAMIC_PERPWR = n
|
||||||
CONFIG_BAND_STEERING = n
|
CONFIG_BAND_STEERING = n
|
||||||
|
CONFIG_PRBREQ_REPORT = n
|
||||||
|
CONFIG_SUPPORT_4ADDR = n
|
||||||
|
|
||||||
#support D80X2 can write rf result to file
|
#support D80X2 can write rf result to file
|
||||||
CONFIG_WRITE_FILE_D80X2 = n
|
CONFIG_WRITE_FILE_D80X2 = n
|
||||||
@@ -151,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
|
||||||
@@ -189,7 +210,9 @@ $(MODULE_NAME)-y := \
|
|||||||
aic_priv_cmd.o \
|
aic_priv_cmd.o \
|
||||||
aicwf_compat_8800dc.o \
|
aicwf_compat_8800dc.o \
|
||||||
aicwf_compat_8800d80.o \
|
aicwf_compat_8800d80.o \
|
||||||
aicwf_compat_8800d80x2.o
|
aicwf_compat_8800d80x2.o \
|
||||||
|
aicwf_compat_8800d80n.o \
|
||||||
|
aicwf_compat_8800dln.o
|
||||||
|
|
||||||
$(MODULE_NAME)-$(CONFIG_BAND_STEERING) += aicwf_manager.o \
|
$(MODULE_NAME)-$(CONFIG_BAND_STEERING) += aicwf_manager.o \
|
||||||
aicwf_steering.o
|
aicwf_steering.o
|
||||||
@@ -263,6 +286,8 @@ ccflags-$(CONFIG_LOAD_BT_PATCH_IN_FDRV) += -DCONFIG_LOAD_BT_PATCH_IN_FDRV
|
|||||||
ccflags-$(CONFIG_DYNAMIC_PWR) += -DCONFIG_DYNAMIC_PWR
|
ccflags-$(CONFIG_DYNAMIC_PWR) += -DCONFIG_DYNAMIC_PWR
|
||||||
ccflags-$(CONFIG_DYNAMIC_PERPWR) += -DCONFIG_DYNAMIC_PERPWR
|
ccflags-$(CONFIG_DYNAMIC_PERPWR) += -DCONFIG_DYNAMIC_PERPWR
|
||||||
ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING
|
ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING
|
||||||
|
ccflags-$(CONFIG_PRBREQ_REPORT) += -DCONFIG_PRBREQ_REPORT
|
||||||
|
ccflags-$(CONFIG_SUPPORT_4ADDR) += -DCONFIG_SUPPORT_4ADDR
|
||||||
ccflags-$(CONFIG_WRITE_FILE_D80X2) += -DRF_WRITE_FILE
|
ccflags-$(CONFIG_WRITE_FILE_D80X2) += -DRF_WRITE_FILE
|
||||||
|
|
||||||
ifeq ($(CONFIG_SDIO_SUPPORT), y)
|
ifeq ($(CONFIG_SDIO_SUPPORT), y)
|
||||||
@@ -338,10 +363,10 @@ ccflags-$(CONFIG_GKI) += -DCONFIG_GKI
|
|||||||
ccflags-$(CONFIG_SCHED_SCAN) += -DCONFIG_SCHED_SCAN
|
ccflags-$(CONFIG_SCHED_SCAN) += -DCONFIG_SCHED_SCAN
|
||||||
ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK
|
ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK
|
||||||
ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP
|
ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP
|
||||||
|
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
|
||||||
|
|
||||||
# Platform support list
|
# Platform support list
|
||||||
CONFIG_PLATFORM_ROCKCHIP ?= n
|
CONFIG_PLATFORM_ROCKCHIP ?= n
|
||||||
CONFIG_PLATFORM_ALLWINNER ?= n
|
CONFIG_PLATFORM_ALLWINNER ?= n
|
||||||
@@ -380,11 +405,13 @@ KDIR ?= /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
||||||
KVER := $(or $(KVER), $(kernelver), $(KERNELRELEASE), $(shell uname -r))
|
KVER ?= $(shell uname -r)
|
||||||
KDIR ?= /lib/modules/$(KVER)/build
|
KDIR ?= /lib/modules/$(KVER)/build
|
||||||
|
#KDIR ?= ~/D/Workspace/CyberQuantum/Linux/linux-4.15/
|
||||||
PWD ?= $(shell pwd)
|
PWD ?= $(shell pwd)
|
||||||
MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
|
MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
|
||||||
ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
|
SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
|
||||||
|
ARCH ?= $(SUBARCH)
|
||||||
CROSS_COMPILE ?=
|
CROSS_COMPILE ?=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,30 @@
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright(c) 2007 - 2017 Realtek Corporation.
|
* Copyright (C) 2019-2021 Aicsemi Corporation
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of version 2 of the GNU General Public License as
|
* you may not use this file except in compliance with the License.
|
||||||
* published by the Free Software Foundation.
|
* You may obtain a copy of the License at:
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
#define _AIC_BR_EXT_C_
|
#define _AIC_BR_EXT_C_
|
||||||
|
#include <linux/version.h>
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
#include <linux/if_arp.h>
|
#include <linux/if_arp.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||||
#include <net/ipx.h>
|
#include <net/ipx.h>
|
||||||
|
#endif
|
||||||
#include <linux/atalk.h>
|
#include <linux/atalk.h>
|
||||||
#include <linux/udp.h>
|
#include <linux/udp.h>
|
||||||
#include <linux/if_pppox.h>
|
#include <linux/if_pppox.h>
|
||||||
@@ -54,6 +61,7 @@
|
|||||||
#define MAGIC_CODE_LEN 2
|
#define MAGIC_CODE_LEN 2
|
||||||
#define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */
|
#define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------
|
/*-----------------------------------------------------------------
|
||||||
How database records network address:
|
How database records network address:
|
||||||
0 1 2 3 4 5 6 7 8 9 10
|
0 1 2 3 4 5 6 7 8 9 10
|
||||||
@@ -503,7 +511,6 @@ static void __nat25_db_network_insert(struct rwnx_vif *vif,
|
|||||||
spin_unlock_bh(&vif->br_ext_lock);
|
spin_unlock_bh(&vif->br_ext_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void __nat25_db_print(struct rwnx_vif *vif)
|
static void __nat25_db_print(struct rwnx_vif *vif)
|
||||||
{
|
{
|
||||||
spin_lock_bh(&vif->br_ext_lock);
|
spin_lock_bh(&vif->br_ext_lock);
|
||||||
@@ -746,6 +753,22 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
|
|||||||
|
|
||||||
protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN));
|
protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN));
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printk("nat25_db_handle: DA=%02x%02x%02x%02x%02x%02x SA=%02x%02x%02x%02x%02x%02x\n",
|
||||||
|
skb->data[0],
|
||||||
|
skb->data[1],
|
||||||
|
skb->data[2],
|
||||||
|
skb->data[3],
|
||||||
|
skb->data[4],
|
||||||
|
skb->data[5],
|
||||||
|
skb->data[6],
|
||||||
|
skb->data[7],
|
||||||
|
skb->data[8],
|
||||||
|
skb->data[9],
|
||||||
|
skb->data[10],
|
||||||
|
skb->data[11]);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*---------------------------------------------------*/
|
/*---------------------------------------------------*/
|
||||||
/* Handle IP frame */
|
/* Handle IP frame */
|
||||||
/*---------------------------------------------------*/
|
/*---------------------------------------------------*/
|
||||||
@@ -849,7 +872,6 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
|
|||||||
|
|
||||||
case NAT25_LOOKUP: {
|
case NAT25_LOOKUP: {
|
||||||
printk("NAT25: Lookup ARP\n");
|
printk("NAT25: Lookup ARP\n");
|
||||||
|
|
||||||
arp_ptr += arp->ar_hln;
|
arp_ptr += arp->ar_hln;
|
||||||
sender = (unsigned int *)arp_ptr;
|
sender = (unsigned int *)arp_ptr;
|
||||||
arp_ptr += (arp->ar_hln + arp->ar_pln);
|
arp_ptr += (arp->ar_hln + arp->ar_pln);
|
||||||
@@ -874,23 +896,34 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
|
|||||||
/*---------------------------------------------------*/
|
/*---------------------------------------------------*/
|
||||||
/* Handle IPX and Apple Talk frame */
|
/* Handle IPX and Apple Talk frame */
|
||||||
/*---------------------------------------------------*/
|
/*---------------------------------------------------*/
|
||||||
else if ((protocol == __constant_htons(ETH_P_IPX)) ||
|
else if (
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||||
|
(protocol == __constant_htons(ETH_P_IPX)) ||
|
||||||
|
#endif
|
||||||
(protocol == __constant_htons(ETH_P_ATALK)) ||
|
(protocol == __constant_htons(ETH_P_ATALK)) ||
|
||||||
(protocol == __constant_htons(ETH_P_AARP))) {
|
(protocol == __constant_htons(ETH_P_AARP))) {
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||||
unsigned char ipx_header[2] = {0xFF, 0xFF};
|
unsigned char ipx_header[2] = {0xFF, 0xFF};
|
||||||
struct ipxhdr *ipx = NULL;
|
struct ipxhdr *ipx = NULL;
|
||||||
|
#endif
|
||||||
struct elapaarp *ea = NULL;
|
struct elapaarp *ea = NULL;
|
||||||
struct ddpehdr *ddp = NULL;
|
struct ddpehdr *ddp = NULL;
|
||||||
unsigned char *framePtr = skb->data + ETH_HLEN;
|
unsigned char *framePtr = skb->data + ETH_HLEN;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||||
if (protocol == __constant_htons(ETH_P_IPX)) {
|
if (protocol == __constant_htons(ETH_P_IPX)) {
|
||||||
printk("NAT25: Protocol=IPX (Ethernet II)\n");
|
printk("NAT25: Protocol=IPX (Ethernet II)\n");
|
||||||
ipx = (struct ipxhdr *)framePtr;
|
ipx = (struct ipxhdr *)framePtr;
|
||||||
} else { /* if(protocol <= __constant_htons(ETH_FRAME_LEN)) */
|
} else
|
||||||
|
#endif
|
||||||
|
{ /* if(protocol <= __constant_htons(ETH_FRAME_LEN)) */
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||||
if (!memcmp(ipx_header, framePtr, 2)) {
|
if (!memcmp(ipx_header, framePtr, 2)) {
|
||||||
printk("NAT25: Protocol=IPX (Ethernet 802.3)\n");
|
printk("NAT25: Protocol=IPX (Ethernet 802.3)\n");
|
||||||
ipx = (struct ipxhdr *)framePtr;
|
ipx = (struct ipxhdr *)framePtr;
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
unsigned char ipx_8022_type = 0xE0;
|
unsigned char ipx_8022_type = 0xE0;
|
||||||
unsigned char snap_8022_type = 0xAA;
|
unsigned char snap_8022_type = 0xAA;
|
||||||
|
|
||||||
@@ -900,13 +933,15 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
|
|||||||
unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; /* Apple Talk DDP SNAP ID */
|
unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; /* Apple Talk DDP SNAP ID */
|
||||||
|
|
||||||
framePtr += 3; /* eliminate the 802.2 header */
|
framePtr += 3; /* eliminate the 802.2 header */
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||||
if (!memcmp(ipx_snap_id, framePtr, 5)) {
|
if (!memcmp(ipx_snap_id, framePtr, 5)) {
|
||||||
framePtr += 5; /* eliminate the SNAP header */
|
framePtr += 5; /* eliminate the SNAP header */
|
||||||
|
|
||||||
printk("NAT25: Protocol=IPX (Ethernet SNAP)\n");
|
printk("NAT25: Protocol=IPX (Ethernet SNAP)\n");
|
||||||
ipx = (struct ipxhdr *)framePtr;
|
ipx = (struct ipxhdr *)framePtr;
|
||||||
} else if (!memcmp(aarp_snap_id, framePtr, 5)) {
|
} else
|
||||||
|
#endif
|
||||||
|
if (!memcmp(aarp_snap_id, framePtr, 5)) {
|
||||||
framePtr += 5; /* eliminate the SNAP header */
|
framePtr += 5; /* eliminate the SNAP header */
|
||||||
|
|
||||||
ea = (struct elapaarp *)framePtr;
|
ea = (struct elapaarp *)framePtr;
|
||||||
@@ -919,7 +954,9 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
|
|||||||
framePtr[1], framePtr[2], framePtr[3], framePtr[4]);
|
framePtr[1], framePtr[2], framePtr[3], framePtr[4]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (*framePtr == ipx_8022_type) {
|
}
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||||
|
else if (*framePtr == ipx_8022_type) {
|
||||||
framePtr += 3; /* eliminate the 802.2 header */
|
framePtr += 3; /* eliminate the 802.2 header */
|
||||||
|
|
||||||
if (!memcmp(ipx_header, framePtr, 2)) {
|
if (!memcmp(ipx_header, framePtr, 2)) {
|
||||||
@@ -928,9 +965,11 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
|
|||||||
} else
|
} else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||||
/* IPX */
|
/* IPX */
|
||||||
if (ipx != NULL) {
|
if (ipx != NULL) {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
@@ -997,10 +1036,11 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
|
|||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}else
|
||||||
|
#endif
|
||||||
|
|
||||||
/* AARP */
|
/* AARP */
|
||||||
else if (ea != NULL) {
|
if (ea != NULL) {
|
||||||
/* Sanity check fields. */
|
/* Sanity check fields. */
|
||||||
if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) {
|
if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) {
|
||||||
printk("NAT25: Appletalk AARP Sanity check fail!\n");
|
printk("NAT25: Appletalk AARP Sanity check fail!\n");
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright(c) 2007 - 2017 Realtek Corporation.
|
* Copyright (C) 2019-2021 Aicsemi Corporation
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* under the terms of version 2 of the GNU General Public License as
|
* you may not use this file except in compliance with the License.
|
||||||
* published by the Free Software Foundation.
|
* You may obtain a copy of the License at:
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
#ifndef _AIC_BR_EXT_H_
|
#ifndef _AIC_BR_EXT_H_
|
||||||
#define _AIC_BR_EXT_H_
|
#define _AIC_BR_EXT_H_
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/vmalloc.h>
|
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include "rwnx_defs.h"
|
#include "rwnx_defs.h"
|
||||||
#include "rwnx_msg_tx.h"
|
#include "rwnx_msg_tx.h"
|
||||||
@@ -90,6 +88,7 @@ enum {
|
|||||||
EXEC_FLASH_OPER,
|
EXEC_FLASH_OPER,
|
||||||
RDWR_PWRADD2X,
|
RDWR_PWRADD2X,
|
||||||
RDWR_EFUSE_PWRADD2X,
|
RDWR_EFUSE_PWRADD2X,
|
||||||
|
GET_RSSI=0x52,
|
||||||
CHECK_FLASH=0x108,
|
CHECK_FLASH=0x108,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -342,7 +341,7 @@ static int aic_priv_cmd_set_tx (struct rwnx_hw *rwnx_hw, int argc, char *argv[],
|
|||||||
AICWFDBG(LOGINFO, "txparam:%d,%d,%d,%d,%d,%d\n", settx_param.chan, settx_param.bw,
|
AICWFDBG(LOGINFO, "txparam:%d,%d,%d,%d,%d,%d\n", settx_param.chan, settx_param.bw,
|
||||||
settx_param.mode, settx_param.rate, settx_param.length, settx_param.tx_intv_us);
|
settx_param.mode, settx_param.rate, settx_param.length, settx_param.tx_intv_us);
|
||||||
#ifdef CONFIG_POWER_LIMIT
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
r_idx = get_ccode_region(country_code);
|
r_idx = get_ccode_region(rwnx_hw->wiphy->regd->alpha2);
|
||||||
txpwr_loss = &txpwr_loss_tmp;
|
txpwr_loss = &txpwr_loss_tmp;
|
||||||
get_userconfig_txpwr_loss(txpwr_loss);
|
get_userconfig_txpwr_loss(txpwr_loss);
|
||||||
if (txpwr_loss->loss_enable_2g4 == 1)
|
if (txpwr_loss->loss_enable_2g4 == 1)
|
||||||
@@ -797,7 +796,10 @@ static int aic_priv_cmd_rdwr_pwrlvl (struct rwnx_hw *rwnx_hw, int argc, char *ar
|
|||||||
AICWFDBG(LOGERROR, "wrong func: %x\n", func);
|
AICWFDBG(LOGERROR, "wrong func: %x\n", func);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)){
|
if((dev->chipid == PRODUCT_ID_AIC8800D81)||
|
||||||
|
(dev->chipid == PRODUCT_ID_AIC8800D81X2) ||
|
||||||
|
(dev->chipid == PRODUCT_ID_AIC8800D89X2) ||
|
||||||
|
(dev->chipid == PRODUCT_ID_AIC8800D80N)) {
|
||||||
memcpy(command, &cfm.rftest_result[0], 6 * 12);
|
memcpy(command, &cfm.rftest_result[0], 6 * 12);
|
||||||
return (6 * 12);
|
return (6 * 12);
|
||||||
} else {
|
} else {
|
||||||
@@ -823,16 +825,19 @@ static int aic_priv_cmd_rdwr_pwrofst (struct rwnx_hw *rwnx_hw, int argc, char *a
|
|||||||
if (func == 0) { // read cur
|
if (func == 0) { // read cur
|
||||||
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, 0, NULL, &cfm);
|
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, 0, NULL, &cfm);
|
||||||
} else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1
|
} else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1
|
||||||
if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2))) {
|
if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) ||
|
||||||
|
(dev->chipid == PRODUCT_ID_AIC8800D81X2) ||
|
||||||
|
(dev->chipid == PRODUCT_ID_AIC8800D89X2) ||
|
||||||
|
(dev->chipid == PRODUCT_ID_AIC8800D80N))) {
|
||||||
u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16);
|
u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16);
|
||||||
u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16);
|
u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16);
|
||||||
s8_l pwrofst = (u8_l)command_strtoul(argv[4], NULL, 10);
|
s8_l pwrofst = (s8_l)command_strtoul(argv[4], NULL, 10);
|
||||||
u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst};
|
u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst};
|
||||||
AICWFDBG(LOGINFO, "set pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst);
|
AICWFDBG(LOGINFO, "set pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst);
|
||||||
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm);
|
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm);
|
||||||
} else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC))) {
|
} else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DLN))) {
|
||||||
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
|
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
|
||||||
s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10);
|
s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10);
|
||||||
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
|
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
|
||||||
AICWFDBG(LOGINFO, "set pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst);
|
AICWFDBG(LOGINFO, "set pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst);
|
||||||
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm);
|
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm);
|
||||||
@@ -843,9 +848,9 @@ static int aic_priv_cmd_rdwr_pwrofst (struct rwnx_hw *rwnx_hw, int argc, char *a
|
|||||||
AICWFDBG(LOGERROR, "wrong func: %x\n", func);
|
AICWFDBG(LOGERROR, "wrong func: %x\n", func);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW)) { // 3 = 3 (2.4g)
|
if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DLN)) { // 3 = 3 (2.4g)
|
||||||
res_len = 3;
|
res_len = 3;
|
||||||
} else if (dev->chipid == PRODUCT_ID_AIC8800D81) { // 3 * 2 (2.4g) + 3 * 6 (5g)
|
} else if ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D80N)) { // 3 * 2 (2.4g) + 3 * 6 (5g)
|
||||||
res_len = 3 * 3 + 3 * 6;
|
res_len = 3 * 3 + 3 * 6;
|
||||||
} else if ((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // ant0/1
|
} else if ((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // ant0/1
|
||||||
res_len = ( 3 * 3 + 3 * 6 ) * 2;
|
res_len = ( 3 * 3 + 3 * 6 ) * 2;
|
||||||
@@ -868,7 +873,7 @@ static int aic_priv_cmd_rdwr_pwrofstfine (struct rwnx_hw *rwnx_hw, int argc, cha
|
|||||||
} else if (func <= 2) { // write 2.4g/5g pwr ofst
|
} else if (func <= 2) { // write 2.4g/5g pwr ofst
|
||||||
if (argc > 3) {
|
if (argc > 3) {
|
||||||
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
|
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
|
||||||
s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10);
|
s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10);
|
||||||
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
|
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
|
||||||
AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst);
|
AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst);
|
||||||
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFSTFINE, sizeof(buf), buf, &cfm);
|
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFSTFINE, sizeof(buf), buf, &cfm);
|
||||||
@@ -930,16 +935,17 @@ static int aic_priv_cmd_rdwr_efuse_pwrofst (struct rwnx_hw *rwnx_hw, int argc, c
|
|||||||
if (func == 0) { // read cur
|
if (func == 0) { // read cur
|
||||||
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, 0, NULL, &cfm);
|
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, 0, NULL, &cfm);
|
||||||
} else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1
|
} else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1
|
||||||
if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2))) {
|
if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)
|
||||||
|
|| (dev->chipid == PRODUCT_ID_AIC8800D80N))) {
|
||||||
u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16);
|
u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16);
|
||||||
u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16);
|
u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16);
|
||||||
s8_l pwrofst = (u8_l)command_strtoul(argv[4], NULL, 10);
|
s8_l pwrofst = (s8_l)command_strtoul(argv[4], NULL, 10);
|
||||||
u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst};
|
u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst};
|
||||||
AICWFDBG(LOGINFO, "set efuse pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst);
|
AICWFDBG(LOGINFO, "set efuse pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst);
|
||||||
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm);
|
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm);
|
||||||
} else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC))) {
|
} else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DLN))) {
|
||||||
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
|
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
|
||||||
s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10);
|
s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10);
|
||||||
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
|
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
|
||||||
AICWFDBG(LOGINFO, "set efuse pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst);
|
AICWFDBG(LOGINFO, "set efuse pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst);
|
||||||
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm);
|
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm);
|
||||||
@@ -951,9 +957,9 @@ static int aic_priv_cmd_rdwr_efuse_pwrofst (struct rwnx_hw *rwnx_hw, int argc, c
|
|||||||
AICWFDBG(LOGERROR, "wrong func: %x\n", func);
|
AICWFDBG(LOGERROR, "wrong func: %x\n", func);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW)) { // 6 = 3 (2.4g) * 2
|
if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DLN)) { // 6 = 3 (2.4g) * 2
|
||||||
res_len = 3 * 2;
|
res_len = 3 * 2;
|
||||||
} else if (dev->chipid == PRODUCT_ID_AIC8800D81) { // 3 * 2 (2.4g) + 3 * 6 (5g)
|
} else if ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D80N)) { // 3 * 2 (2.4g) + 3 * 6 (5g)
|
||||||
res_len = (3 * 3 + 3 * 6) * 2;
|
res_len = (3 * 3 + 3 * 6) * 2;
|
||||||
} else if((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // 3 * 2 (2.4g) *2 + 3 * 6 (5g) *2
|
} else if((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // 3 * 2 (2.4g) *2 + 3 * 6 (5g) *2
|
||||||
res_len = (3 * 3 + 3 * 6) * 2 * 2;
|
res_len = (3 * 3 + 3 * 6) * 2 * 2;
|
||||||
@@ -976,7 +982,7 @@ static int aic_priv_cmd_rdwr_efuse_pwrofstfine (struct rwnx_hw *rwnx_hw, int arg
|
|||||||
} else if (func <= 2) { // write 2.4g/5g pwr ofst
|
} else if (func <= 2) { // write 2.4g/5g pwr ofst
|
||||||
if (argc > 3) {
|
if (argc > 3) {
|
||||||
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
|
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
|
||||||
s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10);
|
s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10);
|
||||||
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
|
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
|
||||||
AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst);
|
AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst);
|
||||||
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFSTFINE, sizeof(buf), buf, &cfm);
|
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFSTFINE, sizeof(buf), buf, &cfm);
|
||||||
@@ -1273,6 +1279,49 @@ static int aic_priv_cmd_set_pll_test (struct rwnx_hw *rwnx_hw, int argc, char *a
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int aic_priv_cmd_get_txpwr(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
|
||||||
|
{
|
||||||
|
s8_l power=0;
|
||||||
|
power = get_txpwr_max(power);
|
||||||
|
memcpy(command, &power, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int aic_priv_cmd_set_txpwr_loss(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
|
||||||
|
{
|
||||||
|
s8_l func;
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
struct aic_sdio_dev *dev = g_rwnx_plat->sdiodev;
|
||||||
|
#endif
|
||||||
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
struct aic_usb_dev *dev = g_rwnx_plat->usbdev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
func = (s8_l)command_strtoul(argv[1], NULL, 10);
|
||||||
|
AICWFDBG(LOGINFO, "set txpwr loss: %d\n", func);
|
||||||
|
if (dev->chipid == PRODUCT_ID_AIC8800D81 ||
|
||||||
|
dev->chipid == PRODUCT_ID_AIC8800D80N){
|
||||||
|
set_txpwr_loss_ofst(func);
|
||||||
|
rwnx_send_txpwr_lvl_v3_req(dev->rwnx_hw);
|
||||||
|
}else if(dev->chipid == PRODUCT_ID_AIC8800D81X2 ||
|
||||||
|
dev->chipid == PRODUCT_ID_AIC8800D89X2){
|
||||||
|
set_txpwr_loss_ofst(func);
|
||||||
|
rwnx_send_txpwr_lvl_v4_req(dev->rwnx_hw);
|
||||||
|
}else if(dev->chipid == PRODUCT_ID_AIC8800DC ||
|
||||||
|
dev->chipid == PRODUCT_ID_AIC8800DW){
|
||||||
|
set_txpwr_loss_ofst(func);
|
||||||
|
rwnx_send_txpwr_lvl_req(dev->rwnx_hw);
|
||||||
|
}else{
|
||||||
|
AICWFDBG(LOGINFO, "error:don't support 8800D");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AICWFDBG(LOGERROR, "wrong args\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int aic_priv_cmd_set_ant_mode (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
|
static int aic_priv_cmd_set_ant_mode (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
|
||||||
{
|
{
|
||||||
u8_l func = 0;
|
u8_l func = 0;
|
||||||
@@ -1340,6 +1389,12 @@ static int aic_priv_cmd_country_set(struct rwnx_hw *rwnx_hw, int argc,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rwnx_hw->mod_params->custregd) {
|
||||||
|
AICWFDBG(LOGERROR, "%s: invalid custregd\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AICWFDBG(LOGINFO, "cmd country_set: %s\n", argv[1]);
|
AICWFDBG(LOGINFO, "cmd country_set: %s\n", argv[1]);
|
||||||
|
|
||||||
regdomain = getRegdomainFromRwnxDB(rwnx_hw->wiphy, argv[1]);
|
regdomain = getRegdomainFromRwnxDB(rwnx_hw->wiphy, argv[1]);
|
||||||
@@ -1474,6 +1529,58 @@ static int aic_priv_cmd_check_flash(struct rwnx_hw *rwnx_hw, int argc, char *arg
|
|||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int aic_priv_cmd_get_rssi(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
|
||||||
|
{
|
||||||
|
rwnx_send_rftest_req(rwnx_hw, GET_RSSI, 0, NULL, &cfm);
|
||||||
|
memcpy(command, &cfm.rftest_result[0], 1);
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "get_rssi: %d\n", (char)cfm.rftest_result[0]);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||||
|
static int aic_priv_cmd_set_sta_thd(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
s8_l val;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
AICWFDBG(LOGERROR, "%s: Invalid parameters (argc=%d)\n", __func__, argc);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGDEBUG, "cmd set_sta_thd: %s, %s\n", argv[1], argv[2]);
|
||||||
|
|
||||||
|
val = (s8_l)command_strtoul(argv[2], NULL, 10);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const char *name;
|
||||||
|
s8_l *target;
|
||||||
|
size_t name_len;
|
||||||
|
} thd_map[] = {
|
||||||
|
{ "rssi_thd_0", &rwnx_hw->pwrth.rssi_thd_0, 10 },
|
||||||
|
{ "rssi_thd_1", &rwnx_hw->pwrth.rssi_thd_1, 10 },
|
||||||
|
{ "rssi_thd_2", &rwnx_hw->pwrth.rssi_thd_2, 10 },
|
||||||
|
{ "pwr_loss_lvl_0", &rwnx_hw->pwrth.pwr_loss_lvl_0, 14 },
|
||||||
|
{ "pwr_loss_lvl_1", &rwnx_hw->pwrth.pwr_loss_lvl_1, 14 },
|
||||||
|
{ "pwr_loss_lvl_2", &rwnx_hw->pwrth.pwr_loss_lvl_2, 14 },
|
||||||
|
{ "pwr_loss_lvl_3", &rwnx_hw->pwrth.pwr_loss_lvl_3, 14 },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(thd_map); i++) {
|
||||||
|
if (strncmp(argv[1], thd_map[i].name, thd_map[i].name_len) == 0) {
|
||||||
|
*thd_map[i].target = val;
|
||||||
|
AICWFDBG(LOGINFO, "%s: %s = %d\n", __func__, thd_map[i].name, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGERROR, "%s: Unknown parameter '%s'\n", __func__, argv[1]);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int aic_priv_cmd_help (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
|
static int aic_priv_cmd_help (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
|
||||||
{
|
{
|
||||||
print_help(argc > 0 ? argv[0] : NULL);
|
print_help(argc > 0 ? argv[0] : NULL);
|
||||||
@@ -1575,6 +1682,10 @@ static const struct aic_priv_cmd aic_priv_commands[] = {
|
|||||||
"= off usb configure before usb disconnect" },
|
"= off usb configure before usb disconnect" },
|
||||||
{ "set_pll_test", aic_priv_cmd_set_pll_test,
|
{ "set_pll_test", aic_priv_cmd_set_pll_test,
|
||||||
"<func> <freq> <tx_pwr> = use pll test to measure saturation power" },
|
"<func> <freq> <tx_pwr> = use pll test to measure saturation power" },
|
||||||
|
{ "get_txpwr", aic_priv_cmd_get_txpwr,
|
||||||
|
"= get userconfig max txpwr" },
|
||||||
|
{ "set_txpwr_loss",aic_priv_cmd_set_txpwr_loss,
|
||||||
|
"<val> = txpwr will change ,val can be negative" },
|
||||||
{ "set_ant", aic_priv_cmd_set_ant_mode,
|
{ "set_ant", aic_priv_cmd_set_ant_mode,
|
||||||
"<val> = 0/ant0, 1/ant1, 2/both" },
|
"<val> = 0/ant0, 1/ant1, 2/both" },
|
||||||
{ "rdwr_bt_efuse_pwrofst", aic_priv_cmd_rdwr_bt_efuse_pwrofst,
|
{ "rdwr_bt_efuse_pwrofst", aic_priv_cmd_rdwr_bt_efuse_pwrofst,
|
||||||
@@ -1589,6 +1700,11 @@ static const struct aic_priv_cmd aic_priv_commands[] = {
|
|||||||
"a value is added for both 2.4G and 5G to achieve overall power adjustment of the band, write to efuse"},
|
"a value is added for both 2.4G and 5G to achieve overall power adjustment of the band, write to efuse"},
|
||||||
{"check_flash", aic_priv_cmd_check_flash,
|
{"check_flash", aic_priv_cmd_check_flash,
|
||||||
"check bin crc in flash" },
|
"check bin crc in flash" },
|
||||||
|
{"get_rssi", aic_priv_cmd_get_rssi, "get rssi"},
|
||||||
|
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||||
|
{"set_sta_thd", aic_priv_cmd_set_sta_thd,
|
||||||
|
"set per_sta power threshold, (set_sta_thd rssi_thd_0 value; set_sta_thd pwr_loss_lvl_0 value)"},
|
||||||
|
#endif
|
||||||
|
|
||||||
//Reserve for new aic_priv_cmd.
|
//Reserve for new aic_priv_cmd.
|
||||||
{ "help", aic_priv_cmd_help,
|
{ "help", aic_priv_cmd_help,
|
||||||
@@ -1716,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
|
||||||
@@ -1724,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)
|
||||||
@@ -1751,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);
|
||||||
@@ -1794,7 +1910,7 @@ int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(&cs_info, 0, sizeof(struct aicwf_cs_info));
|
memset(&cs_info, 0, sizeof(struct aicwf_cs_info));
|
||||||
memcpy(cs_info.countrycode, country_code, 4);
|
memcpy(cs_info.countrycode, vif->rwnx_hw->wiphy->regd->alpha2, 2);
|
||||||
|
|
||||||
if((sta == NULL) && (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_AP)) {
|
if((sta == NULL) && (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_AP)) {
|
||||||
sta = &vif->rwnx_hw->sta_table[vif->ap.bcmc_index];
|
sta = &vif->rwnx_hw->sta_table[vif->ap.bcmc_index];
|
||||||
@@ -1940,6 +2056,11 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
|
|||||||
strncasecmp(command, "country_set", strlen("country_set"))) {
|
strncasecmp(command, "country_set", strlen("country_set"))) {
|
||||||
skip = strlen(CMD_SET_COUNTRY) + 1;
|
skip = strlen(CMD_SET_COUNTRY) + 1;
|
||||||
country = command + skip;
|
country = command + skip;
|
||||||
|
if (!vif->rwnx_hw->mod_params->custregd) {
|
||||||
|
AICWFDBG(LOGERROR, "%s: invalid custregd\n", __func__);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
if (!country || strlen(country) < RWNX_COUNTRY_CODE_LEN) {
|
if (!country || strlen(country) < RWNX_COUNTRY_CODE_LEN) {
|
||||||
AICWFDBG(LOGERROR, "%s: invalid country code\n", __func__);
|
AICWFDBG(LOGERROR, "%s: invalid country code\n", __func__);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
@@ -1991,9 +2112,11 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
|
|||||||
if(g_rwnx_plat && g_rwnx_plat->usbdev->rwnx_hw){
|
if(g_rwnx_plat && g_rwnx_plat->usbdev->rwnx_hw){
|
||||||
if (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW ||
|
if (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW ||
|
||||||
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DC) ||
|
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DC) ||
|
||||||
|
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DLN) ||
|
||||||
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81) ||
|
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81) ||
|
||||||
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81X2) ||
|
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81X2) ||
|
||||||
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D89X2)){
|
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) ||
|
||||||
|
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D80N)){
|
||||||
set_testmode(!testmode);
|
set_testmode(!testmode);
|
||||||
rwnx_send_reboot(g_rwnx_plat->usbdev->rwnx_hw);
|
rwnx_send_reboot(g_rwnx_plat->usbdev->rwnx_hw);
|
||||||
}
|
}
|
||||||
@@ -2013,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);
|
||||||
|
|||||||
@@ -59,6 +59,14 @@ typedef struct _compat_android_wifi_priv_cmd {
|
|||||||
int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd);
|
int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd);
|
||||||
int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val);
|
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);
|
||||||
|
int str_starts(const char *str, const char *start);
|
||||||
|
int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len);
|
||||||
|
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
|
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter);
|
||||||
|
#else
|
||||||
|
void set_mon_chan(struct rwnx_vif *vif, char *parameter);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _AIC_PRIV_CMD_H_ */
|
#endif /* _AIC_PRIV_CMD_H_ */
|
||||||
|
|
||||||
|
|||||||
@@ -323,6 +323,13 @@ static int aicwf_vendor_subcmd_set_country_code(struct wiphy *wiphy, struct wire
|
|||||||
const struct nlattr *iter;
|
const struct nlattr *iter;
|
||||||
struct ieee80211_regdomain *regdomain;
|
struct ieee80211_regdomain *regdomain;
|
||||||
|
|
||||||
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
|
|
||||||
|
if (!rwnx_hw->mod_params->custregd) {
|
||||||
|
AICWFDBG(LOGERROR, "%s: invalid custregd\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
nla_for_each_attr(iter, data, len, rem) {
|
nla_for_each_attr(iter, data, len, rem) {
|
||||||
type = nla_type(iter);
|
type = nla_type(iter);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define _AIC_VENDOR_H
|
#define _AIC_VENDOR_H
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
|
||||||
#define GOOGLE_OUI 0x001A11
|
#define GOOGLE_OUI 0x001A11
|
||||||
#define BRCM_OUI 0x001018
|
#define BRCM_OUI 0x001018
|
||||||
@@ -342,5 +343,10 @@ typedef struct wl_mkeep_alive_pkt {
|
|||||||
u8 data[1];
|
u8 data[1];
|
||||||
} wl_mkeep_alive_pkt_t;
|
} wl_mkeep_alive_pkt_t;
|
||||||
|
|
||||||
|
int aic_dev_start_mkeep_alive(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
u8 mkeep_alive_id, u8 *ip_pkt, u16 ip_pkt_len, u8 *src_mac, u8 *dst_mac, u32 period_msec);
|
||||||
|
int aic_dev_stop_mkeep_alive(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, u8 mkeep_alive_id);
|
||||||
|
int aicwf_vendor_init(struct wiphy *wiphy);
|
||||||
|
|
||||||
#endif /* _AIC_VENDOR_H */
|
#endif /* _AIC_VENDOR_H */
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
#include "rwnx_main.h"
|
#include "rwnx_main.h"
|
||||||
#include "rwnx_msg_tx.h"
|
#include "rwnx_msg_tx.h"
|
||||||
#include "reg_access.h"
|
#include "reg_access.h"
|
||||||
|
#include "aicwf_compat_8800d80.h"
|
||||||
|
|
||||||
#define FW_USERCONFIG_NAME_8800D80 "aic_userconfig_8800d80.txt"
|
#define FW_USERCONFIG_NAME_8800D80 "aic_userconfig_8800d80.txt"
|
||||||
#define FW_USERCONFIG_NAME_8800D80_U11 "aic_userconfig_8800d80_u11.txt"
|
|
||||||
#define FW_USERCONFIG_NAME_8800D80_U11_PRO "aic_userconfig_8800d80_u11_pro.txt"
|
|
||||||
#define FW_USERCONFIG_NAME_8800D80_U11_CUS "aic_userconfig_8800d80_u11_cus.txt"
|
|
||||||
#define FW_POWERLIMIT_NAME_8800D80 "aic_powerlimit_8800d80.txt"
|
#define FW_POWERLIMIT_NAME_8800D80 "aic_powerlimit_8800d80.txt"
|
||||||
|
|
||||||
extern char aic_fw_path[200];
|
extern char aic_fw_path[200];
|
||||||
@@ -40,23 +38,10 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){
|
|||||||
int size;
|
int size;
|
||||||
u32 *dst=NULL;
|
u32 *dst=NULL;
|
||||||
char *filename = FW_USERCONFIG_NAME_8800D80;
|
char *filename = FW_USERCONFIG_NAME_8800D80;
|
||||||
if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11
|
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS1
|
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS4
|
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS7) {
|
|
||||||
filename = FW_USERCONFIG_NAME_8800D80_U11;
|
|
||||||
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11_PRO
|
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS3
|
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS5
|
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS6
|
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS8) {
|
|
||||||
filename = FW_USERCONFIG_NAME_8800D80_U11_PRO;
|
|
||||||
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS2) {
|
|
||||||
filename = FW_USERCONFIG_NAME_8800D80_U11_CUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#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);
|
||||||
@@ -102,7 +87,7 @@ int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw)
|
|||||||
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
/* parsing the file */
|
/* parsing the file */
|
||||||
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code);
|
rwnx_plat_powerlimit_parsing((char *)dst, size);
|
||||||
|
|
||||||
rwnx_release_firmware_common(&dst);
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
@@ -111,3 +96,37 @@ int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int system_config_8800d80(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
const u32 mem_addr = 0x40500000;
|
||||||
|
const u32 read_mem_addr = 0x40241014;
|
||||||
|
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGINFO, "%x rd fail: %d\n", mem_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL) {
|
||||||
|
chip_mcu_id = 1;
|
||||||
|
}
|
||||||
|
chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16);
|
||||||
|
AICWFDBG(LOGINFO, "chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id);
|
||||||
|
if (testmode == 1 && (IS_CHIP_ID_H()))
|
||||||
|
{
|
||||||
|
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, read_mem_addr, &rd_mem_addr_cfm);
|
||||||
|
AICWFDBG(LOGINFO, "%s 0x%08x=0x%08x\n", __func__, read_mem_addr, rd_mem_addr_cfm.memdata);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "%x rd fail: %d\n", read_mem_addr, ret);
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
if (rd_mem_addr_cfm.memdata != 1) {
|
||||||
|
AICWFDBG(LOGERROR, "check fail: %x\n", rd_mem_addr_cfm.memdata);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw);
|
|||||||
int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw);
|
int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw);
|
||||||
#endif
|
#endif
|
||||||
int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
|
int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
|
||||||
|
int system_config_8800d80(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,560 @@
|
|||||||
|
#include "rwnx_main.h"
|
||||||
|
#include "rwnx_msg_tx.h"
|
||||||
|
#include "reg_access.h"
|
||||||
|
#include "rwnx_platform.h"
|
||||||
|
#include "aicwf_compat_8800d80n.h"
|
||||||
|
|
||||||
|
#define FW_USERCONFIG_NAME_8800D80N "aic_userconfig_8800d80n.txt"
|
||||||
|
#define FW_POWERLIMIT_NAME_8800D80N "aic_powerlimit_8800d80n.txt"
|
||||||
|
#define RWNX_MAC_FW_RF_BASE_NAME_8800D80N "lmacfw_rf_8800d80n.bin"
|
||||||
|
#define RWNX_MAC_FW_INITVAR_NAME_8800D80N "fmacfw_initvar_8800d80n.bin"
|
||||||
|
#define RWNX_MAC_FW_GAINTBL_NAME_8800D80N "fmacfw_gaintbl_8800d80n.bin"
|
||||||
|
#define RWNX_MAC_FW_CINIT_NAME_8800D80N_U02 "fmacfw_cinit_8800d80n_u02.bin"
|
||||||
|
#define RWNX_MAC_FW_CALIB_NAME_8800D80N_U02 "fmacfw_calib_8800d80n_u02.bin"
|
||||||
|
#define RWNX_MAC_PATCH_NAME_8800D80N_U02 "fmacfw_patch_8800d80n_u02.bin"
|
||||||
|
#define RWNX_MAC_PATCHTBL_NAME_8800D80N_U02 "fmacfw_patch_tbl_8800d80n_u02.bin"
|
||||||
|
|
||||||
|
#define RAM_LMAC_FW_RF_ADDR_8800D80N 0x00132C00
|
||||||
|
#define ROM_FMAC_CINIT_ADDR_8800D80N_U02 0x00133000
|
||||||
|
#define ROM_FMAC_CALIB_ADDR_8800D80N_U02 0x00138000
|
||||||
|
#define ROM_FMAC_PATCH_ADDR_8800D80N_U02 0x00188000
|
||||||
|
|
||||||
|
#define CHIP_INFO_FLAG_CINIT_BEGIN (0x01U << 12)
|
||||||
|
#define CHIP_INFO_FLAG_CINIT_DONE (0x01U << 13)
|
||||||
|
|
||||||
|
#define PATCH_VAR_FLAG_CALIB_BEGIN (0x01U << 0)
|
||||||
|
#define PATCH_VAR_FLAG_CALIB_DONE (0x01U << 1)
|
||||||
|
|
||||||
|
#define WF_RXGAIN_TBL_IDX_MAX 20
|
||||||
|
#define WF_RXGAIN_TBL_SIZE 256
|
||||||
|
#define WF_TXGAIN_TBL_IDX_MAX 21
|
||||||
|
#define WF_TXGAIN_TBL_SIZE 128
|
||||||
|
|
||||||
|
extern char aic_fw_path[200];
|
||||||
|
|
||||||
|
int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
|
||||||
|
char *filename);
|
||||||
|
int rwnx_plat_bin_fw_upload_2_with_version(struct rwnx_hw *rwnx_hw, u32 fw_addr,
|
||||||
|
char *filename, char *version_str, int version_size);
|
||||||
|
int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw,
|
||||||
|
u32** buffer, const char *filename);
|
||||||
|
void rwnx_plat_userconfig_parsing(char *buffer, int size);
|
||||||
|
void rwnx_release_firmware_common(u32** buffer);
|
||||||
|
|
||||||
|
extern int get_adap_test(void);
|
||||||
|
|
||||||
|
typedef u32 (*array2_tbl_t)[2];
|
||||||
|
typedef u32 (*array3_tbl_t)[3];
|
||||||
|
|
||||||
|
u32 syscfg_tbl_masked_8800d80n[][3] = {
|
||||||
|
// {Address, mask, value}
|
||||||
|
#if DEF_PATCH_METHOD_VER_1 // moved to cinit.bin
|
||||||
|
// anareg1, u01 only
|
||||||
|
{0x4050201C, (0x7 << 0), (0x7 << 0)},
|
||||||
|
// pmic_pmu_init
|
||||||
|
{0x70001024, ((0x1F << 0) | (0x1 << 14) | (0x1 << 15)),
|
||||||
|
((0x08 << 0) | (0x1 << 14) | (0x1 << 15))},
|
||||||
|
{0x70001044, (0xF << 20), (0x4 << 20)},
|
||||||
|
{0x70001084, ((0xF << 23) | (0x1 << 27) | (0x1 << 31)),
|
||||||
|
((0x4 << 23) | (0x0 << 27) | (0x1 << 31))},
|
||||||
|
{0x70002118, (0x3 << 0), (0x0 << 0)},
|
||||||
|
{0x7000211C, (0x3 << 2), (0x0 << 2)},
|
||||||
|
{0x700021D8, (0x3 << 4), (0x0 << 4)},
|
||||||
|
{0x700021D0, ((0x1 << 5) | (0x1 << 6)),
|
||||||
|
((0x1 << 5) | (0x1 << 6))},
|
||||||
|
#if defined(CONFIG_VRF_DCDC_MODE)
|
||||||
|
{0x70001000, (0x1 << 0), (0x1 << 0)},
|
||||||
|
#else
|
||||||
|
{0x70001000, (0x1 << 0), (0x0 << 0)},
|
||||||
|
#endif
|
||||||
|
// cm_rf_init
|
||||||
|
{0x4050500C, ((0x7 << 27) | (0x3 << 30)),
|
||||||
|
((0x3 << 27) | (0x3 << 30))},
|
||||||
|
{0x40505008, ((0x3 << 11) | (0xF << 15)),
|
||||||
|
((0x1 << 11) | (0x4 << 15))},
|
||||||
|
#endif
|
||||||
|
{0x00000000, 0x00000000, 0x00000000}, // last one
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 patch_tbl_wifisetting_8800d80n[][2] =
|
||||||
|
{
|
||||||
|
//{0x00b8, 0x00009d08 | (0x01U << 13)}, // debug_mask, bit13: CALIB_BIT
|
||||||
|
};
|
||||||
|
|
||||||
|
//adap test
|
||||||
|
u32 adaptivity_patch_tbl_8800d80n[][2] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 patch_tbl_rf_func_8800d80n[][2] =
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int testmode;
|
||||||
|
extern u8 chip_id;
|
||||||
|
extern u8 chip_mcu_id;
|
||||||
|
|
||||||
|
void system_config_8800d80n(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int syscfg_num;
|
||||||
|
array3_tbl_t p_syscfg_msk_tbl;
|
||||||
|
int ret, cnt;
|
||||||
|
const u32 mem_addr = 0x40500000;
|
||||||
|
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||||
|
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16);
|
||||||
|
//printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
|
||||||
|
if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL) {
|
||||||
|
chip_mcu_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chip_sub_id = (u8)(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);
|
||||||
|
|
||||||
|
syscfg_num = sizeof(syscfg_tbl_masked_8800d80n) / sizeof(u32) / 3;
|
||||||
|
p_syscfg_msk_tbl = syscfg_tbl_masked_8800d80n;
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||||
|
if (p_syscfg_msk_tbl[cnt][0] == 0x00000000) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = rwnx_send_dbg_mem_mask_write_req(rwnx_hw,
|
||||||
|
p_syscfg_msk_tbl[cnt][0], p_syscfg_msk_tbl[cnt][1], p_syscfg_msk_tbl[cnt][2]);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "%x mask write fail: %d\n", p_syscfg_msk_tbl[cnt][0], ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int aicwf_plat_patch_load_8800d80n(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
char patch_ver_str[128];
|
||||||
|
//wifi patch
|
||||||
|
ret = rwnx_plat_bin_fw_upload_2_with_version(rwnx_hw,
|
||||||
|
ROM_FMAC_PATCH_ADDR_8800D80N_U02, RWNX_MAC_PATCH_NAME_8800D80N_U02, patch_ver_str, sizeof(patch_ver_str));
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "load patch bin fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO, "PatchVer: %s", patch_ver_str);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aicwf_plat_patch_table_load_8800d80n(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
unsigned int i, size;
|
||||||
|
u32 *dst = NULL;
|
||||||
|
char *filename = RWNX_MAC_PATCHTBL_NAME_8800D80N_U02;
|
||||||
|
|
||||||
|
/* Copy the file on the Embedded side */
|
||||||
|
AICWFDBG(LOGINFO, "### Upload %s \n", filename);
|
||||||
|
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
if (!dst) {
|
||||||
|
AICWFDBG(LOGERROR, "No such file or directory\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (size <= 0) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
|
||||||
|
dst = NULL;
|
||||||
|
err = -1;
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO, "tbl size = %d \n", size);
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
for (i = 0; i < (size / 4); i += 2) {
|
||||||
|
if ((dst[i] == 0x0) || (dst[i] == 0xFFFFFFFF)) {
|
||||||
|
break; // end of tbl
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGERROR, "patch_tbl: %x %x\n", dst[i], dst[i+1]);
|
||||||
|
err = rwnx_send_dbg_mem_write_req(rwnx_hw, dst[i], dst[i+1]);
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
AICWFDBG(LOGERROR, "tbl bin upload fail: %x, err:%d\r\n", dst[i], err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst) {
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_patch_config_8800d80n(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_ROM_PATCH_EN
|
||||||
|
int ret = 0;
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
//adap test
|
||||||
|
int adap_test = 0;
|
||||||
|
int adap_patch_num = 0;
|
||||||
|
|
||||||
|
adap_test = get_adap_test();
|
||||||
|
//adap test
|
||||||
|
|
||||||
|
if (testmode == 0) {
|
||||||
|
const u32 cfg_base = 0x10170;
|
||||||
|
struct dbg_mem_read_cfm cfm;
|
||||||
|
//int i;
|
||||||
|
u32 wifisetting_cfg_addr;
|
||||||
|
u32 agc_cfg_addr;
|
||||||
|
u32 txgain_cfg_24g_addr, txgain_cfg_5g_addr;
|
||||||
|
u32 jump_tbl_addr = 0;
|
||||||
|
|
||||||
|
u32 patch_tbl_wifisetting_num = sizeof(patch_tbl_wifisetting_8800d80n)/sizeof(u32)/2;
|
||||||
|
//u32 jump_tbl_size = 0;
|
||||||
|
//u32 patch_tbl_func_num = 0;
|
||||||
|
|
||||||
|
//array2_tbl_t jump_tbl_base = NULL;
|
||||||
|
//array2_tbl_t patch_tbl_func_base = NULL;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm))) {
|
||||||
|
AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", cfg_base, ret);
|
||||||
|
}
|
||||||
|
wifisetting_cfg_addr = cfm.memdata;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 4, &cfm))) {
|
||||||
|
AICWFDBG(LOGERROR, "jump_tbl base[0x%x] rd fail: %d\n", cfg_base + 4, ret);
|
||||||
|
}
|
||||||
|
jump_tbl_addr = cfm.memdata;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x10, &cfm))) {
|
||||||
|
AICWFDBG(LOGERROR, "agc_cfg base[0x%x] rd fail: %d\n", cfg_base + 0xc, ret);
|
||||||
|
}
|
||||||
|
agc_cfg_addr = cfm.memdata;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) {
|
||||||
|
AICWFDBG(LOGERROR, "txgain_cfg_24g base[0x%x] rd fail: %d\n", cfg_base + 0x10, ret);
|
||||||
|
}
|
||||||
|
txgain_cfg_24g_addr = cfm.memdata;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x18, &cfm))) {
|
||||||
|
AICWFDBG(LOGERROR, "txgain_cfg_5g base[0x%x] rd fail: %d\n", cfg_base + 0x10, ret);
|
||||||
|
}
|
||||||
|
txgain_cfg_5g_addr = cfm.memdata;
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "wifisetting_cfg_addr=%x, jump_tbl_addr=%x, agc_cfg_addr=%x, txgain_cfg_24g_addr=%x, txgain_cfg_5g_addr=%x\n",
|
||||||
|
wifisetting_cfg_addr, jump_tbl_addr, agc_cfg_addr, txgain_cfg_24g_addr, txgain_cfg_5g_addr);
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < patch_tbl_wifisetting_num; cnt++) {
|
||||||
|
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + patch_tbl_wifisetting_8800d80n[cnt][0], patch_tbl_wifisetting_8800d80n[cnt][1]))) {
|
||||||
|
AICWFDBG(LOGERROR, "wifisetting %x write fail\n", patch_tbl_wifisetting_8800d80n[cnt][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//adap test
|
||||||
|
if (adap_test) {
|
||||||
|
adap_patch_num = sizeof(adaptivity_patch_tbl_8800d80n)/sizeof(u32)/2;
|
||||||
|
for(cnt = 0; cnt < adap_patch_num; cnt++)
|
||||||
|
{
|
||||||
|
if((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + adaptivity_patch_tbl_8800d80n[cnt][0], adaptivity_patch_tbl_8800d80n[cnt][1]))) {
|
||||||
|
AICWFDBG(LOGERROR, "%x write fail\n", wifisetting_cfg_addr + adaptivity_patch_tbl_8800d80n[cnt][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//adap test
|
||||||
|
|
||||||
|
#if DEF_PATCH_METHOD_VER_1
|
||||||
|
ret = aicwf_plat_initvar_load_8800d80n(rwnx_hw, txgain_cfg_24g_addr);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "initvar load fail: %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
u32 patch_tbl_rf_func_num = sizeof(patch_tbl_rf_func_8800d80n)/sizeof(u32)/2;
|
||||||
|
for (cnt = 0; cnt < patch_tbl_rf_func_num; cnt++) {
|
||||||
|
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_rf_func_8800d80n[cnt][0], patch_tbl_rf_func_8800d80n[cnt][1]))) {
|
||||||
|
AICWFDBG(LOGERROR, "patch_tbl_rf_func %x write fail\n", patch_tbl_rf_func_8800d80n[cnt][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int aicwf_plat_rftest_load_8800d80n(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, RAM_LMAC_FW_RF_ADDR_8800D80N, RWNX_MAC_FW_RF_BASE_NAME_8800D80N);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aicwf_plat_rftest_exec_8800d80n(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
uint32_t fw_addr, boot_type;
|
||||||
|
uint32_t rst_hdlr_addr = RAM_LMAC_FW_RF_ADDR_8800D80N + 0x04;
|
||||||
|
uint32_t rst_hdlr_val;
|
||||||
|
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, rst_hdlr_addr, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "%x rd fail: %d\n", rst_hdlr_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
rst_hdlr_val = rd_mem_addr_cfm.memdata;
|
||||||
|
if ((rst_hdlr_val & ~0x03FF) == RAM_LMAC_FW_RF_ADDR_8800D80N) {
|
||||||
|
AICWFDBG(LOGINFO, "rftest loaded, hdlr=%x\n", rst_hdlr_val);
|
||||||
|
}
|
||||||
|
/* fw start */
|
||||||
|
fw_addr = RAM_LMAC_FW_RF_ADDR_8800D80N;
|
||||||
|
boot_type = HOST_START_APP_AUTO;
|
||||||
|
AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type);
|
||||||
|
ret = rwnx_send_dbg_start_app_req(rwnx_hw, fw_addr, boot_type);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "start app fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEF_PATCH_METHOD_VER_1
|
||||||
|
int aicwf_plat_initvar_load_8800d80n(struct rwnx_hw *rwnx_hw, u32 var_base_addr)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, var_base_addr, RWNX_MAC_FW_INITVAR_NAME_8800D80N);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "load initvar bin fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aicwf_plat_gain_table_load_8800d80n(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int size, desired_size, idx, ret;
|
||||||
|
u32 *dst=NULL;
|
||||||
|
u8_l *tbl_base;
|
||||||
|
char *filename = RWNX_MAC_FW_GAINTBL_NAME_8800D80N;
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "gaintbl file path:%s\n", filename);
|
||||||
|
|
||||||
|
/* load file */
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
desired_size = WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE + WF_TXGAIN_TBL_IDX_MAX * WF_TXGAIN_TBL_SIZE;
|
||||||
|
if ((size <= 0) || (size != desired_size)) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of firmware file, desired=%d, size=%d\n", desired_size, size);
|
||||||
|
if (dst) {
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
dst = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the file on the Embedded side */
|
||||||
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
|
/* RX gain */
|
||||||
|
tbl_base = (u8_l *)dst;
|
||||||
|
for (idx = 0; idx < WF_RXGAIN_TBL_IDX_MAX; idx++) {
|
||||||
|
u16_l ofst = idx * 16;
|
||||||
|
u8_l *tbl_ptr = tbl_base + idx * WF_RXGAIN_TBL_SIZE;
|
||||||
|
ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 0, tbl_ptr, WF_RXGAIN_TBL_SIZE);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "rx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TX gain */
|
||||||
|
tbl_base = (u8_l *)dst + WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE;
|
||||||
|
for (idx = 0; idx < WF_TXGAIN_TBL_IDX_MAX; idx++) {
|
||||||
|
u16_l ofst = idx * 16;
|
||||||
|
u8_l *tbl_ptr = tbl_base + idx * WF_TXGAIN_TBL_SIZE;
|
||||||
|
ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 2, tbl_ptr, WF_TXGAIN_TBL_SIZE);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "tx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "gaintbl download complete\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEF_PATCH_METHOD_VER_2
|
||||||
|
int aicwf_plat_cinit_exec_8800d80n(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
uint32_t fw_addr, boot_type;
|
||||||
|
uint32_t mem_addr = 0x40500184;
|
||||||
|
uint32_t mem_val;
|
||||||
|
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
mem_val = rd_mem_addr_cfm.memdata;
|
||||||
|
if (mem_val & CHIP_INFO_FLAG_CINIT_BEGIN) {
|
||||||
|
// wait done
|
||||||
|
while (!(mem_val & CHIP_INFO_FLAG_CINIT_DONE)) {
|
||||||
|
AICWFDBG(LOGINFO, "cinit rd chipinfo=%x\n", mem_val);
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
mem_val = rd_mem_addr_cfm.memdata;
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO, "cinit executed, chipinfo=%x\n", mem_val);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_CINIT_ADDR_8800D80N_U02, RWNX_MAC_FW_CINIT_NAME_8800D80N_U02);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "load cinit bin fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* fw start */
|
||||||
|
fw_addr = ROM_FMAC_CINIT_ADDR_8800D80N_U02 + 0x0009;
|
||||||
|
boot_type = HOST_START_APP_FNCALL;
|
||||||
|
AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type);
|
||||||
|
ret = rwnx_send_dbg_start_app_req(rwnx_hw, fw_addr, boot_type);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "start app fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aicwf_plat_calib_exec_8800d80n(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
uint32_t fw_addr, boot_type;
|
||||||
|
uint32_t patch_var_flags_addr = ROM_FMAC_PATCH_ADDR_8800D80N_U02 + 0x08;
|
||||||
|
uint32_t patch_var_flags_val;
|
||||||
|
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, patch_var_flags_addr, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "%x rd fail: %d\n", patch_var_flags_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
patch_var_flags_val = rd_mem_addr_cfm.memdata;
|
||||||
|
if (patch_var_flags_val & (PATCH_VAR_FLAG_CALIB_BEGIN | PATCH_VAR_FLAG_CALIB_DONE)) {
|
||||||
|
AICWFDBG(LOGINFO, "calib executed, var_flags=%x\n", patch_var_flags_val);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_CALIB_ADDR_8800D80N_U02, RWNX_MAC_FW_CALIB_NAME_8800D80N_U02);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "load calib bin fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* fw start */
|
||||||
|
fw_addr = ROM_FMAC_CALIB_ADDR_8800D80N_U02 + 0x0009;
|
||||||
|
boot_type = HOST_START_APP_FNCALL;
|
||||||
|
AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type);
|
||||||
|
ret = rwnx_send_dbg_start_app_req(rwnx_hw, fw_addr, boot_type);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "start app fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int aicwf_set_rf_config_8800d80n(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_txpwr_lvl_v3_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ret = rwnx_send_txpwr_lvl_adj_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ret = rwnx_send_txpwr_ofst2x_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#if DEF_PATCH_METHOD_VER_1
|
||||||
|
if (testmode == FW_NORMAL_MODE) {
|
||||||
|
aicwf_plat_gain_table_load_8800d80n(rwnx_hw);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int rwnx_plat_userconfig_load_8800d80n(struct rwnx_hw *rwnx_hw){
|
||||||
|
int size;
|
||||||
|
u32 *dst=NULL;
|
||||||
|
char *filename = FW_USERCONFIG_NAME_8800D80N;
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
||||||
|
|
||||||
|
/* load file */
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
if (size <= 0) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
|
||||||
|
dst = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the file on the Embedded side */
|
||||||
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
|
rwnx_plat_userconfig_parsing((char *)dst, size);
|
||||||
|
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "userconfig download complete\n\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
extern char country_code[];
|
||||||
|
int rwnx_plat_powerlimit_load_8800d80n(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
u32 *dst=NULL;
|
||||||
|
char *filename = FW_POWERLIMIT_NAME_8800D80N;
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "powerlimit file path:%s \r\n", filename);
|
||||||
|
|
||||||
|
/* load file */
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
if (size <= 0) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of cfg file\n");
|
||||||
|
dst = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
|
/* parsing the file */
|
||||||
|
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code);
|
||||||
|
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "powerlimit download complete\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#define DEF_PATCH_METHOD_VER_1 0 // deprecated
|
||||||
|
#define DEF_PATCH_METHOD_VER_2 1 // in used
|
||||||
|
|
||||||
|
void system_config_8800d80n(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
int aicwf_plat_patch_load_8800d80n(struct rwnx_hw *rwnx_hw);
|
||||||
|
int aicwf_plat_patch_table_load_8800d80n(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
void aicwf_patch_config_8800d80n(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
int aicwf_plat_rftest_load_8800d80n(struct rwnx_hw *rwnx_hw);
|
||||||
|
int aicwf_plat_rftest_exec_8800d80n(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
#if DEF_PATCH_METHOD_VER_1
|
||||||
|
int aicwf_plat_initvar_load_8800d80n(struct rwnx_hw *rwnx_hw, u32 var_base_addr);
|
||||||
|
int aicwf_plat_gain_table_load_8800d80n(struct rwnx_hw *rwnx_hw);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEF_PATCH_METHOD_VER_2
|
||||||
|
int aicwf_plat_cinit_exec_8800d80n(struct rwnx_hw *rwnx_hw);
|
||||||
|
int aicwf_plat_calib_exec_8800d80n(struct rwnx_hw *rwnx_hw);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int rwnx_plat_userconfig_load_8800d80n(struct rwnx_hw *rwnx_hw);
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
int rwnx_plat_powerlimit_load_8800d80n(struct rwnx_hw *rwnx_hw);
|
||||||
|
#endif
|
||||||
|
int aicwf_set_rf_config_8800d80n(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
|
||||||
|
|
||||||
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "rwnx_main.h"
|
#include "rwnx_main.h"
|
||||||
#include "rwnx_msg_tx.h"
|
#include "rwnx_msg_tx.h"
|
||||||
#include "reg_access.h"
|
#include "reg_access.h"
|
||||||
|
#include "aicwf_compat_8800d80x2.h"
|
||||||
|
|
||||||
#define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt"
|
#define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt"
|
||||||
#define FW_POWERLIMIT_NAME_8800D80X2 "aic_powerlimit_8800d80x2.txt"
|
#define FW_POWERLIMIT_NAME_8800D80X2 "aic_powerlimit_8800d80x2.txt"
|
||||||
@@ -40,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);
|
||||||
@@ -86,7 +88,7 @@ int rwnx_plat_powerlimit_load_8800d80x2(struct rwnx_hw *rwnx_hw)
|
|||||||
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
/* parsing the file */
|
/* parsing the file */
|
||||||
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code);
|
rwnx_plat_powerlimit_parsing((char *)dst, size);
|
||||||
|
|
||||||
rwnx_release_firmware_common(&dst);
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
|
|||||||
@@ -3047,14 +3047,18 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *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);
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, boot_argc_read_addr, &cfm);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
AICWFDBG(LOGERROR, "boot argc [0x%x] rd fail: %d\n", boot_argc_read_addr, ret);
|
AICWFDBG(LOGERROR, "boot argc [0x%x] rd fail: %d\n", boot_argc_read_addr, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
printk("boot argc %x\n", cfm.memdata);
|
AICWFDBG(LOGINFO, "issue71: boot argc=0x%x\n", cfm.memdata);
|
||||||
if (cfm.memdata & 0x10) {
|
if (cfm.memdata & 0x10) {
|
||||||
|
if (valid_out) {
|
||||||
*valid_out = 1;
|
*valid_out = 1;
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO, "issue71: boot arguments mark DPD result valid\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (chip_mcu_id) {
|
if (chip_mcu_id) {
|
||||||
@@ -3064,7 +3068,6 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
flash_size = cfm.memdata & 0xff;
|
flash_size = cfm.memdata & 0xff;
|
||||||
printk("flash size %x\n", flash_size);
|
|
||||||
if (flash_size == 0x16) {
|
if (flash_size == 0x16) {
|
||||||
dpd_info_read_addr += 0x4300000;
|
dpd_info_read_addr += 0x4300000;
|
||||||
} else if (flash_size == 0x15) {
|
} else if (flash_size == 0x15) {
|
||||||
@@ -3079,10 +3082,14 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out)
|
|||||||
AICWFDBG(LOGERROR, "dpd info [0x%x] rd fail: %d\n", dpd_info_read_addr, ret);
|
AICWFDBG(LOGERROR, "dpd info [0x%x] rd fail: %d\n", dpd_info_read_addr, ret);
|
||||||
return 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 (cfm.memdata & (1<<7)) {
|
||||||
if (valid_out) {
|
if (valid_out) {
|
||||||
*valid_out = 1;
|
*valid_out = 1;
|
||||||
}
|
}
|
||||||
|
AICWFDBG(LOGINFO, "issue71: legacy V3 flash DPD result is valid\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (testmode == FW_RFTEST_MODE) {
|
if (testmode == FW_RFTEST_MODE) {
|
||||||
@@ -3510,16 +3517,17 @@ 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 (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA
|
if (pid == USB_PRODUCT_ID_TENDA
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS3
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS3
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS5
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS5
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS6) {
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS6) {
|
||||||
filename = FW_USERCONFIG_NAME_8800DW_W311;
|
filename = FW_USERCONFIG_NAME_8800DW_W311;
|
||||||
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U2
|
} else if (pid == USB_PRODUCT_ID_TENDA_U2
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS1
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS1
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS2
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS2
|
||||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS4) {
|
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS4) {
|
||||||
filename = FW_USERCONFIG_NAME_8800DW_U2;
|
filename = FW_USERCONFIG_NAME_8800DW_U2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3666,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)
|
||||||
|
|||||||
@@ -60,3 +60,6 @@ int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw);
|
|||||||
int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id);
|
int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id);
|
||||||
#endif
|
#endif
|
||||||
void system_config_8800dc(struct rwnx_hw *rwnx_hw);
|
void system_config_8800dc(struct rwnx_hw *rwnx_hw);
|
||||||
|
int aicwf_patch_var_config_8800dc(struct rwnx_hw *rwnx_hw);
|
||||||
|
int set_bbpll_config(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,330 @@
|
|||||||
|
#include "rwnx_main.h"
|
||||||
|
#include "rwnx_msg_tx.h"
|
||||||
|
#include "reg_access.h"
|
||||||
|
#include "rwnx_platform.h"
|
||||||
|
#include "aicwf_compat_8800dln.h"
|
||||||
|
|
||||||
|
#define FW_USERCONFIG_NAME_8800DLN "aic_userconfig_8800dln.txt"
|
||||||
|
#define FW_POWERLIMIT_NAME_8800DLN "aic_powerlimit_8800dln.txt"
|
||||||
|
#define RWNX_MAC_FW_RF_BASE_NAME_8800DLN "lmacfw_rf_8800dln.bin"
|
||||||
|
#define RWNX_MAC_FW_INITVAR_NAME_8800DLN "fmacfw_initvar_8800dln.bin"
|
||||||
|
#define RWNX_MAC_FW_GAINTBL_NAME_8800DLN "fmacfw_gaintbl_8800dln.bin"
|
||||||
|
|
||||||
|
#define WF_RXGAIN_TBL_IDX_MAX 20
|
||||||
|
#define WF_RXGAIN_TBL_SIZE 256
|
||||||
|
#define WF_TXGAIN_TBL_IDX_MAX 21
|
||||||
|
#define WF_TXGAIN_TBL_SIZE 128
|
||||||
|
|
||||||
|
extern char aic_fw_path[200];
|
||||||
|
|
||||||
|
int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
|
||||||
|
char *filename);
|
||||||
|
int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw,
|
||||||
|
u32** buffer, const char *filename);
|
||||||
|
void rwnx_plat_userconfig_parsing(char *buffer, int size);
|
||||||
|
void rwnx_release_firmware_common(u32** buffer);
|
||||||
|
|
||||||
|
extern int get_adap_test(void);
|
||||||
|
|
||||||
|
typedef u32 (*array2_tbl_t)[2];
|
||||||
|
typedef u32 (*array3_tbl_t)[3];
|
||||||
|
|
||||||
|
|
||||||
|
u32 syscfg_tbl_masked_8800dln[][3] = {
|
||||||
|
// {Address, mask, value}
|
||||||
|
{0x00000000, 0x00000000, 0x00000000}, // last one
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 patch_tbl_wifisetting_8800dln[][2] =
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
//adap test
|
||||||
|
u32 adaptivity_patch_tbl_8800dln[][2] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 patch_tbl_rf_func_8800dln[][2] =
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int testmode;
|
||||||
|
extern u8 chip_id;
|
||||||
|
extern u8 chip_mcu_id;
|
||||||
|
|
||||||
|
void system_config_8800dln(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int syscfg_num;
|
||||||
|
array3_tbl_t p_syscfg_msk_tbl;
|
||||||
|
int ret, cnt;
|
||||||
|
const u32 mem_addr = 0x40500000;
|
||||||
|
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||||
|
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16);
|
||||||
|
//printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
|
||||||
|
if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL) {
|
||||||
|
chip_mcu_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chip_sub_id = (u8)(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);
|
||||||
|
|
||||||
|
syscfg_num = sizeof(syscfg_tbl_masked_8800dln) / sizeof(u32) / 3;
|
||||||
|
p_syscfg_msk_tbl = syscfg_tbl_masked_8800dln;
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||||
|
if (p_syscfg_msk_tbl[cnt][0] == 0x00000000) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = rwnx_send_dbg_mem_mask_write_req(rwnx_hw,
|
||||||
|
p_syscfg_msk_tbl[cnt][0], p_syscfg_msk_tbl[cnt][1], p_syscfg_msk_tbl[cnt][2]);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "%x mask write fail: %d\n", p_syscfg_msk_tbl[cnt][0], ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_patch_config_8800dln(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_ROM_PATCH_EN
|
||||||
|
int ret = 0;
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
//adap test
|
||||||
|
int adap_test = 0;
|
||||||
|
int adap_patch_num = 0;
|
||||||
|
|
||||||
|
adap_test = get_adap_test();
|
||||||
|
//adap test
|
||||||
|
|
||||||
|
if (testmode == 0) {
|
||||||
|
const u32 cfg_base = 0x8150;
|
||||||
|
struct dbg_mem_read_cfm cfm;
|
||||||
|
u32 wifisetting_cfg_addr;
|
||||||
|
u32 agc_cfg_addr;
|
||||||
|
u32 txgain_cfg_24g_addr;
|
||||||
|
u32 jump_tbl_addr = 0;
|
||||||
|
|
||||||
|
u32 patch_tbl_num;
|
||||||
|
|
||||||
|
//array2_tbl_t jump_tbl_base = NULL;
|
||||||
|
array2_tbl_t patch_tbl_base = NULL;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm))) {
|
||||||
|
AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", cfg_base, ret);
|
||||||
|
}
|
||||||
|
wifisetting_cfg_addr = cfm.memdata;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 4, &cfm))) {
|
||||||
|
AICWFDBG(LOGERROR, "jump_tbl base[0x%x] rd fail: %d\n", cfg_base + 4, ret);
|
||||||
|
}
|
||||||
|
jump_tbl_addr = cfm.memdata;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x10, &cfm))) {
|
||||||
|
AICWFDBG(LOGERROR, "agc_cfg base[0x%x] rd fail: %d\n", cfg_base + 0xc, ret);
|
||||||
|
}
|
||||||
|
agc_cfg_addr = cfm.memdata;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) {
|
||||||
|
AICWFDBG(LOGERROR, "txgain_cfg_24g base[0x%x] rd fail: %d\n", cfg_base + 0x10, ret);
|
||||||
|
}
|
||||||
|
txgain_cfg_24g_addr = cfm.memdata;
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "wifisetting_cfg_addr=%x, jump_tbl_addr=%x, agc_cfg_addr=%x, txgain_cfg_24g_addr=%x\n",
|
||||||
|
wifisetting_cfg_addr, jump_tbl_addr, agc_cfg_addr, txgain_cfg_24g_addr);
|
||||||
|
|
||||||
|
patch_tbl_num = sizeof(patch_tbl_wifisetting_8800dln)/sizeof(u32)/2;
|
||||||
|
patch_tbl_base = patch_tbl_wifisetting_8800dln;
|
||||||
|
for (cnt = 0; cnt < patch_tbl_num; cnt++) {
|
||||||
|
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + patch_tbl_base[cnt][0], patch_tbl_base[cnt][1]))) {
|
||||||
|
AICWFDBG(LOGERROR, "wifisetting %x write fail\n", patch_tbl_base[cnt][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//adap test
|
||||||
|
if (adap_test) {
|
||||||
|
adap_patch_num = sizeof(adaptivity_patch_tbl_8800dln)/sizeof(u32)/2;
|
||||||
|
patch_tbl_base = adaptivity_patch_tbl_8800dln;
|
||||||
|
for(cnt = 0; cnt < adap_patch_num; cnt++)
|
||||||
|
{
|
||||||
|
if((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + patch_tbl_base[cnt][0], patch_tbl_base[cnt][1]))) {
|
||||||
|
AICWFDBG(LOGERROR, "%x write fail\n", wifisetting_cfg_addr + patch_tbl_base[cnt][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//adap test
|
||||||
|
|
||||||
|
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, txgain_cfg_24g_addr, RWNX_MAC_FW_INITVAR_NAME_8800DLN);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGINFO, "load initvar bin fail: %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
u32 patch_tbl_rf_func_num = sizeof(patch_tbl_rf_func_8800dln)/sizeof(u32)/2;
|
||||||
|
for (cnt = 0; cnt < patch_tbl_rf_func_num; cnt++) {
|
||||||
|
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_rf_func_8800dln[cnt][0], patch_tbl_rf_func_8800dln[cnt][1]))) {
|
||||||
|
AICWFDBG(LOGERROR, "patch_tbl_rf_func %x write fail\n", patch_tbl_rf_func_8800dln[cnt][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int aicwf_plat_rftest_load_8800dln(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, RAM_LMAC_FW_ADDR, RWNX_MAC_FW_RF_BASE_NAME_8800DLN);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aicwf_plat_gain_table_load_8800dln(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int size, desired_size, idx, ret;
|
||||||
|
u32 *dst=NULL;
|
||||||
|
u8_l *tbl_base;
|
||||||
|
char *filename = RWNX_MAC_FW_GAINTBL_NAME_8800DLN;
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "gaintbl file path:%s\n", filename);
|
||||||
|
|
||||||
|
/* load file */
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
desired_size = WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE + WF_TXGAIN_TBL_IDX_MAX * WF_TXGAIN_TBL_SIZE;
|
||||||
|
if ((size <= 0) || (size != desired_size)) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of firmware file, desired=%d, size=%d\n", desired_size, size);
|
||||||
|
if (dst) {
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
dst = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the file on the Embedded side */
|
||||||
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
|
/* RX gain */
|
||||||
|
tbl_base = (u8_l *)dst;
|
||||||
|
for (idx = 0; idx < WF_RXGAIN_TBL_IDX_MAX; idx++) {
|
||||||
|
u16_l ofst = idx * 16;
|
||||||
|
u8_l *tbl_ptr = tbl_base + idx * WF_RXGAIN_TBL_SIZE;
|
||||||
|
ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 0, tbl_ptr, WF_RXGAIN_TBL_SIZE);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "rx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TX gain */
|
||||||
|
tbl_base = (u8_l *)dst + WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE;
|
||||||
|
for (idx = 0; idx < WF_TXGAIN_TBL_IDX_MAX; idx++) {
|
||||||
|
u16_l ofst = idx * 16;
|
||||||
|
u8_l *tbl_ptr = tbl_base + idx * WF_TXGAIN_TBL_SIZE;
|
||||||
|
ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 2, tbl_ptr, WF_TXGAIN_TBL_SIZE);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "tx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "gaintbl download complete\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aicwf_set_rf_config_8800dln(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_txpwr_lvl_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ret = rwnx_send_txpwr_lvl_adj_v2_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ret = rwnx_send_txpwr_ofst2x_v3_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (testmode == FW_NORMAL_MODE) {
|
||||||
|
aicwf_plat_gain_table_load_8800dln(rwnx_hw);
|
||||||
|
}
|
||||||
|
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int rwnx_plat_userconfig_load_8800dln(struct rwnx_hw *rwnx_hw){
|
||||||
|
int size;
|
||||||
|
u32 *dst=NULL;
|
||||||
|
char *filename = FW_USERCONFIG_NAME_8800DLN;
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
||||||
|
|
||||||
|
/* load file */
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
if (size <= 0) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
|
||||||
|
dst = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the file on the Embedded side */
|
||||||
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
|
rwnx_plat_userconfig_parsing((char *)dst, size);
|
||||||
|
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "userconfig download complete\n\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
extern char country_code[];
|
||||||
|
int rwnx_plat_powerlimit_load_8800dln(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
u32 *dst=NULL;
|
||||||
|
char *filename = FW_POWERLIMIT_NAME_8800DLN;
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "powerlimit file path:%s \r\n", filename);
|
||||||
|
|
||||||
|
/* load file */
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
if (size <= 0) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of cfg file\n");
|
||||||
|
dst = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
|
/* parsing the file */
|
||||||
|
rwnx_plat_powerlimit_parsing((char *)dst, size);
|
||||||
|
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "powerlimit download complete\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
void system_config_8800dln(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
void aicwf_patch_config_8800dln(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
int aicwf_plat_rftest_load_8800dln(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
int aicwf_plat_gain_table_load_8800dln(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
int rwnx_plat_userconfig_load_8800dln(struct rwnx_hw *rwnx_hw);
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
int rwnx_plat_powerlimit_load_8800dln(struct rwnx_hw *rwnx_hw);
|
||||||
|
#endif
|
||||||
|
int aicwf_set_rf_config_8800dln(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
|
||||||
|
|
||||||
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__
|
#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__
|
||||||
|
|
||||||
|
|
||||||
@@ -11,6 +9,7 @@
|
|||||||
#define LOGDEBUG 0x0008
|
#define LOGDEBUG 0x0008
|
||||||
#define LOGDATA 0x0010
|
#define LOGDATA 0x0010
|
||||||
#define LOGSTEER 0x0020
|
#define LOGSTEER 0x0020
|
||||||
|
#define LOGFW 0x0200
|
||||||
|
|
||||||
extern int aicwf_dbg_level;
|
extern int aicwf_dbg_level;
|
||||||
void rwnx_data_dump(char* tag, void* data, unsigned long len);
|
void rwnx_data_dump(char* tag, void* data, unsigned long len);
|
||||||
@@ -48,6 +47,3 @@ do { \
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ static int freq_to_channel(int freq)
|
|||||||
} else if (freq >= FREQ_6G_MIN && freq <= FREQ_6G_MAX) {
|
} else if (freq >= FREQ_6G_MIN && freq <= FREQ_6G_MAX) {
|
||||||
return (freq - 5950) / 5;
|
return (freq - 5950) / 5;
|
||||||
} else {
|
} else {
|
||||||
AICWFDBG(LOGERROR, MANAGER_STR"aic Unsupported frequency: %d MHz\n", freq);
|
AICWFDBG(LOGERROR, MANAGER_STR"Unsupported frequency: %d MHz\n", freq);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ void aicwf_nl_recv_msg(struct sk_buff *skb)
|
|||||||
rwnx_hook = nl_hook[band][ssid];
|
rwnx_hook = nl_hook[band][ssid];
|
||||||
|
|
||||||
if (!rwnx_hook) {
|
if (!rwnx_hook) {
|
||||||
AICWFDBG(LOGSTEER, MANAGER_STR"%s, !rwnx_hook, %d,%d\n", __func__, band, ssid);
|
AICWFDBG(LOGSTEER, MANAGER_STR"%s, search for the next rwnx_hook, %d,%d\n", __func__, band, ssid);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (rwnx_vif == NULL || rwnx_vif->up == false) {
|
if (rwnx_vif == NULL || rwnx_vif->up == false) {
|
||||||
@@ -144,7 +144,7 @@ void aicwf_nl_recv_msg(struct sk_buff *skb)
|
|||||||
rwnx_hook = nl_hook[band][ssid];
|
rwnx_hook = nl_hook[band][ssid];
|
||||||
|
|
||||||
if (!rwnx_hook) {
|
if (!rwnx_hook) {
|
||||||
AICWFDBG(LOGSTEER, MANAGER_STR"rwnx_hook is null p1.\n");
|
//AICWFDBG(LOGSTEER, MANAGER_STR"Not this driver's msg p1.\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (rwnx_vif == NULL || rwnx_vif->up == false) {
|
if (rwnx_vif == NULL || rwnx_vif->up == false) {
|
||||||
@@ -185,7 +185,7 @@ void aicwf_nl_recv_msg(struct sk_buff *skb)
|
|||||||
rwnx_hook = nl_hook[band][ssid];
|
rwnx_hook = nl_hook[band][ssid];
|
||||||
|
|
||||||
if (!rwnx_hook) {
|
if (!rwnx_hook) {
|
||||||
AICWFDBG(LOGERROR, MANAGER_STR"rwnx_hook is null p2.\n");
|
//AICWFDBG(LOGERROR, MANAGER_STR"Not this driver's msg p2.\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (rwnx_vif == NULL || rwnx_vif->up == false) {
|
if (rwnx_vif == NULL || rwnx_vif->up == false) {
|
||||||
|
|||||||
@@ -527,11 +527,7 @@ static void aicwf_sdio_bus_stop(struct device *dev)
|
|||||||
|
|
||||||
aicwf_sdio_pwrctl_timer(sdiodev, 0);
|
aicwf_sdio_pwrctl_timer(sdiodev, 0);
|
||||||
if(timer_pending(&sdiodev->rwnx_hw->p2p_alive_timer)){
|
if(timer_pending(&sdiodev->rwnx_hw->p2p_alive_timer)){
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
|
|
||||||
ret = timer_delete(&sdiodev->rwnx_hw->p2p_alive_timer);}
|
|
||||||
#else
|
|
||||||
ret = del_timer(&sdiodev->rwnx_hw->p2p_alive_timer);}
|
ret = del_timer(&sdiodev->rwnx_hw->p2p_alive_timer);}
|
||||||
#endif
|
|
||||||
sdio_dbg("%s\n",__func__);
|
sdio_dbg("%s\n",__func__);
|
||||||
if (sdiodev->pwrctl_tsk) {
|
if (sdiodev->pwrctl_tsk) {
|
||||||
complete(&sdiodev->pwrctrl_trgg);
|
complete(&sdiodev->pwrctrl_trgg);
|
||||||
@@ -1001,7 +997,8 @@ static void aicwf_sdio_bus_pwrctl(struct timer_list *t)
|
|||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
|
||||||
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data;
|
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data;
|
||||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
|
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
|
||||||
struct aic_sdio_dev *sdiodev = timer_container_of(sdiodev, t, timer);#else
|
struct aic_sdio_dev *sdiodev = timer_container_of(sdiodev, t, timer);
|
||||||
|
#else
|
||||||
struct aic_sdio_dev *sdiodev = from_timer(sdiodev, t, timer);
|
struct aic_sdio_dev *sdiodev = from_timer(sdiodev, t, timer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1085,11 +1082,7 @@ void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration)
|
|||||||
spin_lock_bh(&sdiodev->pwrctl_lock);
|
spin_lock_bh(&sdiodev->pwrctl_lock);
|
||||||
if (!duration) {
|
if (!duration) {
|
||||||
if (timer_pending(&sdiodev->timer))
|
if (timer_pending(&sdiodev->timer))
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
|
|
||||||
timer_delete_sync(&sdiodev->timer);
|
|
||||||
#else
|
|
||||||
del_timer_sync(&sdiodev->timer);
|
del_timer_sync(&sdiodev->timer);
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
sdiodev->active_duration = duration;
|
sdiodev->active_duration = duration;
|
||||||
timeout = msecs_to_jiffies(sdiodev->active_duration);
|
timeout = msecs_to_jiffies(sdiodev->active_duration);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <net/tcp.h>
|
#include <net/tcp.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
|
||||||
|
|
||||||
#define TCP_ACK_NUM 32
|
#define TCP_ACK_NUM 32
|
||||||
@@ -89,4 +90,29 @@ int filter_send_tcp_ack(struct rwnx_hw *priv, struct msg_buf *msgbuf,unsigned ch
|
|||||||
void filter_rx_tcp_ack(struct rwnx_hw *priv,unsigned char *buf, unsigned plen);
|
void filter_rx_tcp_ack(struct rwnx_hw *priv,unsigned char *buf, unsigned plen);
|
||||||
|
|
||||||
void move_tcpack_msg(struct rwnx_hw *priv, struct msg_buf * msg);
|
void move_tcpack_msg(struct rwnx_hw *priv, struct msg_buf * msg);
|
||||||
|
void intf_tcp_drop_msg(struct rwnx_hw *priv, struct msg_buf *msg);
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||||
|
void tcp_ack_timeout(unsigned long data);
|
||||||
|
#else
|
||||||
|
void tcp_ack_timeout(struct timer_list *t);
|
||||||
|
#endif
|
||||||
|
int tcp_check_quick_ack(unsigned char *buf, struct tcp_ack_msg *msg);
|
||||||
|
int tcp_check_ack(unsigned char *buf,
|
||||||
|
struct tcp_ack_msg *msg,
|
||||||
|
unsigned short *win_scale);
|
||||||
|
int tcp_ack_match(struct tcp_ack_manage *ack_m, struct tcp_ack_msg *ack_msg);
|
||||||
|
void tcp_ack_update(struct tcp_ack_manage *ack_m);
|
||||||
|
int tcp_ack_alloc_index(struct tcp_ack_manage *ack_m);
|
||||||
|
int tcp_ack_handle(struct msg_buf *new_msgbuf,
|
||||||
|
struct tcp_ack_manage *ack_m,
|
||||||
|
struct tcp_ack_info *ack_info,
|
||||||
|
struct tcp_ack_msg *ack_msg,
|
||||||
|
int type);
|
||||||
|
int tcp_ack_handle_new(struct msg_buf *new_msgbuf,
|
||||||
|
struct tcp_ack_manage *ack_m,
|
||||||
|
struct tcp_ack_info *ack_info,
|
||||||
|
struct tcp_ack_msg *ack_msg,
|
||||||
|
int type);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#define DATA_BUF_MAX 2048
|
#define DATA_BUF_MAX 2048
|
||||||
#define TXPKT_BLOCKSIZE 512
|
#define TXPKT_BLOCKSIZE 512
|
||||||
#define MAX_AGGR_TXPKT_LEN (1536*64)
|
#define MAX_AGGR_TXPKT_LEN (1536*64)
|
||||||
#define CMD_TX_TIMEOUT 2000
|
#define CMD_TX_TIMEOUT 5000
|
||||||
#define TX_ALIGNMENT 4
|
#define TX_ALIGNMENT 4
|
||||||
|
|
||||||
#ifdef CONFIG_USB_TX_AGGR
|
#ifdef CONFIG_USB_TX_AGGR
|
||||||
@@ -155,7 +155,7 @@ struct aicwf_tx_priv {
|
|||||||
#define DEFRAG_MAX_WAIT 40 //100
|
#define DEFRAG_MAX_WAIT 40 //100
|
||||||
#ifdef AICWF_RX_REORDER
|
#ifdef AICWF_RX_REORDER
|
||||||
#define MAX_REORD_RXFRAME 250
|
#define MAX_REORD_RXFRAME 250
|
||||||
#define REORDER_UPDATE_TIME 500//50
|
#define REORDER_UPDATE_TIME 50
|
||||||
#define AICWF_REORDER_WINSIZE 64
|
#define AICWF_REORDER_WINSIZE 64
|
||||||
//SN_LESS(a, b) a-b<0 is ture
|
//SN_LESS(a, b) a-b<0 is ture
|
||||||
#define SN_LESS(a, b) (((a-b)&0x800)!=0)
|
#define SN_LESS(a, b) (((a-b)&0x800)!=0)
|
||||||
@@ -307,6 +307,7 @@ void aicwf_rxframe_queue_init_2(struct rx_frame_queue *pq, int max_len);
|
|||||||
void rxbuff_free(struct rx_buff *rxbuff);
|
void rxbuff_free(struct rx_buff *rxbuff);
|
||||||
struct rx_buff *rxbuff_dequeue(struct rx_frame_queue *pq);
|
struct rx_buff *rxbuff_dequeue(struct rx_frame_queue *pq);
|
||||||
bool aicwf_rxbuff_enqueue(struct device *dev, struct rx_frame_queue *rxq, struct rx_buff *pkt);
|
bool aicwf_rxbuff_enqueue(struct device *dev, struct rx_frame_queue *rxq, struct rx_buff *pkt);
|
||||||
|
struct rx_buff *rxbuff_queue_penq(struct rx_frame_queue *pq, struct rx_buff *p);
|
||||||
extern struct aicwf_rx_buff_list aic_rx_buff_list;
|
extern struct aicwf_rx_buff_list aic_rx_buff_list;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -155,22 +155,24 @@ static void aicwf_usb_msg_rx_buf_put(struct aic_usb_dev *usb_dev, struct aicwf_u
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void rwnx_stop_sta_all_queues(struct rwnx_sta *sta, struct rwnx_hw *rwnx_hw)
|
void rwnx_stop_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw)
|
||||||
{
|
{
|
||||||
u8 tid;
|
u8 tid;
|
||||||
struct rwnx_txq *txq;
|
struct rwnx_txq *txq;
|
||||||
|
struct rwnx_sta *sta_tmp = (struct rwnx_sta *)sta;
|
||||||
for(tid=0; tid<8; tid++) {
|
for(tid=0; tid<8; tid++) {
|
||||||
txq = rwnx_txq_sta_get(sta, tid, rwnx_hw);
|
txq = rwnx_txq_sta_get(sta_tmp, tid, rwnx_hw);
|
||||||
netif_stop_subqueue(txq->ndev, txq->ndev_idx);
|
netif_stop_subqueue(txq->ndev, txq->ndev_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rwnx_wake_sta_all_queues(struct rwnx_sta *sta, struct rwnx_hw *rwnx_hw)
|
void rwnx_wake_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw)
|
||||||
{
|
{
|
||||||
u8 tid;
|
u8 tid;
|
||||||
struct rwnx_txq *txq;
|
struct rwnx_txq *txq;
|
||||||
|
struct rwnx_sta *sta_tmp = (struct rwnx_sta *)sta;
|
||||||
for(tid=0; tid<8; tid++) {
|
for(tid=0; tid<8; tid++) {
|
||||||
txq = rwnx_txq_sta_get(sta, tid, rwnx_hw);
|
txq = rwnx_txq_sta_get(sta_tmp, tid, rwnx_hw);
|
||||||
netif_wake_subqueue(txq->ndev, txq->ndev_idx);
|
netif_wake_subqueue(txq->ndev, txq->ndev_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,7 +202,7 @@ static void usb_txc_sta_flowctrl(struct aicwf_usb_buf *usb_buf, struct aic_usb_d
|
|||||||
usb_dev->rwnx_hw->sta_flowctrl[sta_idx].flowctrl) {
|
usb_dev->rwnx_hw->sta_flowctrl[sta_idx].flowctrl) {
|
||||||
//AICWFDBG(LOGDEBUG, "sta 0x%x:0x%x, %d pending %d, wake\n", sta->mac_addr[4], sta->mac_addr[5], sta->sta_idx, atomic_read(&usb_dev->rwnx_hw->sta_flowctrl[sta_idx].tx_pending_cnt));
|
//AICWFDBG(LOGDEBUG, "sta 0x%x:0x%x, %d pending %d, wake\n", sta->mac_addr[4], sta->mac_addr[5], sta->sta_idx, atomic_read(&usb_dev->rwnx_hw->sta_flowctrl[sta_idx].tx_pending_cnt));
|
||||||
if(!usb_dev->tbusy)
|
if(!usb_dev->tbusy)
|
||||||
rwnx_wake_sta_all_queues(sta, usb_dev->rwnx_hw);
|
rwnx_wake_sta_all_queues((void *)sta, usb_dev->rwnx_hw);
|
||||||
usb_dev->rwnx_hw->sta_flowctrl[sta_idx].flowctrl = 0;
|
usb_dev->rwnx_hw->sta_flowctrl[sta_idx].flowctrl = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,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);
|
||||||
@@ -383,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);
|
||||||
@@ -781,7 +759,7 @@ static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev,
|
|||||||
aicwf_prealloc_rxbuff_free(rx_buff, &usb_dev->rx_priv->rxbuff_lock);
|
aicwf_prealloc_rxbuff_free(rx_buff, &usb_dev->rx_priv->rxbuff_lock);
|
||||||
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
||||||
|
|
||||||
msleep(100);
|
mdelay(100);
|
||||||
return -1;
|
return -1;
|
||||||
}else{
|
}else{
|
||||||
atomic_inc(&rx_urb_cnt);
|
atomic_inc(&rx_urb_cnt);
|
||||||
@@ -840,7 +818,7 @@ static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev,
|
|||||||
usb_buf->skb = NULL;
|
usb_buf->skb = NULL;
|
||||||
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
||||||
|
|
||||||
msleep(100);
|
mdelay(100);
|
||||||
return -1;
|
return -1;
|
||||||
}else{
|
}else{
|
||||||
atomic_inc(&rx_urb_cnt);
|
atomic_inc(&rx_urb_cnt);
|
||||||
@@ -913,7 +891,7 @@ static int aicwf_usb_submit_msg_rx_urb(struct aic_usb_dev *usb_dev,
|
|||||||
usb_buf->skb = NULL;
|
usb_buf->skb = NULL;
|
||||||
aicwf_usb_msg_rx_buf_put(usb_dev, usb_buf);
|
aicwf_usb_msg_rx_buf_put(usb_dev, usb_buf);
|
||||||
|
|
||||||
msleep(100);
|
mdelay(100);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1214,9 +1192,6 @@ fail:
|
|||||||
usb_buf->skb = NULL;
|
usb_buf->skb = NULL;
|
||||||
aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf,
|
aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf,
|
||||||
&usb_dev->tx_free_count, &usb_dev->tx_free_lock);
|
&usb_dev->tx_free_count, &usb_dev->tx_free_lock);
|
||||||
if (ret == -ENODEV) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1677,7 +1652,7 @@ static void usb_tx_flow_ctrl(struct rwnx_txhdr *txhdr, struct aic_usb_dev *usb_d
|
|||||||
rwnx_hw->sta_flowctrl[sta_idx].flowctrl) {
|
rwnx_hw->sta_flowctrl[sta_idx].flowctrl) {
|
||||||
//AICWFDBG(LOGDEBUG, "sta 0x%x:0x%x, %d pending %d, stop\n", sta->mac_addr[4], sta->mac_addr[5], sta->sta_idx, atomic_read(&rwnx_hw->sta_flowctrl[sta_idx].tx_pending_cnt));
|
//AICWFDBG(LOGDEBUG, "sta 0x%x:0x%x, %d pending %d, stop\n", sta->mac_addr[4], sta->mac_addr[5], sta->sta_idx, atomic_read(&rwnx_hw->sta_flowctrl[sta_idx].tx_pending_cnt));
|
||||||
if(!usb_dev->tbusy)
|
if(!usb_dev->tbusy)
|
||||||
rwnx_stop_sta_all_queues(sta, usb_dev->rwnx_hw);
|
rwnx_stop_sta_all_queues((void *)sta, usb_dev->rwnx_hw);
|
||||||
rwnx_hw->sta_flowctrl[sta_idx].flowctrl = 1;
|
rwnx_hw->sta_flowctrl[sta_idx].flowctrl = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1903,15 +1878,14 @@ static int aicwf_usb_bus_start(struct device *dev)
|
|||||||
aicwf_usb_state_change(usb_dev, USB_UP_ST);
|
aicwf_usb_state_change(usb_dev, USB_UP_ST);
|
||||||
|
|
||||||
usb_dev->rx_prepare_ready = false;
|
usb_dev->rx_prepare_ready = false;
|
||||||
|
aicwf_usb_rx_prepare(usb_dev);
|
||||||
aicwf_usb_tx_prepare(usb_dev);
|
aicwf_usb_tx_prepare(usb_dev);
|
||||||
#ifdef CONFIG_USB_MSG_IN_EP
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
if(usb_dev->msg_in_pipe){
|
if(usb_dev->msg_in_pipe){
|
||||||
aicwf_usb_msg_rx_prepare(usb_dev);
|
aicwf_usb_msg_rx_prepare(usb_dev);
|
||||||
} else {
|
|
||||||
aicwf_usb_rx_prepare(usb_dev);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(!usb_dev->msg_in_pipe && !usb_dev->rx_prepare_ready){
|
if(!usb_dev->rx_prepare_ready){
|
||||||
AICWFDBG(LOGERROR, "%s rx prepare fail\r\n", __func__);
|
AICWFDBG(LOGERROR, "%s rx prepare fail\r\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}else{
|
}else{
|
||||||
@@ -1981,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
|
||||||
}
|
}
|
||||||
@@ -2154,12 +2124,13 @@ static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *in
|
|||||||
AICWFDBG(LOGERROR, "AIC8800DC change to AIC8800DW\n");
|
AICWFDBG(LOGERROR, "AIC8800DC change to AIC8800DW\n");
|
||||||
usb_dev->chipid = PRODUCT_ID_AIC8800DW;
|
usb_dev->chipid = PRODUCT_ID_AIC8800DW;
|
||||||
}else if (usb_dev->chipid == PRODUCT_ID_AIC8800DW) {
|
}else if (usb_dev->chipid == PRODUCT_ID_AIC8800DW) {
|
||||||
AICWFDBG(LOGINFO, "AIC8800DW\n");}
|
AICWFDBG(LOGINFO, "AIC8800DW\n");
|
||||||
else if (usb_dev->chipid == PRODUCT_ID_AIC8800D81) {
|
} else if (usb_dev->chipid == PRODUCT_ID_AIC8800D80N) {
|
||||||
AICWFDBG(LOGINFO, "AIC8800D80\n");
|
AICWFDBG(LOGERROR, "AIC8800D80N change to AIC8800D80WN\n");
|
||||||
} else if(usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 ||
|
} else if (usb_dev->chipid == PRODUCT_ID_AIC8800DLN) {
|
||||||
usb_dev->chipid == PRODUCT_ID_AIC8800D89X2 ||
|
AICWFDBG(LOGERROR, "AIC8800DLN change to AIC8800DWN\n");
|
||||||
usb_dev->chipid == PRODUCT_ID_AIC8800D81){
|
}else if(usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 ||
|
||||||
|
usb_dev->chipid == PRODUCT_ID_AIC8800D89X2){
|
||||||
//TODO
|
//TODO
|
||||||
}else{
|
}else{
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
@@ -2342,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
|
||||||
@@ -2356,11 +2328,13 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid
|
|||||||
return 0;
|
return 0;
|
||||||
}else if(pid == USB_PRODUCT_ID_AIC8800D81 || pid == USB_PRODUCT_ID_AIC8800D41
|
}else if(pid == USB_PRODUCT_ID_AIC8800D81 || pid == USB_PRODUCT_ID_AIC8800D41
|
||||||
|| pid == USB_PRODUCT_ID_TENDA_U11 || pid == USB_PRODUCT_ID_TENDA_U11_PRO
|
|| pid == USB_PRODUCT_ID_TENDA_U11 || pid == USB_PRODUCT_ID_TENDA_U11_PRO
|
||||||
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS1 || pid == USB_PRODUCT_ID_AIC8800M80_CUS2
|
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS0 || pid == USB_PRODUCT_ID_AIC8800M80_CUS1
|
||||||
|
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS2
|
||||||
|| 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_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__);
|
||||||
@@ -2393,7 +2367,23 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid
|
|||||||
}
|
}
|
||||||
AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__);
|
AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}else{
|
} else if ((pid == USB_PRODUCT_ID_AIC8800D80N) ||
|
||||||
|
(pid == USB_PRODUCT_ID_AIC8800D80LN) ||
|
||||||
|
(pid == USB_PRODUCT_ID_AIC8800D80WN) ||
|
||||||
|
(pid == USB_PRODUCT_ID_AIC8800D40N) ||
|
||||||
|
(pid == USB_PRODUCT_ID_AIC8800D40LN) ||
|
||||||
|
(pid == USB_PRODUCT_ID_AIC8800D40WN)) {
|
||||||
|
usb_dev->chipid = PRODUCT_ID_AIC8800D80N;
|
||||||
|
aicwf_usb_rx_aggr = true;
|
||||||
|
AICWFDBG(LOGINFO, "%s USE AIC8800D80N\r\n", __func__);
|
||||||
|
return 0;
|
||||||
|
} else if ((pid == USB_PRODUCT_ID_AIC8800DLN) ||
|
||||||
|
(pid == USB_PRODUCT_ID_AIC8800DWN)) {
|
||||||
|
usb_dev->chipid = PRODUCT_ID_AIC8800DLN;
|
||||||
|
aicwf_usb_rx_aggr = true;
|
||||||
|
AICWFDBG(LOGINFO, "%s USE AIC8800DLN\r\n", __func__);
|
||||||
|
return 0;
|
||||||
|
} else{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2457,9 +2447,6 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i
|
|||||||
usb_dev->dev = &usb->dev;
|
usb_dev->dev = &usb->dev;
|
||||||
usb_set_intfdata(intf, usb_dev);
|
usb_set_intfdata(intf, usb_dev);
|
||||||
|
|
||||||
usb_dev->vid = id->idVendor;
|
|
||||||
usb_dev->pid = id->idProduct;
|
|
||||||
|
|
||||||
ret = aicwf_usb_chipmatch(usb_dev, id->idVendor, id->idProduct);
|
ret = aicwf_usb_chipmatch(usb_dev, id->idVendor, id->idProduct);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -2531,9 +2518,6 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i
|
|||||||
AICWFDBG(LOGERROR, "aicwf_rwnx_usb_platform_init err %d\n", ret);
|
AICWFDBG(LOGERROR, "aicwf_rwnx_usb_platform_init err %d\n", ret);
|
||||||
goto out_free_bus;
|
goto out_free_bus;
|
||||||
}
|
}
|
||||||
if(usb_dev->msg_in_pipe){
|
|
||||||
aicwf_usb_rx_prepare(usb_dev);
|
|
||||||
}
|
|
||||||
aicwf_hostif_ready();
|
aicwf_hostif_ready();
|
||||||
|
|
||||||
#ifdef CONFIG_GPIO_WAKEUP
|
#ifdef CONFIG_GPIO_WAKEUP
|
||||||
@@ -2602,7 +2586,9 @@ static int aicwf_usb_suspend(struct usb_interface *intf, pm_message_t state)
|
|||||||
|
|
||||||
AICWFDBG(LOGINFO, "%s enter\r\n", __func__);
|
AICWFDBG(LOGINFO, "%s enter\r\n", __func__);
|
||||||
#ifdef CONFIG_WOWLAN
|
#ifdef CONFIG_WOWLAN
|
||||||
|
#ifndef ANDROID_PLATFORM
|
||||||
rwnx_send_dummy_reboot(usb_dev->rwnx_hw);
|
rwnx_send_dummy_reboot(usb_dev->rwnx_hw);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) {
|
list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) {
|
||||||
if (rwnx_vif->ndev){
|
if (rwnx_vif->ndev){
|
||||||
@@ -2634,6 +2620,7 @@ static int aicwf_usb_resume(struct usb_interface *intf)
|
|||||||
|
|
||||||
if (usb_dev->state != USB_UP_ST){
|
if (usb_dev->state != USB_UP_ST){
|
||||||
aicwf_bus_start(usb_dev->bus_if);
|
aicwf_bus_start(usb_dev->bus_if);
|
||||||
|
g_rwnx_plat->wait_disconnect_cb = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) {
|
list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) {
|
||||||
@@ -2641,9 +2628,6 @@ static int aicwf_usb_resume(struct usb_interface *intf)
|
|||||||
netif_tx_wake_all_queues(rwnx_vif->ndev);
|
netif_tx_wake_all_queues(rwnx_vif->ndev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(usb_dev->msg_in_pipe){
|
|
||||||
aicwf_usb_rx_prepare(usb_dev);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2660,11 +2644,20 @@ 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)},
|
||||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D81X2, 0xff, 0xff, 0xff)},
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D81X2, 0xff, 0xff, 0xff)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D89X2)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D89X2)},
|
||||||
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80N, 0xff, 0xff, 0xff)},
|
||||||
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80LN, 0xff, 0xff, 0xff)},
|
||||||
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80WN, 0xff, 0xff, 0xff)},
|
||||||
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D40N, 0xff, 0xff, 0xff)},
|
||||||
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D40LN, 0xff, 0xff, 0xff)},
|
||||||
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D40WN, 0xff, 0xff, 0xff)},
|
||||||
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800DLN, 0xff, 0xff, 0xff)},
|
||||||
|
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800DWN, 0xff, 0xff, 0xff)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA)},
|
{USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U2)},
|
{USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U2)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U11)},
|
{USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U11)},
|
||||||
@@ -2676,6 +2669,7 @@ static struct usb_device_id aicwf_usb_id_table[] = {
|
|||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS4)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS4)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS5)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS5)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS6)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS6)},
|
||||||
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS0)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS1)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS1)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS2)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS2)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS3)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS3)},
|
||||||
@@ -2685,6 +2679,8 @@ static struct usb_device_id aicwf_usb_id_table[] = {
|
|||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS7)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS7)},
|
||||||
{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_AND_INTERFACE_INFO(USB_VENDOR_ID_TP, USB_PRODUCT_ID_TP, 0xff, 0xff, 0xff)},
|
||||||
#endif
|
#endif
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,11 +16,17 @@
|
|||||||
|
|
||||||
/* USB Device ID */
|
/* USB Device ID */
|
||||||
#define USB_VENDOR_ID_AIC 0xA69C
|
#define USB_VENDOR_ID_AIC 0xA69C
|
||||||
#define USB_VENDOR_ID_AIC_V2 0x368B
|
#define USB_VENDOR_ID_TP 0x2357
|
||||||
#define USB_VENDOR_ID_TENDA 0x2604
|
#define USB_VENDOR_ID_TENDA 0x2604
|
||||||
#define USB_VENDOR_ID_TENDA_V2 0x3625
|
#define USB_VENDOR_ID_TENDA_V2 0x3625
|
||||||
|
#define USB_VENDOR_ID_AIC_V2 0x368B
|
||||||
|
|
||||||
|
#define USB_PRODUCT_ID_TP 0x014e
|
||||||
|
#define USB_PRODUCT_ID_MERCURY 0x014b
|
||||||
|
#define USB_PRODUCT_ID_FAST 0x014f
|
||||||
|
|
||||||
|
#define USB_PRODUCT_ID_TENDA_U11 0x001f
|
||||||
|
#define USB_PRODUCT_ID_TENDA_U11_PRO 0x0020
|
||||||
#ifndef CONFIG_USB_BT
|
#ifndef CONFIG_USB_BT
|
||||||
#define USB_PRODUCT_ID_AIC8800 0x8800
|
#define USB_PRODUCT_ID_AIC8800 0x8800
|
||||||
#define USB_PRODUCT_ID_AIC8801 0x8801
|
#define USB_PRODUCT_ID_AIC8801 0x8801
|
||||||
@@ -32,15 +38,22 @@
|
|||||||
#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
|
||||||
#define USB_PRODUCT_ID_AIC8800D81X2 0x8d91
|
#define USB_PRODUCT_ID_AIC8800D81X2 0x8d91
|
||||||
#define USB_PRODUCT_ID_AIC8800D89X2 0x8d99
|
#define USB_PRODUCT_ID_AIC8800D89X2 0x8d99
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D80N 0x8d45
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D80LN 0x8d46
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D80WN 0x8d47
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D40N 0x8d48
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D40LN 0x8d49
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D40WN 0x8d4a
|
||||||
|
#define USB_PRODUCT_ID_AIC8800DWN 0x8870
|
||||||
|
#define USB_PRODUCT_ID_AIC8800DLN 0x8871
|
||||||
#define USB_PRODUCT_ID_TENDA 0x0013
|
#define USB_PRODUCT_ID_TENDA 0x0013
|
||||||
#define USB_PRODUCT_ID_TENDA_U2 0x0014
|
#define USB_PRODUCT_ID_TENDA_U2 0x0014
|
||||||
#define USB_PRODUCT_ID_TENDA_U11 0x001f
|
|
||||||
#define USB_PRODUCT_ID_TENDA_U11_PRO 0x0020
|
|
||||||
#define USB_PRODUCT_ID_TENDA_TX1U_NANO 0x0110
|
#define USB_PRODUCT_ID_TENDA_TX1U_NANO 0x0110
|
||||||
#define USB_PRODUCT_ID_AIC8800FC_CUS1 0x88df
|
#define USB_PRODUCT_ID_AIC8800FC_CUS1 0x88df
|
||||||
#define USB_PRODUCT_ID_AIC8800FC_CUS2 0x88E0
|
#define USB_PRODUCT_ID_AIC8800FC_CUS2 0x88E0
|
||||||
@@ -49,6 +62,7 @@
|
|||||||
#define USB_PRODUCT_ID_AIC8800FC_CUS5 0x88E3
|
#define USB_PRODUCT_ID_AIC8800FC_CUS5 0x88E3
|
||||||
#define USB_PRODUCT_ID_AIC8800FC_CUS6 0x88E5
|
#define USB_PRODUCT_ID_AIC8800FC_CUS6 0x88E5
|
||||||
|
|
||||||
|
#define USB_PRODUCT_ID_AIC8800M80_CUS0 0x8D84
|
||||||
#define USB_PRODUCT_ID_AIC8800M80_CUS1 0x8D83
|
#define USB_PRODUCT_ID_AIC8800M80_CUS1 0x8D83
|
||||||
#define USB_PRODUCT_ID_AIC8800M80_CUS2 0x8D85
|
#define USB_PRODUCT_ID_AIC8800M80_CUS2 0x8D85
|
||||||
#define USB_PRODUCT_ID_AIC8800M80_CUS3 0x8D86
|
#define USB_PRODUCT_ID_AIC8800M80_CUS3 0x8D86
|
||||||
@@ -64,6 +78,8 @@ enum AICWF_IC{
|
|||||||
PRODUCT_ID_AIC8801 = 0,
|
PRODUCT_ID_AIC8801 = 0,
|
||||||
PRODUCT_ID_AIC8800DC,
|
PRODUCT_ID_AIC8800DC,
|
||||||
PRODUCT_ID_AIC8800DW,
|
PRODUCT_ID_AIC8800DW,
|
||||||
|
PRODUCT_ID_AIC8800DLN,
|
||||||
|
PRODUCT_ID_AIC8800D80N,
|
||||||
PRODUCT_ID_AIC8800D81,
|
PRODUCT_ID_AIC8800D81,
|
||||||
PRODUCT_ID_AIC8800D81X2,
|
PRODUCT_ID_AIC8800D81X2,
|
||||||
PRODUCT_ID_AIC8800D89X2
|
PRODUCT_ID_AIC8800D89X2
|
||||||
@@ -78,7 +94,7 @@ enum AICWF_IC{
|
|||||||
#define TXQLEN (2048*4)
|
#define TXQLEN (2048*4)
|
||||||
#define AICWF_USB_TX_URBS (50)
|
#define AICWF_USB_TX_URBS (50)
|
||||||
#else
|
#else
|
||||||
#define AICWF_USB_TX_URBS 50//(100)
|
#define AICWF_USB_TX_URBS 200//(100)
|
||||||
#endif
|
#endif
|
||||||
#define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4)//25%
|
#define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4)//25%
|
||||||
#define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3)//75%
|
#define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3)//75%
|
||||||
@@ -202,8 +218,6 @@ struct aic_usb_dev {
|
|||||||
#endif
|
#endif
|
||||||
u16 chipid;
|
u16 chipid;
|
||||||
bool tbusy;
|
bool tbusy;
|
||||||
u16_l vid;
|
|
||||||
u16_l pid;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void aicwf_usb_exit(void);
|
extern void aicwf_usb_exit(void);
|
||||||
@@ -214,7 +228,9 @@ int usb_msg_busrx_thread(void *data);
|
|||||||
#endif
|
#endif
|
||||||
int usb_bustx_thread(void *data);
|
int usb_bustx_thread(void *data);
|
||||||
int usb_busrx_thread(void *data);
|
int usb_busrx_thread(void *data);
|
||||||
|
void rwnx_stop_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw);
|
||||||
|
void rwnx_wake_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw);
|
||||||
|
void aicwf_usb_cancel_all_urbs(struct aic_usb_dev *usb_dev);
|
||||||
|
|
||||||
extern void aicwf_hostif_ready(void);
|
extern void aicwf_hostif_ready(void);
|
||||||
|
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ static char *aicwf_get_iwe_stream_mac_addr(struct rwnx_hw* rwnx_hw,
|
|||||||
iwe->cmd = SIOCGIWAP;
|
iwe->cmd = SIOCGIWAP;
|
||||||
iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
|
|
||||||
if(scan_re->bss && &scan_re->bss->bssid[0]){
|
if(scan_re->bss){
|
||||||
memcpy(iwe->u.ap_addr.sa_data, scan_re->bss->bssid, ETH_ALEN);
|
memcpy(iwe->u.ap_addr.sa_data, scan_re->bss->bssid, ETH_ALEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,8 +616,10 @@ static inline char *aicwf_get_iwe_stream_rate(struct rwnx_hw* rwnx_hw,
|
|||||||
u16 vht_data_rate = 0;
|
u16 vht_data_rate = 0;
|
||||||
|
|
||||||
u16 he_cap = false;
|
u16 he_cap = false;
|
||||||
u8 he_ch_width_set = 0;
|
|
||||||
u8 he_bw = 0;
|
u8 he_bw = 0;
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)|| defined(CONFIG_HE_FOR_OLD_KERNEL)
|
||||||
|
u8 he_ch_width_set = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* parsing HT_CAP_IE */
|
/* parsing HT_CAP_IE */
|
||||||
ie_content = NULL;
|
ie_content = NULL;
|
||||||
|
|||||||
@@ -8,4 +8,6 @@ struct scanu_result_wext{
|
|||||||
|
|
||||||
void aicwf_set_wireless_ext( struct net_device *ndev, struct rwnx_hw *rwnx_hw);
|
void aicwf_set_wireless_ext( struct net_device *ndev, struct rwnx_hw *rwnx_hw);
|
||||||
void aicwf_scan_complete_event(struct net_device *dev);
|
void aicwf_scan_complete_event(struct net_device *dev);
|
||||||
|
int aic_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len);
|
||||||
|
u8 aicwf_get_is_wps_ie(u8 *ie_ptr, uint *wps_ielen);
|
||||||
|
|
||||||
|
|||||||
@@ -413,6 +413,13 @@ enum mm_msg_tag
|
|||||||
MM_SET_TXPWR_PER_STA_REQ,
|
MM_SET_TXPWR_PER_STA_REQ,
|
||||||
MM_SET_TXPWR_PER_STA_CFM,
|
MM_SET_TXPWR_PER_STA_CFM,
|
||||||
|
|
||||||
|
MM_GET_STATISTIC_REQ,
|
||||||
|
MM_GET_STATISTIC_CFM,
|
||||||
|
|
||||||
|
MM_VENDOR_SWCONFIG_IND,
|
||||||
|
MM_FW_PANIC_IND,
|
||||||
|
MM_FW_ASSERT_IND,
|
||||||
|
|
||||||
/// MAX number of messages
|
/// MAX number of messages
|
||||||
MM_MAX,
|
MM_MAX,
|
||||||
};
|
};
|
||||||
@@ -892,6 +899,7 @@ struct mm_ba_add_cfm
|
|||||||
u8_l tid;
|
u8_l tid;
|
||||||
/// Status of ba establishment
|
/// Status of ba establishment
|
||||||
u8_l status;
|
u8_l status;
|
||||||
|
u8_l alligned;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Structure containing the parameters of the @ref MM_BA_DEL_REQ message.
|
/// Structure containing the parameters of the @ref MM_BA_DEL_REQ message.
|
||||||
@@ -1345,6 +1353,12 @@ struct mm_get_sta_info_req
|
|||||||
u8_l sta_idx;
|
u8_l sta_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mm_get_sta_info_compat_req
|
||||||
|
{
|
||||||
|
u8_l sta_idx;
|
||||||
|
char pattern[3];
|
||||||
|
};
|
||||||
|
|
||||||
struct mm_get_sta_info_cfm
|
struct mm_get_sta_info_cfm
|
||||||
{
|
{
|
||||||
u32_l rate_info;
|
u32_l rate_info;
|
||||||
@@ -1412,6 +1426,12 @@ typedef struct
|
|||||||
s8_l pwrlvl_adj_tbl_5g[6];
|
s8_l pwrlvl_adj_tbl_5g[6];
|
||||||
} txpwr_lvl_adj_conf_t;
|
} txpwr_lvl_adj_conf_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u8_l enable;
|
||||||
|
s8_l pwrlvl_adj_tbl_2g4[3];
|
||||||
|
} txpwr_lvl_adj_conf_v2_t;
|
||||||
|
|
||||||
struct mm_set_txpwr_lvl_req
|
struct mm_set_txpwr_lvl_req
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
@@ -1424,7 +1444,10 @@ struct mm_set_txpwr_lvl_req
|
|||||||
|
|
||||||
struct mm_set_txpwr_lvl_adj_req
|
struct mm_set_txpwr_lvl_adj_req
|
||||||
{
|
{
|
||||||
|
union {
|
||||||
txpwr_lvl_adj_conf_t txpwr_lvl_adj;
|
txpwr_lvl_adj_conf_t txpwr_lvl_adj;
|
||||||
|
txpwr_lvl_adj_conf_v2_t txpwr_lvl_adj_v2;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -1538,12 +1561,33 @@ typedef struct
|
|||||||
s8_l pwrofst2x_tbl_6g_ant1[15];
|
s8_l pwrofst2x_tbl_6g_ant1[15];
|
||||||
} txpwr_ofst2x_conf_v2_t;
|
} txpwr_ofst2x_conf_v2_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pwrofst2x_tbl_2g4[3][3]:
|
||||||
|
* +---------------+----------+----------+----------+
|
||||||
|
* | RateTyp\ChGrp | CH_1_4 | CH_5_9 | CH_10_13 |
|
||||||
|
* +---------------+----------+----------+----------+
|
||||||
|
* | DSSS | [0][0] | [0][1] | [0][2] |
|
||||||
|
* +---------------+----------+----------+----------+
|
||||||
|
* | OFDM_HIGHRATE | [1][0] | [1][1] | [1][2] |
|
||||||
|
* +---------------+----------+----------+----------+
|
||||||
|
* | OFDM_LOWRATE | [2][0] | [2][1] | [2][2] |
|
||||||
|
* +---------------+----------+----------+----------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u8_l enable;
|
||||||
|
s8_l pwrofst2x_tbl_2g4[3][3];
|
||||||
|
u8_l RESERVED[2];
|
||||||
|
} txpwr_ofst2x_conf_v3_t;
|
||||||
|
|
||||||
struct mm_set_txpwr_ofst_req
|
struct mm_set_txpwr_ofst_req
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
txpwr_ofst_conf_t txpwr_ofst;
|
txpwr_ofst_conf_t txpwr_ofst;
|
||||||
txpwr_ofst2x_conf_t txpwr_ofst2x;
|
txpwr_ofst2x_conf_t txpwr_ofst2x;
|
||||||
txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2;
|
txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2;
|
||||||
|
txpwr_ofst2x_conf_v3_t txpwr_ofst2x_v3;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1664,6 +1708,18 @@ struct mm_csa_traffic_ind
|
|||||||
bool_l enable;
|
bool_l enable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fw_panic_info_ind
|
||||||
|
{
|
||||||
|
uint32_t len;
|
||||||
|
uint8_t info[384];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fw_assert_info_ind
|
||||||
|
{
|
||||||
|
uint32_t len;
|
||||||
|
uint8_t info[384];
|
||||||
|
};
|
||||||
|
|
||||||
/// Structure containing the parameters of the @ref MM_MU_GROUP_UPDATE_REQ message.
|
/// Structure containing the parameters of the @ref MM_MU_GROUP_UPDATE_REQ message.
|
||||||
/// Size allocated for the structure depends of the number of group
|
/// Size allocated for the structure depends of the number of group
|
||||||
struct mm_mu_group_update_req
|
struct mm_mu_group_update_req
|
||||||
@@ -2038,6 +2094,7 @@ struct me_sta_add_cfm
|
|||||||
u8_l status;
|
u8_l status;
|
||||||
/// PM state of the station
|
/// PM state of the station
|
||||||
u8_l pm_state;
|
u8_l pm_state;
|
||||||
|
u8_l alligned;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Structure containing the parameters of the @ref ME_STA_DEL_REQ message.
|
/// Structure containing the parameters of the @ref ME_STA_DEL_REQ message.
|
||||||
@@ -3463,37 +3520,4 @@ struct mm_set_wakeup_info_req {
|
|||||||
u16_l length;
|
u16_l length;
|
||||||
u8_l mask_and_pattern[];
|
u8_l mask_and_pattern[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dbg_pwm_init_req
|
|
||||||
{
|
|
||||||
/// PWM_CHANNEL_GPIO
|
|
||||||
u8 pwm_gpidx;
|
|
||||||
/// 0 normal 1 breath
|
|
||||||
u8 mode;
|
|
||||||
/// 0 config only 1 run after config
|
|
||||||
u8 run;
|
|
||||||
u32 tmr_cnt;
|
|
||||||
u32 dty_cnt;
|
|
||||||
u32 step_val;
|
|
||||||
/// 0 disable 1 enable
|
|
||||||
u8 gpio_en;
|
|
||||||
/// 0 input 1 output
|
|
||||||
u8 gpio_dir;
|
|
||||||
/// 0 low 1 high
|
|
||||||
u8 gpio_val;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dbg_pwm_deinit_req
|
|
||||||
{
|
|
||||||
/// PWM_CHANNEL_GPIO
|
|
||||||
u8 pwm_gpidx;
|
|
||||||
/// 0 disable 1 enable
|
|
||||||
u8 gpio_en;
|
|
||||||
/// 0 input 1 output
|
|
||||||
u8 gpio_dir;
|
|
||||||
/// 0 low 1 high
|
|
||||||
u8 gpio_val;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // LMAC_MSG_H_
|
#endif // LMAC_MSG_H_
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -139,9 +139,13 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
|||||||
#endif
|
#endif
|
||||||
if(cmd->e2a_msg != NULL) {
|
if(cmd->e2a_msg != NULL) {
|
||||||
do {
|
do {
|
||||||
if(cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED)
|
|
||||||
break;
|
|
||||||
spin_lock_bh(&cmd_mgr->lock);
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
if(cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
|
||||||
|
AICWFDBG(LOGERROR, "cmd queue crashed\n");
|
||||||
|
cmd->result = -EPIPE;
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
return -EPIPE;
|
||||||
|
}
|
||||||
empty = list_empty(&cmd_mgr->cmds);
|
empty = list_empty(&cmd_mgr->cmds);
|
||||||
if(!empty) {
|
if(!empty) {
|
||||||
spin_unlock_bh(&cmd_mgr->lock);
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
@@ -156,15 +160,13 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
|||||||
} while(!empty);//wait for cmd queue empty
|
} while(!empty);//wait for cmd queue empty
|
||||||
} else {
|
} else {
|
||||||
spin_lock_bh(&cmd_mgr->lock);
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
|
if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
|
||||||
printk(KERN_CRIT"cmd queue crashed\n");
|
printk(KERN_CRIT"cmd queue crashed\n");
|
||||||
cmd->result = -EPIPE;
|
cmd->result = -EPIPE;
|
||||||
spin_unlock_bh(&cmd_mgr->lock);
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_RWNX_FHOST
|
#ifndef CONFIG_RWNX_FHOST
|
||||||
if (!list_empty(&cmd_mgr->cmds)) {
|
if (!list_empty(&cmd_mgr->cmds)) {
|
||||||
@@ -221,8 +223,9 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
|||||||
//printk("defer push: tkn=%d\r\n", cmd->tkn);
|
//printk("defer push: tkn=%d\r\n", cmd->tkn);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_bh(&cmd_mgr->lock);
|
//spin_unlock_bh(&cmd_mgr->lock);
|
||||||
if (!defer_push) {
|
if (!defer_push) {
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
AICWFDBG(LOGTRACE, "queue:id=%x, param_len=%u\n",cmd->a2e_msg->id, cmd->a2e_msg->param_len);
|
AICWFDBG(LOGTRACE, "queue:id=%x, param_len=%u\n",cmd->a2e_msg->id, cmd->a2e_msg->param_len);
|
||||||
|
|
||||||
#ifdef AICWF_SDIO_SUPPORT
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
@@ -234,8 +237,11 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
|||||||
|
|
||||||
kfree(cmd->a2e_msg);
|
kfree(cmd->a2e_msg);
|
||||||
} else {
|
} else {
|
||||||
if(cmd_mgr->queue_sz <= 1){
|
if(cmd_mgr->queue_sz <= 1) {
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
WAKE_CMD_WORK(cmd_mgr);
|
WAKE_CMD_WORK(cmd_mgr);
|
||||||
|
} else {
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -559,7 +565,6 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len)
|
|||||||
{
|
{
|
||||||
u8 *buffer = NULL;
|
u8 *buffer = NULL;
|
||||||
u16 index = 0;
|
u16 index = 0;
|
||||||
int ret = 0;
|
|
||||||
#ifdef AICWF_SDIO_SUPPORT
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev;
|
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev;
|
||||||
struct aicwf_bus *bus = sdiodev->bus_if;
|
struct aicwf_bus *bus = sdiodev->bus_if;
|
||||||
@@ -594,9 +599,6 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len)
|
|||||||
index += 2;
|
index += 2;
|
||||||
memcpy(&buffer[index], (u8 *)msg->param, msg->param_len);
|
memcpy(&buffer[index], (u8 *)msg->param, msg->param_len);
|
||||||
|
|
||||||
ret = aicwf_bus_txmsg(bus, buffer, len + 8);
|
aicwf_bus_txmsg(bus, buffer, len + 8);
|
||||||
if (ret == -EIO) {
|
|
||||||
ret = aicwf_bus_txmsg(bus, buffer, len + 8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,5 +116,6 @@ void rwnx_cmd_mgr_init(struct rwnx_cmd_mgr *cmd_mgr);
|
|||||||
void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr);
|
void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr);
|
||||||
int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd);
|
int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd);
|
||||||
void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len);
|
void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len);
|
||||||
|
void cmd_mgr_task_process(struct work_struct *work);
|
||||||
|
|
||||||
#endif /* _RWNX_CMDS_H_ */
|
#endif /* _RWNX_CMDS_H_ */
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -41,7 +68,7 @@
|
|||||||
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK
|
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 18, 0)
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 15, 60)
|
||||||
#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE
|
#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -380,6 +407,7 @@ enum {
|
|||||||
rwnx_ops_hw_scan(hw, vif, struct cfg80211_scan_request *req)
|
rwnx_ops_hw_scan(hw, vif, struct cfg80211_scan_request *req)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
u16 rwnx_select_txq(struct rwnx_vif *rwnx_vif, struct sk_buff *skb);
|
||||||
/* NET */
|
/* NET */
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
|
||||||
#define rwnx_select_queue(dev, skb, sb_dev) \
|
#define rwnx_select_queue(dev, skb, sb_dev) \
|
||||||
|
|||||||
@@ -1777,7 +1777,7 @@ static ssize_t rwnx_dbgfs_dbg_level_read(struct file *file,
|
|||||||
char __user *user_buf,
|
char __user *user_buf,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *priv = file->private_data;
|
//struct rwnx_hw *priv = file->private_data;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
int ret;
|
int ret;
|
||||||
ssize_t read;
|
ssize_t read;
|
||||||
@@ -1796,7 +1796,7 @@ static ssize_t rwnx_dbgfs_dbg_level_write(struct file *file,
|
|||||||
const char __user *user_buf,
|
const char __user *user_buf,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *priv = file->private_data;
|
//struct rwnx_hw *priv = file->private_data;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
int val;
|
int val;
|
||||||
size_t len = min_t(size_t, count, sizeof(buf) - 1);
|
size_t len = min_t(size_t, count, sizeof(buf) - 1);
|
||||||
@@ -2019,7 +2019,7 @@ static void idx_to_rate_cfg1(unsigned int formatmod,
|
|||||||
case FORMATMOD_NON_HT:
|
case FORMATMOD_NON_HT:
|
||||||
{
|
{
|
||||||
r_cfg->formatModTx = formatmod;
|
r_cfg->formatModTx = formatmod;
|
||||||
r_cfg->giAndPreTypeTx = 1;
|
r_cfg->giAndPreTypeTx = 2;
|
||||||
r_cfg->mcsIndexTx = mcs;
|
r_cfg->mcsIndexTx = mcs;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2236,8 +2236,7 @@ static ssize_t rwnx_dbgfs_rc_fixed_rate_idx_write(struct file *file,
|
|||||||
/* Get the station index from MAC address */
|
/* Get the station index from MAC address */
|
||||||
sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
||||||
&mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
|
&mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
|
||||||
if (&mac[0] == NULL)
|
|
||||||
return 0;
|
|
||||||
sta = rwnx_get_sta(priv, mac);
|
sta = rwnx_get_sta(priv, mac);
|
||||||
if (sta == NULL)
|
if (sta == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ static inline void rwnx_dbgfs_register_rc_stat(struct rwnx_hw *rwnx_hw, struct r
|
|||||||
static inline void rwnx_dbgfs_unregister_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) {}
|
static inline void rwnx_dbgfs_unregister_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) {}
|
||||||
#endif
|
#endif
|
||||||
#endif /* CONFIG_RWNX_DEBUGFS */
|
#endif /* CONFIG_RWNX_DEBUGFS */
|
||||||
|
void _rwnx_dbgfs_rc_stat_write(struct rwnx_debugfs *rwnx_debugfs, uint8_t sta_idx);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _RWNX_DEBUGFS_H_ */
|
#endif /* _RWNX_DEBUGFS_H_ */
|
||||||
|
|||||||
@@ -79,20 +79,11 @@
|
|||||||
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
|
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
|
||||||
#ifndef IEEE80211_MAX_AMPDU_BUF
|
|
||||||
#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE
|
#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE
|
||||||
#endif
|
|
||||||
#ifndef IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB
|
|
||||||
#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB
|
#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB
|
||||||
#endif
|
|
||||||
#ifndef IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB
|
|
||||||
#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB
|
#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB
|
||||||
#endif
|
|
||||||
#ifndef IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA
|
|
||||||
#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU
|
#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef IEEE80211_MAX_AMPDU_BUF
|
#ifndef IEEE80211_MAX_AMPDU_BUF
|
||||||
#define IEEE80211_MAX_AMPDU_BUF 0x100
|
#define IEEE80211_MAX_AMPDU_BUF 0x100
|
||||||
@@ -107,6 +98,7 @@
|
|||||||
#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40
|
#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL)
|
||||||
enum nl80211_ac {
|
enum nl80211_ac {
|
||||||
NL80211_AC_VO,
|
NL80211_AC_VO,
|
||||||
@@ -237,6 +229,7 @@ struct tmp_feature_sta {
|
|||||||
u8_l supported_band;
|
u8_l supported_band;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define MAX_PENDING_PROBES 3
|
#define MAX_PENDING_PROBES 3
|
||||||
struct ap_probe_rsp {
|
struct ap_probe_rsp {
|
||||||
u8_l da[6];
|
u8_l da[6];
|
||||||
@@ -244,6 +237,7 @@ struct ap_probe_rsp {
|
|||||||
bool in_use;
|
bool in_use;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
|
||||||
#define NL80211_MESHCONF_POWER_MODE 26
|
#define NL80211_MESHCONF_POWER_MODE 26
|
||||||
@@ -388,6 +382,18 @@ enum rwnx_ap_flags {
|
|||||||
RWNX_AP_ISOLATE = BIT(0),
|
RWNX_AP_ISOLATE = BIT(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||||
|
struct sta_pwrthd {
|
||||||
|
s8_l rssi_thd_0; //rssi 0 (dBm)
|
||||||
|
s8_l rssi_thd_1; //rssi 1 (dBm)
|
||||||
|
s8_l rssi_thd_2; //rssi 2 (dBm)
|
||||||
|
s8_l pwr_loss_lvl_0; //RSSI > RSSI_THD_0
|
||||||
|
s8_l pwr_loss_lvl_1; //RSSI_THD_1 < RSSI <= RSSI_THD_0
|
||||||
|
s8_l pwr_loss_lvl_2; //RSSI_THD_2 < RSSI <= RSSI_THD_1
|
||||||
|
s8_l pwr_loss_lvl_3; //RSSI <= RSSI_THD_2
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure used to save information relative to the managed interfaces.
|
* Structure used to save information relative to the managed interfaces.
|
||||||
* This is also linked within the rwnx_hw vifs list.
|
* This is also linked within the rwnx_hw vifs list.
|
||||||
@@ -402,6 +408,7 @@ struct rwnx_vif {
|
|||||||
struct rwnx_key key[6];
|
struct rwnx_key key[6];
|
||||||
unsigned long drv_flags;
|
unsigned long drv_flags;
|
||||||
atomic_t drv_conn_state;
|
atomic_t drv_conn_state;
|
||||||
|
spinlock_t conn_state_lock;
|
||||||
u8 drv_vif_index; /* Identifier of the VIF in driver */
|
u8 drv_vif_index; /* Identifier of the VIF in driver */
|
||||||
u8 vif_index; /* Identifier of the station in FW */
|
u8 vif_index; /* Identifier of the station in FW */
|
||||||
u8 ch_index; /* Channel context identifier */
|
u8 ch_index; /* Channel context identifier */
|
||||||
@@ -458,6 +465,7 @@ struct rwnx_vif {
|
|||||||
u32_l freq;
|
u32_l freq;
|
||||||
bool start;
|
bool start;
|
||||||
#endif
|
#endif
|
||||||
|
u32_l ap_freq;
|
||||||
enum nl80211_mesh_power_mode mesh_pm; /* mesh power save mode currently set in firmware */
|
enum nl80211_mesh_power_mode mesh_pm; /* mesh power save mode currently set in firmware */
|
||||||
enum nl80211_mesh_power_mode next_mesh_pm; /* mesh power save mode for next peer */
|
enum nl80211_mesh_power_mode next_mesh_pm; /* mesh power save mode for next peer */
|
||||||
} ap;
|
} ap;
|
||||||
@@ -487,12 +495,14 @@ struct rwnx_vif {
|
|||||||
struct br_ext_info ethBrExtInfo;
|
struct br_ext_info ethBrExtInfo;
|
||||||
#endif /* CONFIG_BR_SUPPORT */
|
#endif /* CONFIG_BR_SUPPORT */
|
||||||
#ifdef CONFIG_BAND_STEERING
|
#ifdef CONFIG_BAND_STEERING
|
||||||
struct workqueue_struct *rsp_wq;
|
|
||||||
struct timer_list steer_timer;
|
struct timer_list steer_timer;
|
||||||
struct work_struct steer_work;
|
struct work_struct steer_work;
|
||||||
struct b_steer_priv bsteerpriv;
|
struct b_steer_priv bsteerpriv;
|
||||||
|
#if 0
|
||||||
|
struct workqueue_struct *rsp_wq;
|
||||||
struct ap_probe_rsp pb_pool[MAX_PENDING_PROBES];
|
struct ap_probe_rsp pb_pool[MAX_PENDING_PROBES];
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -724,7 +734,7 @@ struct amsdu_subframe_hdr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* rwnx driver status */
|
/* rwnx driver status */
|
||||||
void rwnx_set_conn_state(atomic_t *drv_conn_state, int state);
|
void rwnx_set_conn_state(struct rwnx_vif *vif, atomic_t *drv_conn_state, int state);
|
||||||
|
|
||||||
enum rwnx_drv_connect_status {
|
enum rwnx_drv_connect_status {
|
||||||
RWNX_DRV_STATUS_DISCONNECTED = 0,
|
RWNX_DRV_STATUS_DISCONNECTED = 0,
|
||||||
@@ -885,6 +895,7 @@ struct rwnx_hw {
|
|||||||
char wext_essid[33];
|
char wext_essid[33];
|
||||||
int support_freqs[SCAN_CHANNEL_MAX];
|
int support_freqs[SCAN_CHANNEL_MAX];
|
||||||
int support_freqs_number;
|
int support_freqs_number;
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_DYNAMIC_PWR
|
#ifdef CONFIG_DYNAMIC_PWR
|
||||||
struct timer_list pwrloss_timer;
|
struct timer_list pwrloss_timer;
|
||||||
struct work_struct pwrloss_work;
|
struct work_struct pwrloss_work;
|
||||||
@@ -892,11 +903,22 @@ struct rwnx_hw {
|
|||||||
s8 pwrloss_lvl;
|
s8 pwrloss_lvl;
|
||||||
u8 sta_rssi_idx;
|
u8 sta_rssi_idx;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_TEMP_CONTROL
|
||||||
|
struct timer_list tc_timer;
|
||||||
|
struct work_struct tc_work;
|
||||||
|
s8 tc_range;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_BAND_STEERING
|
#ifdef CONFIG_BAND_STEERING
|
||||||
u8_l iface_idx;
|
u8_l iface_idx;
|
||||||
struct tmp_feature_sta feature_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX];
|
struct tmp_feature_sta feature_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX];
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||||
|
struct sta_pwrthd pwrth;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ktime_t last_time;
|
||||||
|
char last_alpha2[3];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
u8 *rwnx_build_bcn(struct rwnx_bcn *bcn, struct cfg80211_beacon_data *new);
|
u8 *rwnx_build_bcn(struct rwnx_bcn *bcn, struct cfg80211_beacon_data *new);
|
||||||
|
|||||||
@@ -16,5 +16,7 @@
|
|||||||
|
|
||||||
int rwnx_dini_platform_init(struct pci_dev *pci_dev,
|
int rwnx_dini_platform_init(struct pci_dev *pci_dev,
|
||||||
struct rwnx_plat **rwnx_plat);
|
struct rwnx_plat **rwnx_plat);
|
||||||
|
int rwnx_cfpga_irq_enable(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_cfpga_irq_disable(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
#endif /* _RWNX_DINI_H_ */
|
#endif /* _RWNX_DINI_H_ */
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include "rwnx_defs.h"
|
#include "rwnx_defs.h"
|
||||||
#include "ipc_host.h"
|
#include "ipc_host.h"
|
||||||
#include "rwnx_prof.h"
|
#include "rwnx_prof.h"
|
||||||
|
#include "rwnx_irqs.h"
|
||||||
/**
|
/**
|
||||||
* rwnx_irq_hdlr - IRQ handler
|
* rwnx_irq_hdlr - IRQ handler
|
||||||
*
|
*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,21 @@ extern u8 chip_mcu_id;
|
|||||||
#define PWR_LOSS_LVL3 (0)//(2) //RSSI <RSSI_THD_2
|
#define PWR_LOSS_LVL3 (0)//(2) //RSSI <RSSI_THD_2
|
||||||
|
|
||||||
#define PWR_DELAY_TIME (10 * 1000) //pwr reduced latency time (ms)
|
#define PWR_DELAY_TIME (10 * 1000) //pwr reduced latency time (ms)
|
||||||
|
#define PWR_FAST_SWITCH_PROTECT_TIME (2 * 1000) //quickly switch protection time (ms)
|
||||||
|
#define RSSI_HYSTERESIS_OFFSET 2 //buffer zone (dB)
|
||||||
|
#define RSSI_HYSTERESIS_THRESHOLD 2 //range of signal variation (dB)
|
||||||
|
|
||||||
|
#ifdef CONFIG_TEMP_CONTROL
|
||||||
|
#define TEMP_GET_INTERVAL (10 * 1000) //time interval
|
||||||
|
#define TEMP_THD_0 (110) //℃
|
||||||
|
#define TEMP_THD_1 (95) //℃
|
||||||
|
#define TEMP_THD_2 (85) //℃
|
||||||
|
|
||||||
|
#define TC_LOSS_LVL0 (-10) //TEMP >= TEMP_THD_0
|
||||||
|
#define TC_LOSS_LVL1 (-5) //TEMP_THD_1 < TEMP <= TEMP_THD_0
|
||||||
|
#define TC_LOSS_LVL2 (-2) //TEMP_THD_2 < TEMP <= TEMP_THD_1
|
||||||
|
#define TC_LOSS_LVL3 (0) //TEMP <= TEMP_THD_2
|
||||||
|
#endif
|
||||||
|
|
||||||
struct rwnx_sta *rwnx_retrieve_sta(struct rwnx_hw *rwnx_hw,
|
struct rwnx_sta *rwnx_retrieve_sta(struct rwnx_hw *rwnx_hw,
|
||||||
struct rwnx_vif *rwnx_vif, u8 *addr,
|
struct rwnx_vif *rwnx_vif, u8 *addr,
|
||||||
@@ -53,13 +68,56 @@ void aicwf_steering_timeout(struct timer_list *t);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DYNAMIC_PERPWR
|
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||||
void rssi_update_txpwrloss(struct rwnx_sta *sta, s8_l rssi);
|
void rssi_update_txpwrloss(struct rwnx_sta *sta, s8_l rssi, struct rwnx_vif *vif);
|
||||||
void aicwf_txpwer_per_sta_worker(struct work_struct *work);
|
void aicwf_txpwer_per_sta_worker(struct work_struct *work);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DYNAMIC_PWR
|
|
||||||
void set_txpwrloss_ctrl(struct rwnx_hw *rwnx_hw, s8 value);
|
void set_txpwrloss_ctrl(struct rwnx_hw *rwnx_hw, s8 value);
|
||||||
|
#ifdef CONFIG_DYNAMIC_PWR
|
||||||
void aicwf_pwrloss_worker(struct work_struct *work);
|
void aicwf_pwrloss_worker(struct work_struct *work);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_TEMP_CONTROL
|
||||||
|
void aicwf_tcloss_worker(struct work_struct *work);
|
||||||
|
#endif
|
||||||
|
void rwnx_skb_align_8bytes(struct sk_buff *skb);
|
||||||
|
void rwnx_frame_parser(char* tag, char* data, unsigned long len);
|
||||||
|
void rwnx_update_mesh_power_mode(struct rwnx_vif *vif);
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||||
|
void aicwf_p2p_alive_timeout(ulong data);
|
||||||
|
#else
|
||||||
|
void aicwf_p2p_alive_timeout(struct timer_list *t);
|
||||||
|
#endif
|
||||||
|
int rwnx_send_check_p2p(struct cfg80211_scan_request *param);
|
||||||
|
void apm_staloss_work_process(struct work_struct *work);
|
||||||
|
void apm_probe_sta_work_process(struct work_struct *work);
|
||||||
|
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||||
|
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||||
|
struct net_device *dev,
|
||||||
|
struct cfg80211_chan_def *chandef);
|
||||||
|
#else
|
||||||
|
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||||
|
struct cfg80211_chan_def *chandef);
|
||||||
|
#endif
|
||||||
|
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
const u8 *peer, u64 *cookie);
|
||||||
|
void rwnx_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
|
||||||
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
|
||||||
|
struct net_device *dev,
|
||||||
|
#else
|
||||||
|
struct wireless_dev *wdev,
|
||||||
|
#endif
|
||||||
|
u16 frame_type, bool reg);
|
||||||
|
|
||||||
|
int rwnx_cfg80211_channel_switch(struct wiphy *wiphy,
|
||||||
|
struct net_device *dev,
|
||||||
|
struct cfg80211_csa_settings *params);
|
||||||
|
int rwnx_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
struct bss_parameters *params);
|
||||||
|
int rwnx_ic_system_init(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_ic_rf_init(struct rwnx_hw *rwnx_hw);
|
||||||
|
void aic_ipc_setting(struct rwnx_vif *rwnx_vif);
|
||||||
|
u16 rwnx_select_queue(struct net_device *dev, struct sk_buff *skb,
|
||||||
|
struct net_device *sb_dev);
|
||||||
|
|
||||||
#endif /* _RWNX_MAIN_H_ */
|
#endif /* _RWNX_MAIN_H_ */
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ struct rwnx_mod_params rwnx_mod_params = {
|
|||||||
COMMON_PARAM(mutx, true, true)
|
COMMON_PARAM(mutx, true, true)
|
||||||
COMMON_PARAM(mutx_on, true, true)
|
COMMON_PARAM(mutx_on, true, true)
|
||||||
COMMON_PARAM(use_80, true, true)
|
COMMON_PARAM(use_80, true, true)
|
||||||
|
/* false: use crda(iw reg set CN); true: drive self-management(wifi_test wlan0 country_set CN) */
|
||||||
COMMON_PARAM(custregd, true, true)
|
COMMON_PARAM(custregd, true, true)
|
||||||
COMMON_PARAM(custchan, false, false)
|
COMMON_PARAM(custchan, false, false)
|
||||||
COMMON_PARAM(roc_dur_max, 500, 500)
|
COMMON_PARAM(roc_dur_max, 500, 500)
|
||||||
@@ -1781,6 +1782,8 @@ int rwnx_handle_dynparams(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
|
|||||||
if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 &&
|
if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 &&
|
||||||
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 &&
|
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 &&
|
||||||
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 &&
|
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 &&
|
||||||
|
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D80N &&
|
||||||
|
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800DLN &&
|
||||||
rwnx_hw->mod_params->he_mcs_map > IEEE80211_HE_MCS_SUPPORT_0_9){
|
rwnx_hw->mod_params->he_mcs_map > IEEE80211_HE_MCS_SUPPORT_0_9){
|
||||||
rwnx_hw->mod_params->he_mcs_map = IEEE80211_HE_MCS_SUPPORT_0_9;
|
rwnx_hw->mod_params->he_mcs_map = IEEE80211_HE_MCS_SUPPORT_0_9;
|
||||||
} else {
|
} else {
|
||||||
@@ -1791,6 +1794,7 @@ int rwnx_handle_dynparams(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
|
|||||||
if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 &&
|
if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 &&
|
||||||
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 &&
|
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 &&
|
||||||
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 &&
|
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 &&
|
||||||
|
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D80N &&
|
||||||
rwnx_hw->mod_params->use_80 == true){
|
rwnx_hw->mod_params->use_80 == true){
|
||||||
rwnx_hw->mod_params->use_80 = false;
|
rwnx_hw->mod_params->use_80 = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -1837,11 +1841,13 @@ void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
|
|||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
|
||||||
wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
|
wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
|
||||||
wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
|
#endif
|
||||||
|
|
||||||
if (!rwnx_hw->mod_params->custregd)
|
if (!rwnx_hw->mod_params->custregd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
|
||||||
|
wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
|
||||||
|
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)
|
||||||
if (regulatory_set_wiphy_regd_sync(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){
|
if (regulatory_set_wiphy_regd_sync(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){
|
||||||
@@ -1852,6 +1858,7 @@ void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
|
|||||||
wiphy_err(wiphy, "Failed to set custom regdomain\n");
|
wiphy_err(wiphy, "Failed to set custom regdomain\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
else{
|
else{
|
||||||
wiphy_err(wiphy,"\n"
|
wiphy_err(wiphy,"\n"
|
||||||
"*******************************************************\n"
|
"*******************************************************\n"
|
||||||
@@ -1860,4 +1867,6 @@ void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
|
|||||||
}
|
}
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ struct ieee80211_regdomain *getRegdomainFromRwnxDB(struct wiphy *wiphy,
|
|||||||
|
|
||||||
struct ieee80211_regdomain *getRegdomainFromRwnxDBIndex(struct wiphy *wiphy,
|
struct ieee80211_regdomain *getRegdomainFromRwnxDBIndex(struct wiphy *wiphy,
|
||||||
int index);
|
int index);
|
||||||
|
void rwnx_get_countrycode_channels(struct wiphy *wiphy,
|
||||||
|
struct ieee80211_regdomain *regdomain);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _RWNX_MOD_PARAM_H_ */
|
#endif /* _RWNX_MOD_PARAM_H_ */
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
#ifdef CONFIG_USE_WIRELESS_EXT
|
#ifdef CONFIG_USE_WIRELESS_EXT
|
||||||
#include "aicwf_wext_linux.h"
|
#include "aicwf_wext_linux.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "rwnx_msg_rx.h"
|
||||||
|
|
||||||
void rwnx_cfg80211_unlink_bss(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif);
|
void rwnx_cfg80211_unlink_bss(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif);
|
||||||
|
|
||||||
static int rwnx_freq_to_idx(struct rwnx_hw *rwnx_hw, int freq)
|
static int rwnx_freq_to_idx(struct rwnx_hw *rwnx_hw, int freq)
|
||||||
@@ -790,7 +792,15 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw,
|
|||||||
|
|
||||||
#ifdef CONFIG_USE_WIRELESS_EXT
|
#ifdef CONFIG_USE_WIRELESS_EXT
|
||||||
if(rwnx_hw->wext_scan){
|
if(rwnx_hw->wext_scan){
|
||||||
|
if (!bss ) {
|
||||||
|
AICWFDBG(LOGERROR, "%s: Invalid BSS structure\n", __func__);
|
||||||
|
goto putbss;
|
||||||
|
}
|
||||||
list_for_each_entry(scan_re_wext, &rwnx_hw->wext_scanre_list, scanu_re_list) {
|
list_for_each_entry(scan_re_wext, &rwnx_hw->wext_scanre_list, scanu_re_list) {
|
||||||
|
if (!scan_re_wext || !scan_re_wext->bss ) {
|
||||||
|
AICWFDBG(LOGDEBUG, "%s: Corrupted list entry detected\n", __func__);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!memcmp(scan_re_wext->bss->bssid, bss->bssid, ETH_ALEN)) {
|
if (!memcmp(scan_re_wext->bss->bssid, bss->bssid, ETH_ALEN)) {
|
||||||
AICWFDBG(LOGDEBUG, "%s: BSSID already exists, no need to add again\r\n", __func__);
|
AICWFDBG(LOGDEBUG, "%s: BSSID already exists, no need to add again\r\n", __func__);
|
||||||
goto putbss;
|
goto putbss;
|
||||||
@@ -815,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);
|
||||||
@@ -1043,9 +1055,9 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
|
|||||||
rwnx_vif->wep_auth_err = true;
|
rwnx_vif->wep_auth_err = true;
|
||||||
AICWFDBG(LOGINFO, "con ind wep_auth_err %d\n", rwnx_vif->wep_auth_err);
|
AICWFDBG(LOGINFO, "con ind wep_auth_err %d\n", rwnx_vif->wep_auth_err);
|
||||||
}
|
}
|
||||||
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
|
rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
|
||||||
}else{
|
}else{
|
||||||
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
|
rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1067,9 +1079,13 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
|
|||||||
ind->assoc_rsp_ie_len, ind->status_code,
|
ind->assoc_rsp_ie_len, ind->status_code,
|
||||||
GFP_ATOMIC);
|
GFP_ATOMIC);
|
||||||
if (ind->status_code == 0) {
|
if (ind->status_code == 0) {
|
||||||
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
|
rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
|
||||||
} else {
|
} else {
|
||||||
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
|
if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED) {
|
||||||
|
AICWFDBG(LOGINFO, "%s roaming fail no roamed ind \r\n", __func__);
|
||||||
|
cfg80211_disconnected(dev, 0, NULL, 0, 1, GFP_ATOMIC);
|
||||||
|
}
|
||||||
|
rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
|
||||||
rwnx_external_auth_disable(rwnx_vif);
|
rwnx_external_auth_disable(rwnx_vif);
|
||||||
}
|
}
|
||||||
AICWFDBG(LOGINFO, "%s cfg80211_connect_result pass, rwnx_vif->drv_conn_state:%d\r\n", __func__, (int)atomic_read(&rwnx_vif->drv_conn_state));
|
AICWFDBG(LOGINFO, "%s cfg80211_connect_result pass, rwnx_vif->drv_conn_state:%d\r\n", __func__, (int)atomic_read(&rwnx_vif->drv_conn_state));
|
||||||
@@ -1078,7 +1094,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
|
|||||||
if(ind->status_code != 0){
|
if(ind->status_code != 0){
|
||||||
AICWFDBG(LOGINFO, "%s roaming fail to notify disconnect \r\n", __func__);
|
AICWFDBG(LOGINFO, "%s roaming fail to notify disconnect \r\n", __func__);
|
||||||
cfg80211_disconnected(dev, 0, NULL, 0,1, GFP_ATOMIC);
|
cfg80211_disconnected(dev, 0, NULL, 0,1, GFP_ATOMIC);
|
||||||
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
|
rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
|
||||||
rwnx_external_auth_disable(rwnx_vif);
|
rwnx_external_auth_disable(rwnx_vif);
|
||||||
}else{
|
}else{
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
|
||||||
@@ -1116,7 +1132,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
|
|||||||
, ind->assoc_rsp_ie_len
|
, ind->assoc_rsp_ie_len
|
||||||
, GFP_ATOMIC);
|
, GFP_ATOMIC);
|
||||||
#endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)*/
|
#endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)*/
|
||||||
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
|
rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
|
||||||
}
|
}
|
||||||
rwnx_vif->sta.is_roam = false;
|
rwnx_vif->sta.is_roam = false;
|
||||||
}
|
}
|
||||||
@@ -1263,7 +1279,7 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
|
|||||||
|
|
||||||
//msleep(200);
|
//msleep(200);
|
||||||
if (rwnx_vif->sta.is_roam == false) {
|
if (rwnx_vif->sta.is_roam == false) {
|
||||||
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
|
rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1577,6 +1593,68 @@ static inline int rwnx_rx_dbg_error_ind(struct rwnx_hw *rwnx_hw,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct fault_ctxt {
|
||||||
|
uint32_t reg_i[13];
|
||||||
|
uint32_t SP;
|
||||||
|
uint32_t LR;
|
||||||
|
uint32_t PC;
|
||||||
|
uint32_t xPSR;
|
||||||
|
uint32_t PSP;
|
||||||
|
uint32_t MSP;
|
||||||
|
uint32_t EXC_RETURN;
|
||||||
|
uint32_t CONTROL;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int rwnx_fw_panic_ind(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct rwnx_cmd *cmd,
|
||||||
|
struct ipc_e2a_msg *msg)
|
||||||
|
{
|
||||||
|
struct fw_panic_info_ind *ind = (struct fw_panic_info_ind *)msg->param;
|
||||||
|
uint8_t version[36];
|
||||||
|
struct fault_ctxt fault;
|
||||||
|
uint32_t msp[64];
|
||||||
|
uint8_t i;
|
||||||
|
memcpy(version, ind->info, 36);
|
||||||
|
version[35] = '\0';
|
||||||
|
memcpy(&fault, &ind->info[36], sizeof(struct fault_ctxt));
|
||||||
|
memcpy(msp, &ind->info[36+sizeof(struct fault_ctxt)], 64*4);
|
||||||
|
|
||||||
|
printk("fw_panic: len=%d\n", ind->len);
|
||||||
|
printk("firmware: %s\n", version);
|
||||||
|
|
||||||
|
for(i=0; i<13; i++)
|
||||||
|
printk("REG %d = [%x]\n", i, fault.reg_i[i]);
|
||||||
|
printk("SP = [%x]\n", fault.SP);
|
||||||
|
printk("LR = [%x]\n", fault.LR);
|
||||||
|
printk("PC = [%x]\n", fault.PC);
|
||||||
|
printk("PSP = [%x]\n", fault.PSP);
|
||||||
|
printk("xPSR = [%x]\n", fault.xPSR);
|
||||||
|
printk("EXC_RETURN = [%x]\n", fault.EXC_RETURN);
|
||||||
|
printk("CONTROL = [%x]\n", fault.CONTROL);
|
||||||
|
|
||||||
|
printk("STACK:\n");
|
||||||
|
for(i=0; i<64; i+=4) {
|
||||||
|
printk("%08x, %08x, %08x, %08x\n", msp[i], msp[i+1], msp[i+2], msp[i+3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int rwnx_fw_assert_ind(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct rwnx_cmd *cmd,
|
||||||
|
struct ipc_e2a_msg *msg)
|
||||||
|
{
|
||||||
|
struct fw_assert_info_ind *ind = (struct fw_assert_info_ind *)msg->param;
|
||||||
|
uint8_t buffer[256];
|
||||||
|
|
||||||
|
memcpy(buffer, ind->info, ind->len);
|
||||||
|
buffer[ind->len] = '\0';
|
||||||
|
|
||||||
|
printk("%s: %s\n", __func__, buffer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_RWNX_FULLMAC
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
|
||||||
static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = {
|
static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = {
|
||||||
@@ -1595,6 +1673,8 @@ static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = {
|
|||||||
[MSG_I(MM_PKTLOSS_IND)] = rwnx_rx_pktloss_notify_ind,
|
[MSG_I(MM_PKTLOSS_IND)] = rwnx_rx_pktloss_notify_ind,
|
||||||
[MSG_I(MM_APM_STALOSS_IND)] = rwnx_apm_staloss_ind,
|
[MSG_I(MM_APM_STALOSS_IND)] = rwnx_apm_staloss_ind,
|
||||||
[MSG_I(MM_RADAR_DETECT_IND)] = rwnx_radar_detect_ind,
|
[MSG_I(MM_RADAR_DETECT_IND)] = rwnx_radar_detect_ind,
|
||||||
|
[MSG_I(MM_FW_PANIC_IND)] = rwnx_fw_panic_ind,
|
||||||
|
[MSG_I(MM_FW_ASSERT_IND)] = rwnx_fw_assert_ind,
|
||||||
};
|
};
|
||||||
|
|
||||||
static msg_cb_fct scan_hdlrs[MSG_I(SCANU_MAX)] = {
|
static msg_cb_fct scan_hdlrs[MSG_I(SCANU_MAX)] = {
|
||||||
@@ -1669,12 +1749,14 @@ void rwnx_rx_handle_print(struct rwnx_hw *rwnx_hw, u8 *msg, u32 len)
|
|||||||
u8 *data_end = NULL;
|
u8 *data_end = NULL;
|
||||||
(void)data_end;
|
(void)data_end;
|
||||||
|
|
||||||
|
msg[len-1] = '\0';
|
||||||
|
|
||||||
if (!rwnx_hw || !rwnx_hw->fwlog_en) {
|
if (!rwnx_hw || !rwnx_hw->fwlog_en) {
|
||||||
pr_err("FWLOG-OVFL: %s", msg);
|
pr_err("FWLOG-OVFL: %s", msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk("FWLOG: %s", msg);
|
AICWFDBG(LOGFW, "%s", msg);
|
||||||
|
|
||||||
#ifdef CONFIG_RWNX_DEBUGFS
|
#ifdef CONFIG_RWNX_DEBUGFS
|
||||||
data_end = rwnx_hw->debugfs.fw_log.buf.dataend;
|
data_end = rwnx_hw->debugfs.fw_log.buf.dataend;
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ void rwnx_cmd_free(struct rwnx_cmd *cmd){
|
|||||||
|
|
||||||
spin_lock_irqsave(&cmd_array_lock, flags);
|
spin_lock_irqsave(&cmd_array_lock, flags);
|
||||||
cmd->used = 0;
|
cmd->used = 0;
|
||||||
|
cmd->flags = 0;
|
||||||
AICWFDBG(LOGTRACE, "%s cmd_array[%d]:%p \r\n", __func__, cmd->array_id, cmd);
|
AICWFDBG(LOGTRACE, "%s cmd_array[%d]:%p \r\n", __func__, cmd->array_id, cmd);
|
||||||
spin_unlock_irqrestore(&cmd_array_lock, flags);
|
spin_unlock_irqrestore(&cmd_array_lock, flags);
|
||||||
}
|
}
|
||||||
@@ -1150,6 +1151,34 @@ int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l *
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rwnx_send_rf_config_v2_req(struct rwnx_hw *rwnx_hw, u16_l ofst, u8_l sel, u8_l *tbl, u16_l len)
|
||||||
|
{
|
||||||
|
struct mm_set_rf_config_req *rf_config_req;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
/* Build the MM_SET_RF_CONFIG_REQ message */
|
||||||
|
rf_config_req = rwnx_msg_zalloc(MM_SET_RF_CONFIG_REQ, TASK_MM, DRV_TASK_ID,
|
||||||
|
sizeof(struct mm_set_rf_config_req));
|
||||||
|
|
||||||
|
if (!rf_config_req) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rf_config_req->table_sel = sel;
|
||||||
|
rf_config_req->table_ofst = 0;
|
||||||
|
rf_config_req->table_num = 16;
|
||||||
|
rf_config_req->deft_page = ofst / 16;
|
||||||
|
|
||||||
|
memcpy(rf_config_req->data, tbl, len);
|
||||||
|
|
||||||
|
/* Send the MM_SET_RF_CONFIG_REQ message to UMAC FW */
|
||||||
|
error = rwnx_send_msg(rwnx_hw, rf_config_req, 1, MM_SET_RF_CONFIG_CFM, NULL);
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef RF_WRITE_FILE
|
#ifdef RF_WRITE_FILE
|
||||||
|
|
||||||
#define FW_PATH_MAX_LEN_RF 200
|
#define FW_PATH_MAX_LEN_RF 200
|
||||||
@@ -1271,6 +1300,9 @@ int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *
|
|||||||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
|
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
|
||||||
rf_calib_req->cal_cfg_24g = 0x0f8f;
|
rf_calib_req->cal_cfg_24g = 0x0f8f;
|
||||||
rf_calib_req->cal_cfg_5g = 0x0f0f;
|
rf_calib_req->cal_cfg_5g = 0x0f0f;
|
||||||
|
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N){
|
||||||
|
rf_calib_req->cal_cfg_24g = 0x0f8f;
|
||||||
|
rf_calib_req->cal_cfg_5g = 0x0f0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
rf_calib_req->param_alpha = 0x0c34c008;
|
rf_calib_req->param_alpha = 0x0c34c008;
|
||||||
@@ -1444,6 +1476,9 @@ int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *
|
|||||||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
|
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
|
||||||
rf_calib_req->cal_cfg_24g = 0x0f8f;
|
rf_calib_req->cal_cfg_24g = 0x0f8f;
|
||||||
rf_calib_req->cal_cfg_5g = 0x0f0f;
|
rf_calib_req->cal_cfg_5g = 0x0f0f;
|
||||||
|
} else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N){
|
||||||
|
rf_calib_req->cal_cfg_24g = 0x0f8f;
|
||||||
|
rf_calib_req->cal_cfg_5g = 0x0f0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
rf_calib_req->param_alpha = 0x0c34c008;
|
rf_calib_req->param_alpha = 0x0c34c008;
|
||||||
@@ -1494,8 +1529,23 @@ int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cf
|
|||||||
int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_get_sta_info_cfm *cfm)
|
int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_get_sta_info_cfm *cfm)
|
||||||
{
|
{
|
||||||
struct mm_get_sta_info_req *get_info_req;
|
struct mm_get_sta_info_req *get_info_req;
|
||||||
|
struct mm_get_sta_info_compat_req *get_info_compat_req;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
if(rwnx_hw->usbdev->chipid < PRODUCT_ID_AIC8800D81X2) {
|
||||||
|
/* Build the MM_GET_STA_INFO_REQ message */
|
||||||
|
get_info_compat_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID,
|
||||||
|
sizeof(struct mm_get_sta_info_compat_req));
|
||||||
|
if (!get_info_compat_req) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_info_compat_req->sta_idx = sta_idx;
|
||||||
|
memcpy(get_info_compat_req->pattern, "sta", 3);
|
||||||
|
/* Send the MM_GET_STA_INFO_REQ message to UMAC FW */
|
||||||
|
error = rwnx_send_msg(rwnx_hw, get_info_compat_req, 1, MM_GET_STA_INFO_CFM, cfm);
|
||||||
|
|
||||||
|
} else {
|
||||||
/* Build the MM_GET_STA_INFO_REQ message */
|
/* Build the MM_GET_STA_INFO_REQ message */
|
||||||
get_info_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID,
|
get_info_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID,
|
||||||
sizeof(struct mm_get_sta_info_req));
|
sizeof(struct mm_get_sta_info_req));
|
||||||
@@ -1508,7 +1558,7 @@ int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_
|
|||||||
|
|
||||||
/* Send the MM_GET_STA_INFO_REQ message to UMAC FW */
|
/* Send the MM_GET_STA_INFO_REQ message to UMAC FW */
|
||||||
error = rwnx_send_msg(rwnx_hw, get_info_req, 1, MM_GET_STA_INFO_CFM, cfm);
|
error = rwnx_send_msg(rwnx_hw, get_info_req, 1, MM_GET_STA_INFO_CFM, cfm);
|
||||||
|
}
|
||||||
return error;
|
return error;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1709,6 +1759,7 @@ int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id,
|
|||||||
printk("get_chip_temp err=%d\n", error);
|
printk("get_chip_temp err=%d\n", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case CUSTOMIZED_FREQ_REQ:
|
case CUSTOMIZED_FREQ_REQ:
|
||||||
/* Build the CUSTOMIZED_FREQ_REQ message */
|
/* Build the CUSTOMIZED_FREQ_REQ message */
|
||||||
req5 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_customized_freq_req));
|
req5 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_customized_freq_req));
|
||||||
@@ -2386,7 +2437,8 @@ int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw)
|
|||||||
txpwr_lvl_v2->pwrlvl_11ax_2g4[i] -= txpwr_loss->loss_value_2g4;
|
txpwr_lvl_v2->pwrlvl_11ax_2g4[i] -= txpwr_loss->loss_value_2g4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((testmode == 0) && (chip_sub_id == 0)) {
|
if ((rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800DLN) &&
|
||||||
|
(testmode == 0) && (chip_sub_id == 0)) {
|
||||||
txpwr_lvl_req->txpwr_lvl.enable = txpwr_lvl_v2->enable;
|
txpwr_lvl_req->txpwr_lvl.enable = txpwr_lvl_v2->enable;
|
||||||
txpwr_lvl_req->txpwr_lvl.dsss = txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]; // 11M
|
txpwr_lvl_req->txpwr_lvl.dsss = txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]; // 11M
|
||||||
txpwr_lvl_req->txpwr_lvl.ofdmlowrate_2g4= txpwr_lvl_v2->pwrlvl_11ax_2g4[4]; // MCS4
|
txpwr_lvl_req->txpwr_lvl.ofdmlowrate_2g4= txpwr_lvl_v2->pwrlvl_11ax_2g4[4]; // MCS4
|
||||||
@@ -2753,6 +2805,45 @@ int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rwnx_send_txpwr_lvl_adj_v2_req(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
struct mm_set_txpwr_lvl_adj_req *txpwr_lvl_adj_req;
|
||||||
|
txpwr_lvl_adj_conf_v2_t txpwr_lvl_adj_v2_tmp;
|
||||||
|
txpwr_lvl_adj_conf_v2_t *txpwr_lvl_adj_v2;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
/* Build the MM_SET_TXPWR_LVL_REQ message */
|
||||||
|
txpwr_lvl_adj_req = rwnx_msg_zalloc(MM_SET_TXPWR_LVL_ADJ_REQ, TASK_MM, DRV_TASK_ID,
|
||||||
|
sizeof(struct mm_set_txpwr_lvl_adj_req));
|
||||||
|
|
||||||
|
if (!txpwr_lvl_adj_req) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
txpwr_lvl_adj_v2 = &txpwr_lvl_adj_v2_tmp;
|
||||||
|
|
||||||
|
get_userconfig_txpwr_lvl_adj_v2_in_fdrv(txpwr_lvl_adj_v2);
|
||||||
|
|
||||||
|
if (txpwr_lvl_adj_v2->enable == 0) {
|
||||||
|
rwnx_msg_free(rwnx_hw, txpwr_lvl_adj_req);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_adj_v2->enable);
|
||||||
|
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_1_4:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[0]);
|
||||||
|
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_5_9:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[1]);
|
||||||
|
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_10_13:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[2]);
|
||||||
|
|
||||||
|
txpwr_lvl_adj_req->txpwr_lvl_adj_v2 = *txpwr_lvl_adj_v2;
|
||||||
|
|
||||||
|
/* Send the MM_SET_TXPWR_LVL_REQ message to UMAC FW */
|
||||||
|
error = rwnx_send_msg(rwnx_hw, txpwr_lvl_adj_req, 1, MM_SET_TXPWR_LVL_ADJ_CFM, NULL);
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst);
|
extern void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst);
|
||||||
|
|
||||||
int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw)
|
int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw)
|
||||||
@@ -2839,6 +2930,8 @@ int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw)
|
|||||||
} else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 ||
|
} else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 ||
|
||||||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
|
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
|
||||||
get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x);
|
get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x);
|
||||||
|
} else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) {
|
||||||
|
get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x);
|
||||||
}
|
}
|
||||||
if (txpwr_ofst2x->enable){
|
if (txpwr_ofst2x->enable){
|
||||||
AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_ofst2x->enable);
|
AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_ofst2x->enable);
|
||||||
@@ -2922,6 +3015,53 @@ int rwnx_send_txpwr_ofst2x_v2_req(struct rwnx_hw *rwnx_hw)
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rwnx_send_txpwr_ofst2x_v3_req(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
struct mm_set_txpwr_ofst_req *txpwr_ofst_req;
|
||||||
|
txpwr_ofst2x_conf_v3_t *txpwr_ofst2x_v3;
|
||||||
|
int error = 0;
|
||||||
|
int type, ch_grp;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
/* Build the MM_SET_TXPWR_OFST_REQ message */
|
||||||
|
txpwr_ofst_req = rwnx_msg_zalloc(MM_SET_TXPWR_OFST_REQ, TASK_MM, DRV_TASK_ID,
|
||||||
|
sizeof(struct mm_set_txpwr_ofst_req));
|
||||||
|
|
||||||
|
if (!txpwr_ofst_req) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
txpwr_ofst2x_v3 = &txpwr_ofst_req->txpwr_ofst2x_v3;
|
||||||
|
txpwr_ofst2x_v3->enable = 0;
|
||||||
|
for (type = 0; type < 3; type++) {
|
||||||
|
for (ch_grp = 0; ch_grp < 3; ch_grp++) {
|
||||||
|
txpwr_ofst2x_v3->pwrofst2x_tbl_2g4[type][ch_grp] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get_userconfig_txpwr_ofst2x_v3_in_fdrv(txpwr_ofst2x_v3);
|
||||||
|
if (txpwr_ofst2x_v3->enable){
|
||||||
|
AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_ofst2x_v3->enable);
|
||||||
|
AICWFDBG(LOGINFO, "pwrofst2x 2.4g: [0]:11b, [1]:ofdm_highrate, [2]:ofdm_lowrate\n"
|
||||||
|
" chan=" "\t1-4" "\t5-9" "\t10-13");
|
||||||
|
for (type = 0; type < 3; type++) {
|
||||||
|
AICWFDBG(LOGINFO, "\n [%d] =", type);
|
||||||
|
for (ch_grp = 0; ch_grp < 3; ch_grp++) {
|
||||||
|
AICWFDBG(LOGINFO, "\t%d", txpwr_ofst2x_v3->pwrofst2x_tbl_2g4[type][ch_grp]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO, "\n");
|
||||||
|
|
||||||
|
/* Send the MM_SET_TXPWR_OFST_REQ message to UMAC FW */
|
||||||
|
error = rwnx_send_msg(rwnx_hw, txpwr_ofst_req, 1, MM_SET_TXPWR_OFST_CFM, NULL);
|
||||||
|
}else{
|
||||||
|
AICWFDBG(LOGINFO, "%s:Do not use txpwr_ofst2x_v3\r\n", __func__);
|
||||||
|
rwnx_msg_free(rwnx_hw, txpwr_ofst_req);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter)
|
int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter)
|
||||||
{
|
{
|
||||||
struct mm_set_filter_req *set_filter_req_param;
|
struct mm_set_filter_req *set_filter_req_param;
|
||||||
@@ -3279,7 +3419,7 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par
|
|||||||
#if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL)
|
#if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL)
|
||||||
struct aic_sta *sta = &rwnx_hw->aic_table[rwnx_vif->ap.aic_index];
|
struct aic_sta *sta = &rwnx_hw->aic_table[rwnx_vif->ap.aic_index];
|
||||||
printk("assoc_req idx %d, he: %d, vht: %d\n ", rwnx_vif->ap.aic_index, sta->he, sta->vht);
|
printk("assoc_req idx %d, he: %d, vht: %d\n ", rwnx_vif->ap.aic_index, sta->he, sta->vht);
|
||||||
if (rwnx_vif->ap.aic_index < NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX)
|
if (rwnx_vif->ap.aic_index < (NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX - 1))
|
||||||
rwnx_vif->ap.aic_index++;
|
rwnx_vif->ap.aic_index++;
|
||||||
else
|
else
|
||||||
rwnx_vif->ap.aic_index = 0;
|
rwnx_vif->ap.aic_index = 0;
|
||||||
@@ -3406,8 +3546,13 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par
|
|||||||
req->flags |= STA_MFP_CAPA;
|
req->flags |= STA_MFP_CAPA;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
||||||
if (link_sta_params->opmode_notif_used) {
|
#if LINUX_VERSION_CODE < HIGH_KERNEL_VERSION
|
||||||
req->opmode = link_sta_params->opmode_notif_used;
|
if (params->opmode_notif_used) {
|
||||||
|
req->opmode = params->opmode_notif;
|
||||||
|
#else
|
||||||
|
if (params->link_sta_params.opmode_notif_used) {
|
||||||
|
req->opmode = params->link_sta_params.opmode_notif;
|
||||||
|
#endif//LINUX_VERSION_CODE < HIGH_KERNEL_VERSION
|
||||||
req->flags |= STA_OPMOD_NOTIF;
|
req->flags |= STA_OPMOD_NOTIF;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -4704,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);
|
||||||
@@ -5038,6 +5189,54 @@ int rwnx_send_cfg_rssi_req(struct rwnx_hw *rwnx_hw, u8 vif_index, int rssi_thold
|
|||||||
return rwnx_send_msg(rwnx_hw, req, 1, MM_CFG_RSSI_CFM, NULL);
|
return rwnx_send_msg(rwnx_hw, req, 1, MM_CFG_RSSI_CFM, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rwnx_send_get_temp_req(struct rwnx_hw *rwnx_hw, s8_l *temp)
|
||||||
|
{
|
||||||
|
struct mm_get_chip_temp_req *hwreq;
|
||||||
|
struct mm_set_vendor_swconfig_req *swreq;
|
||||||
|
struct mm_set_vendor_hwconfig_cfm hwcfm;
|
||||||
|
struct mm_set_vendor_swconfig_cfm swcfm;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC ||
|
||||||
|
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){
|
||||||
|
/* Build the CHIP_TEMP_GET_REQ message */
|
||||||
|
hwreq = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_get_chip_temp_req));
|
||||||
|
if (!hwreq)
|
||||||
|
return -ENOMEM;
|
||||||
|
hwreq->hwconfig_id = CHIP_TEMP_GET_REQ;
|
||||||
|
/* Send the MM_SET_VENDOR_HWCONFIG_REQ message to UMAC FW */
|
||||||
|
ret = rwnx_send_msg(rwnx_hw, hwreq, 1, MM_SET_VENDOR_HWCONFIG_CFM, &hwcfm);
|
||||||
|
if (!ret) {
|
||||||
|
AICWFDBG(LOGINFO, "get_chip_temp degree=%d\n", hwcfm.chip_temp_cfm.degree);
|
||||||
|
*temp = hwcfm.chip_temp_cfm.degree;
|
||||||
|
} else {
|
||||||
|
AICWFDBG(LOGINFO, "get_chip_temp err=%d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} else if (rwnx_hw->usbdev->chipid >= PRODUCT_ID_AIC8800D80N) {
|
||||||
|
/* Build the TEMP_COMP_GET_REQ message */
|
||||||
|
swreq = rwnx_msg_zalloc(MM_SET_VENDOR_SWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_vendor_swconfig_req));
|
||||||
|
if (!swreq) {
|
||||||
|
AICWFDBG(LOGINFO, "%s msg_alloc fail\n", __func__);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
swreq->swconfig_id = TEMP_COMP_GET_REQ;
|
||||||
|
|
||||||
|
ret = rwnx_send_msg(rwnx_hw, swreq, 1, MM_SET_VENDOR_SWCONFIG_CFM, &swcfm);
|
||||||
|
if (!ret) {
|
||||||
|
AICWFDBG(LOGINFO, "status=%d, temp=%d\n", swcfm.temp_comp_get_cfm.status, swcfm.temp_comp_get_cfm.degree);
|
||||||
|
*temp = swcfm.temp_comp_get_cfm.degree;
|
||||||
|
} else {
|
||||||
|
AICWFDBG(LOGINFO, "%s msg_fail\n", __func__);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
//#ifdef CONFIG_USB_BT
|
//#ifdef CONFIG_USB_BT
|
||||||
int rwnx_send_reboot(struct rwnx_hw *rwnx_hw)
|
int rwnx_send_reboot(struct rwnx_hw *rwnx_hw)
|
||||||
{
|
{
|
||||||
@@ -5049,70 +5248,9 @@ int rwnx_send_reboot(struct rwnx_hw *rwnx_hw)
|
|||||||
ret = rwnx_send_dbg_start_app_req(rwnx_hw, delay, HOST_START_APP_REBOOT);
|
ret = rwnx_send_dbg_start_app_req(rwnx_hw, delay, HOST_START_APP_REBOOT);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rwnx_send_pwm_init_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 mode, u8 run, u32 tmr_cnt,
|
|
||||||
u32 dty_cnt, u32 step_val, u8 gpio_en, u8 gpio_dir, u8 gpio_val)
|
|
||||||
{
|
|
||||||
struct dbg_pwm_init_req *pwm_init_req;
|
|
||||||
|
|
||||||
pwm_init_req = rwnx_msg_zalloc(DBG_PWM_INIT_REQ, TASK_DBG, DRV_TASK_ID,
|
|
||||||
sizeof(struct dbg_pwm_init_req));
|
|
||||||
if (!pwm_init_req)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
pwm_init_req->pwm_gpidx = pwm_gpidx;
|
|
||||||
pwm_init_req->mode = mode;
|
|
||||||
pwm_init_req->run = run;
|
|
||||||
pwm_init_req->tmr_cnt = tmr_cnt;
|
|
||||||
pwm_init_req->dty_cnt = dty_cnt;
|
|
||||||
pwm_init_req->step_val = step_val;
|
|
||||||
pwm_init_req->gpio_en = gpio_en;
|
|
||||||
pwm_init_req->gpio_dir = gpio_dir;
|
|
||||||
pwm_init_req->gpio_val = gpio_val;
|
|
||||||
|
|
||||||
|
|
||||||
return rwnx_send_msg(rwnx_hw, pwm_init_req, 1, DBG_PWM_INIT_CFM, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int rwnx_send_pwm_deinit_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 gpio_en, u8 gpio_dir, u8 gpio_val)
|
|
||||||
{
|
|
||||||
struct dbg_pwm_deinit_req *pwm_deinit_req;
|
|
||||||
|
|
||||||
pwm_deinit_req = rwnx_msg_zalloc(DBG_PWM_DEINIT_REQ, TASK_DBG, DRV_TASK_ID,
|
|
||||||
sizeof(struct dbg_pwm_deinit_req));
|
|
||||||
if (!pwm_deinit_req)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
pwm_deinit_req->pwm_gpidx = pwm_gpidx;
|
|
||||||
pwm_deinit_req->gpio_en = gpio_en;
|
|
||||||
pwm_deinit_req->gpio_dir = gpio_dir;
|
|
||||||
pwm_deinit_req->gpio_val = gpio_val;
|
|
||||||
|
|
||||||
return rwnx_send_msg(rwnx_hw, pwm_deinit_req, 1, DBG_PWM_DEINIT_CFM, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 pwm_tbl[][2] = {
|
|
||||||
{0x40504088, 4},
|
|
||||||
};
|
|
||||||
|
|
||||||
void rwnx_set_pwm_tbl(struct rwnx_hw *rwnx_hw)
|
|
||||||
{
|
|
||||||
int patch_num = 0;
|
|
||||||
int cnt = 0;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
patch_num = sizeof(pwm_tbl) / sizeof(u32) / 2;
|
|
||||||
for (cnt = 0; cnt < patch_num; cnt++) {
|
|
||||||
ret = rwnx_send_dbg_mem_write_req(rwnx_hw, pwm_tbl[cnt][0], pwm_tbl[cnt][1]);
|
|
||||||
if (ret) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//#endif // CONFIG_USB_BT
|
//#endif // CONFIG_USB_BT
|
||||||
#ifdef CONFIG_WOWLAN
|
#ifdef CONFIG_WOWLAN
|
||||||
|
#ifndef ANDROID_PLATFORM
|
||||||
int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw)
|
int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -5124,3 +5262,4 @@ int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ int rwnx_send_arpoffload_en_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_v
|
|||||||
u32_l ipaddr, u8_l enable);
|
u32_l ipaddr, u8_l enable);
|
||||||
#endif
|
#endif
|
||||||
int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l *tbl, u16_l len);
|
int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l *tbl, u16_l len);
|
||||||
|
int rwnx_send_rf_config_v2_req(struct rwnx_hw *rwnx_hw, u16_l ofst, u8_l sel, u8_l *tbl, u16_l len);
|
||||||
int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
|
int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
|
||||||
int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cfm *cfm);
|
int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cfm *cfm);
|
||||||
|
|
||||||
@@ -184,11 +185,13 @@ int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw);
|
|||||||
int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw);
|
int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw);
|
||||||
int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw);
|
int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw);
|
||||||
int rwnx_send_txpwr_ofst2x_v2_req(struct rwnx_hw *rwnx_hw);
|
int rwnx_send_txpwr_ofst2x_v2_req(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_txpwr_ofst2x_v3_req(struct rwnx_hw *rwnx_hw);
|
||||||
int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter);
|
int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter);
|
||||||
int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw);
|
int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw);
|
||||||
int rwnx_send_txpwr_lvl_v3_req(struct rwnx_hw *rwnx_hw);
|
int rwnx_send_txpwr_lvl_v3_req(struct rwnx_hw *rwnx_hw);
|
||||||
int rwnx_send_txpwr_lvl_v4_req(struct rwnx_hw *rwnx_hw);
|
int rwnx_send_txpwr_lvl_v4_req(struct rwnx_hw *rwnx_hw);
|
||||||
int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw);
|
int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_txpwr_lvl_adj_v2_req(struct rwnx_hw *rwnx_hw);
|
||||||
#ifdef CONFIG_WOWLAN
|
#ifdef CONFIG_WOWLAN
|
||||||
int rwnx_send_set_pkt_filter_req(struct rwnx_hw *rwnx_hw, u8_l *param);
|
int rwnx_send_set_pkt_filter_req(struct rwnx_hw *rwnx_hw, u8_l *param);
|
||||||
int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw);
|
int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw);
|
||||||
@@ -196,15 +199,14 @@ int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw);
|
|||||||
#ifdef CONFIG_DYNAMIC_PERPWR
|
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||||
int rwnx_send_txpwr_per_sta_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta);
|
int rwnx_send_txpwr_per_sta_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta);
|
||||||
#endif
|
#endif
|
||||||
|
int rwnx_send_get_temp_req(struct rwnx_hw *rwnx_hw, s8_l *temp);
|
||||||
|
|
||||||
//#ifdef CONFIG_USB_BT
|
//#ifdef CONFIG_USB_BT
|
||||||
int rwnx_send_reboot(struct rwnx_hw *rwnx_hw);
|
int rwnx_send_reboot(struct rwnx_hw *rwnx_hw);
|
||||||
//#endif // CONFIG_USB_BT
|
//#endif // CONFIG_USB_BT
|
||||||
|
struct rwnx_cmd *rwnx_cmd_malloc(void);
|
||||||
int rwnx_send_pwm_init_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 mode, u8 run, u32 tmr_cnt,
|
void rwnx_cmd_free(struct rwnx_cmd *cmd);
|
||||||
u32 dty_cnt, u32 step_val, u8 gpio_en, u8 gpio_dir, u8 gpio_val);
|
int rwnx_init_cmd_array(void);
|
||||||
int rwnx_send_pwm_deinit_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 gpio_en, u8 gpio_dir, u8 gpio_val);
|
void rwnx_free_cmd_array(void);
|
||||||
void rwnx_set_pwm_tbl(struct rwnx_hw *rwnx_hw);
|
|
||||||
|
|
||||||
#endif /* _RWNX_MSG_TX_H_ */
|
#endif /* _RWNX_MSG_TX_H_ */
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "rwnx_defs.h"
|
#include "rwnx_defs.h"
|
||||||
#include "rwnx_dini.h"
|
#include "rwnx_dini.h"
|
||||||
#include "rwnx_v7.h"
|
#include "rwnx_v7.h"
|
||||||
|
#include "rwnx_pci.h"
|
||||||
|
|
||||||
#define PCI_VENDOR_ID_DINIGROUP 0x17DF
|
#define PCI_VENDOR_ID_DINIGROUP 0x17DF
|
||||||
#define PCI_DEVICE_ID_DINIGROUP_DNV6_F2PCIE 0x1907
|
#define PCI_DEVICE_ID_DINIGROUP_DNV6_F2PCIE 0x1907
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
#include "aicwf_compat_8800dc.h"
|
#include "aicwf_compat_8800dc.h"
|
||||||
#include "aicwf_compat_8800d80.h"
|
#include "aicwf_compat_8800d80.h"
|
||||||
#include "aicwf_compat_8800d80x2.h"
|
#include "aicwf_compat_8800d80x2.h"
|
||||||
|
#include "aicwf_compat_8800d80n.h"
|
||||||
|
#include "aicwf_compat_8800dln.h"
|
||||||
#ifdef CONFIG_USE_FW_REQUEST
|
#ifdef CONFIG_USE_FW_REQUEST
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -190,6 +192,15 @@ userconfig_info_t userconfig_info = {
|
|||||||
.pwrofst2x_tbl_6g_ant0 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229
|
.pwrofst2x_tbl_6g_ant0 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229
|
||||||
.pwrofst2x_tbl_6g_ant1 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229
|
.pwrofst2x_tbl_6g_ant1 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229
|
||||||
},
|
},
|
||||||
|
.txpwr_ofst2x_v3 = {
|
||||||
|
.enable = 0,
|
||||||
|
.pwrofst2x_tbl_2g4 =
|
||||||
|
{ // ch1-4, ch5-9, ch10-13
|
||||||
|
{ 0, 0, 0 }, // 11b
|
||||||
|
{ 0, 0, 0 }, // ofdm_highrate
|
||||||
|
{ 0, 0, 0 }, // ofdm_lowrate
|
||||||
|
},
|
||||||
|
},
|
||||||
.xtal_cap = {
|
.xtal_cap = {
|
||||||
.enable = 0,
|
.enable = 0,
|
||||||
.xtal_cap = 24,
|
.xtal_cap = 24,
|
||||||
@@ -248,6 +259,7 @@ reg_table reg_tables[] = {
|
|||||||
{.ccode = "CL", .region = REGIONS_ETSI},
|
{.ccode = "CL", .region = REGIONS_ETSI},
|
||||||
{.ccode = "CO", .region = REGIONS_FCC},
|
{.ccode = "CO", .region = REGIONS_FCC},
|
||||||
{.ccode = "CR", .region = REGIONS_FCC},
|
{.ccode = "CR", .region = REGIONS_FCC},
|
||||||
|
{.ccode = "CU", .region = REGIONS_FCC},
|
||||||
{.ccode = "CX", .region = REGIONS_FCC},
|
{.ccode = "CX", .region = REGIONS_FCC},
|
||||||
{.ccode = "CY", .region = REGIONS_ETSI},
|
{.ccode = "CY", .region = REGIONS_ETSI},
|
||||||
{.ccode = "CZ", .region = REGIONS_ETSI},
|
{.ccode = "CZ", .region = REGIONS_ETSI},
|
||||||
@@ -272,7 +284,7 @@ reg_table reg_tables[] = {
|
|||||||
{.ccode = "GL", .region = REGIONS_ETSI},
|
{.ccode = "GL", .region = REGIONS_ETSI},
|
||||||
{.ccode = "GP", .region = REGIONS_ETSI},
|
{.ccode = "GP", .region = REGIONS_ETSI},
|
||||||
{.ccode = "GR", .region = REGIONS_ETSI},
|
{.ccode = "GR", .region = REGIONS_ETSI},
|
||||||
{.ccode = "GT", .region = REGIONS_FCC},
|
{.ccode = "GT", .region = REGIONS_DEFAULT},
|
||||||
{.ccode = "GU", .region = REGIONS_FCC},
|
{.ccode = "GU", .region = REGIONS_FCC},
|
||||||
{.ccode = "GY", .region = REGIONS_DEFAULT},
|
{.ccode = "GY", .region = REGIONS_DEFAULT},
|
||||||
{.ccode = "HK", .region = REGIONS_ETSI},
|
{.ccode = "HK", .region = REGIONS_ETSI},
|
||||||
@@ -285,7 +297,7 @@ reg_table reg_tables[] = {
|
|||||||
{.ccode = "IL", .region = REGIONS_ETSI},
|
{.ccode = "IL", .region = REGIONS_ETSI},
|
||||||
{.ccode = "IN", .region = REGIONS_ETSI},
|
{.ccode = "IN", .region = REGIONS_ETSI},
|
||||||
{.ccode = "IQ", .region = REGIONS_ETSI},
|
{.ccode = "IQ", .region = REGIONS_ETSI},
|
||||||
{.ccode = "IR", .region = REGIONS_JP},
|
{.ccode = "IR", .region = REGIONS_ETSI},
|
||||||
{.ccode = "IS", .region = REGIONS_ETSI},
|
{.ccode = "IS", .region = REGIONS_ETSI},
|
||||||
{.ccode = "IT", .region = REGIONS_ETSI},
|
{.ccode = "IT", .region = REGIONS_ETSI},
|
||||||
{.ccode = "JM", .region = REGIONS_FCC},
|
{.ccode = "JM", .region = REGIONS_FCC},
|
||||||
@@ -295,7 +307,7 @@ reg_table reg_tables[] = {
|
|||||||
{.ccode = "KH", .region = REGIONS_ETSI},
|
{.ccode = "KH", .region = REGIONS_ETSI},
|
||||||
{.ccode = "KN", .region = REGIONS_ETSI},
|
{.ccode = "KN", .region = REGIONS_ETSI},
|
||||||
{.ccode = "KP", .region = REGIONS_JP},
|
{.ccode = "KP", .region = REGIONS_JP},
|
||||||
{.ccode = "KR", .region = REGIONS_ETSI},
|
{.ccode = "KR", .region = REGIONS_KCC},
|
||||||
{.ccode = "KW", .region = REGIONS_ETSI},
|
{.ccode = "KW", .region = REGIONS_ETSI},
|
||||||
{.ccode = "KY", .region = REGIONS_FCC},
|
{.ccode = "KY", .region = REGIONS_FCC},
|
||||||
{.ccode = "KZ", .region = REGIONS_DEFAULT},
|
{.ccode = "KZ", .region = REGIONS_DEFAULT},
|
||||||
@@ -339,7 +351,7 @@ reg_table reg_tables[] = {
|
|||||||
{.ccode = "PF", .region = REGIONS_ETSI},
|
{.ccode = "PF", .region = REGIONS_ETSI},
|
||||||
{.ccode = "PG", .region = REGIONS_FCC},
|
{.ccode = "PG", .region = REGIONS_FCC},
|
||||||
{.ccode = "PH", .region = REGIONS_FCC},
|
{.ccode = "PH", .region = REGIONS_FCC},
|
||||||
{.ccode = "PK", .region = REGIONS_ETSI},
|
{.ccode = "PK", .region = REGIONS_DEFAULT},
|
||||||
{.ccode = "PL", .region = REGIONS_ETSI},
|
{.ccode = "PL", .region = REGIONS_ETSI},
|
||||||
{.ccode = "PM", .region = REGIONS_ETSI},
|
{.ccode = "PM", .region = REGIONS_ETSI},
|
||||||
{.ccode = "PR", .region = REGIONS_FCC},
|
{.ccode = "PR", .region = REGIONS_FCC},
|
||||||
@@ -361,7 +373,7 @@ reg_table reg_tables[] = {
|
|||||||
{.ccode = "SN", .region = REGIONS_FCC},
|
{.ccode = "SN", .region = REGIONS_FCC},
|
||||||
{.ccode = "SR", .region = REGIONS_ETSI},
|
{.ccode = "SR", .region = REGIONS_ETSI},
|
||||||
{.ccode = "SV", .region = REGIONS_FCC},
|
{.ccode = "SV", .region = REGIONS_FCC},
|
||||||
{.ccode = "SY", .region = REGIONS_DEFAULT},
|
{.ccode = "SY", .region = REGIONS_ETSI},
|
||||||
{.ccode = "TC", .region = REGIONS_FCC},
|
{.ccode = "TC", .region = REGIONS_FCC},
|
||||||
{.ccode = "TD", .region = REGIONS_ETSI},
|
{.ccode = "TD", .region = REGIONS_ETSI},
|
||||||
{.ccode = "TG", .region = REGIONS_ETSI},
|
{.ccode = "TG", .region = REGIONS_ETSI},
|
||||||
@@ -372,6 +384,7 @@ reg_table reg_tables[] = {
|
|||||||
{.ccode = "TR", .region = REGIONS_ETSI},
|
{.ccode = "TR", .region = REGIONS_ETSI},
|
||||||
{.ccode = "TT", .region = REGIONS_FCC},
|
{.ccode = "TT", .region = REGIONS_FCC},
|
||||||
{.ccode = "TW", .region = REGIONS_FCC},
|
{.ccode = "TW", .region = REGIONS_FCC},
|
||||||
|
{.ccode = "TZ", .region = REGIONS_ETSI},
|
||||||
{.ccode = "UA", .region = REGIONS_ETSI},
|
{.ccode = "UA", .region = REGIONS_ETSI},
|
||||||
{.ccode = "UG", .region = REGIONS_FCC},
|
{.ccode = "UG", .region = REGIONS_FCC},
|
||||||
{.ccode = "UY", .region = REGIONS_FCC},
|
{.ccode = "UY", .region = REGIONS_FCC},
|
||||||
@@ -382,10 +395,13 @@ reg_table reg_tables[] = {
|
|||||||
{.ccode = "VN", .region = REGIONS_JP},
|
{.ccode = "VN", .region = REGIONS_JP},
|
||||||
{.ccode = "VU", .region = REGIONS_FCC},
|
{.ccode = "VU", .region = REGIONS_FCC},
|
||||||
{.ccode = "WF", .region = REGIONS_ETSI},
|
{.ccode = "WF", .region = REGIONS_ETSI},
|
||||||
|
{.ccode = "WS", .region = REGIONS_ETSI},
|
||||||
{.ccode = "YE", .region = REGIONS_DEFAULT},
|
{.ccode = "YE", .region = REGIONS_DEFAULT},
|
||||||
{.ccode = "YT", .region = REGIONS_ETSI},
|
{.ccode = "YT", .region = REGIONS_ETSI},
|
||||||
{.ccode = "ZA", .region = REGIONS_ETSI},
|
{.ccode = "ZA", .region = REGIONS_ETSI},
|
||||||
{.ccode = "ZM", .region = REGIONS_ETSI},
|
{.ccode = "ZM", .region = REGIONS_ETSI},
|
||||||
|
{.ccode = "FO", .region = REGIONS_ETSI},
|
||||||
|
{.ccode = "FK", .region = REGIONS_ETSI},
|
||||||
{.ccode = "ZW", .region = REGIONS_ETSI},
|
{.ccode = "ZW", .region = REGIONS_ETSI},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -417,6 +433,8 @@ u8 get_region_index(char * name)
|
|||||||
return REGIONS_ETSI;
|
return REGIONS_ETSI;
|
||||||
else if (strncmp(name, "JP", 2) == 0)
|
else if (strncmp(name, "JP", 2) == 0)
|
||||||
return REGIONS_JP;
|
return REGIONS_JP;
|
||||||
|
else if (strncmp(name, "KCC", 3) == 0)
|
||||||
|
return REGIONS_KCC;
|
||||||
else if (strncmp(name, "UNSET", 5) == 0)
|
else if (strncmp(name, "UNSET", 5) == 0)
|
||||||
return REGIONS_DEFAULT;
|
return REGIONS_DEFAULT;
|
||||||
|
|
||||||
@@ -424,6 +442,7 @@ u8 get_region_index(char * name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_POWER_LIMIT
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
#define POWER_LIMIT_INVALID_VAL POWER_LEVEL_INVALID_VAL
|
#define POWER_LIMIT_INVALID_VAL POWER_LEVEL_INVALID_VAL
|
||||||
|
|
||||||
@@ -431,7 +450,7 @@ u8 get_region_index(char * name)
|
|||||||
|
|
||||||
#define MAX_2_4G_BW_NUM 2
|
#define MAX_2_4G_BW_NUM 2
|
||||||
#define MAX_5G_BW_NUM 3
|
#define MAX_5G_BW_NUM 3
|
||||||
#define MAX_REGION_NUM 5
|
#define MAX_REGION_NUM 6
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -685,7 +704,7 @@ static int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *dev
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* start to read from firmware file */
|
/* start to read from firmware file */
|
||||||
buffer = vmalloc(size);
|
buffer = vmalloc(size + 1);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
*fw_buf = NULL;
|
*fw_buf = NULL;
|
||||||
__putname(path);
|
__putname(path);
|
||||||
@@ -700,6 +719,7 @@ static int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *dev
|
|||||||
rdlen = kernel_read(fp, fp->f_pos, buffer, size);
|
rdlen = kernel_read(fp, fp->f_pos, buffer, size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
*((char*)buffer + size) = 0;
|
||||||
if (size != rdlen) {
|
if (size != rdlen) {
|
||||||
AICWFDBG(LOGERROR, "%s: %s file rdlen invalid %d\n", __func__, name, (int)rdlen);
|
AICWFDBG(LOGERROR, "%s: %s file rdlen invalid %d\n", __func__, name, (int)rdlen);
|
||||||
*fw_buf = NULL;
|
*fw_buf = NULL;
|
||||||
@@ -836,6 +856,69 @@ int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rwnx_plat_bin_fw_upload_2_with_version(struct rwnx_hw *rwnx_hw, u32 fw_addr,
|
||||||
|
char *filename, char *version_str, int version_size)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
unsigned int i = 0, size;
|
||||||
|
u32 *dst = NULL;
|
||||||
|
|
||||||
|
/* Copy the file on the Embedded side */
|
||||||
|
AICWFDBG(LOGINFO, "### Upload %s firmware, @ = %x\n", filename, fw_addr);
|
||||||
|
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
if (!dst) {
|
||||||
|
AICWFDBG(LOGERROR, "No such file or directory\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (size <= 0) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
|
||||||
|
dst = NULL;
|
||||||
|
err = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO, "size=%d, dst[0]=%x\n", size, dst[0]);
|
||||||
|
// get version if exist
|
||||||
|
if (version_str) {
|
||||||
|
char *bin_str = (char *)&dst[4];
|
||||||
|
int char_idx = 0;
|
||||||
|
for (char_idx = 0; char_idx < version_size; char_idx++) {
|
||||||
|
version_str[char_idx] = bin_str[char_idx];
|
||||||
|
if (bin_str[char_idx] == '\0') {
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (char_idx == version_size) {
|
||||||
|
version_str[version_size - 1] = '\0';
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO, "version_str=%s\n", version_str);
|
||||||
|
}
|
||||||
|
// upload
|
||||||
|
if (size > 512) {
|
||||||
|
for (; i < (size - 512); i += 512) {
|
||||||
|
//printk("wr blk 0: %p -> %x\r\n", dst + i / 4, fw_addr + i);
|
||||||
|
err = rwnx_send_dbg_mem_block_write_req(rwnx_hw, fw_addr + i, 512, dst + i / 4);
|
||||||
|
if (err) {
|
||||||
|
AICWFDBG(LOGERROR, "bin upload fail: %x, err:%d\r\n", fw_addr + i, err);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!err && (i < size)) {
|
||||||
|
//printk("wr blk 1: %p -> %x\r\n", dst + i / 4, fw_addr + i);
|
||||||
|
err = rwnx_send_dbg_mem_block_write_req(rwnx_hw, fw_addr + i, size - i, dst + i / 4);
|
||||||
|
if (err) {
|
||||||
|
AICWFDBG(LOGERROR, "bin upload fail: %x, err:%d\r\n", fw_addr + i, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst) {
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CONFIG_ROM_PATCH_EN
|
#ifndef CONFIG_ROM_PATCH_EN
|
||||||
@@ -1586,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) {
|
||||||
@@ -1723,8 +1807,54 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
|
|||||||
return 1; // exit calib mode
|
return 1; // exit calib mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) {
|
||||||
|
#ifndef ANDROID_PLATFORM
|
||||||
|
if (strlcat(aic_fw_path, "/aic8800D80N", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||||
|
return -ENAMETOOLONG;
|
||||||
|
#endif
|
||||||
|
if (testmode == FW_NORMAL_MODE) {
|
||||||
|
ret = aicwf_plat_patch_load_8800d80n(rwnx_hw);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "patch upload fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = aicwf_plat_patch_table_load_8800d80n(rwnx_hw);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "patch_tbl upload fail: %d\r\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
aicwf_patch_config_8800d80n(rwnx_hw);
|
||||||
|
#if DEF_PATCH_METHOD_VER_2
|
||||||
|
aicwf_plat_cinit_exec_8800d80n(rwnx_hw);
|
||||||
|
aicwf_plat_calib_exec_8800d80n(rwnx_hw);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (testmode == FW_RFTEST_MODE) {
|
||||||
|
AICWFDBG(LOGINFO, "%s load rftest bin\n", __func__);
|
||||||
|
ret = aicwf_plat_rftest_load_8800d80n(rwnx_hw);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGERROR, "load rftest bin fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN) {
|
||||||
|
#ifndef ANDROID_PLATFORM
|
||||||
|
if (strlcat(aic_fw_path, "/aic8800DLN", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||||
|
return -ENAMETOOLONG;
|
||||||
|
#endif
|
||||||
|
if (testmode == FW_NORMAL_MODE) {
|
||||||
|
aicwf_patch_config_8800dln(rwnx_hw);
|
||||||
|
}
|
||||||
|
else if (testmode == FW_RFTEST_MODE) {
|
||||||
|
AICWFDBG(LOGINFO, "%s load rftest bin\n", __func__);
|
||||||
|
ret = aicwf_plat_rftest_load_8800dln(rwnx_hw);
|
||||||
|
if (ret) {
|
||||||
|
AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2242,6 +2372,16 @@ void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj)
|
|||||||
AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_155:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[5]);
|
AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_155:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_userconfig_txpwr_lvl_adj_v2_in_fdrv(txpwr_lvl_adj_conf_v2_t *txpwr_lvl_adj_v2)
|
||||||
|
{
|
||||||
|
*txpwr_lvl_adj_v2 = userconfig_info.txpwr_lvl_adj_v2;
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_adj_v2->enable);
|
||||||
|
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_1_4:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[0]);
|
||||||
|
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_5_9:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[1]);
|
||||||
|
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_10_13:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst)
|
void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst)
|
||||||
{
|
{
|
||||||
@@ -2311,6 +2451,23 @@ void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x
|
|||||||
}
|
}
|
||||||
AICWFDBG(LOGINFO, "\n");
|
AICWFDBG(LOGINFO, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_userconfig_txpwr_ofst2x_v3_in_fdrv(txpwr_ofst2x_conf_v3_t *txpwr_ofst2x_v3)
|
||||||
|
{
|
||||||
|
int type, ch_grp;
|
||||||
|
*txpwr_ofst2x_v3 = userconfig_info.txpwr_ofst2x_v3;
|
||||||
|
AICWFDBG(LOGINFO, "%s:enable :%d\r\n", __func__, txpwr_ofst2x_v3->enable);
|
||||||
|
AICWFDBG(LOGINFO, "pwrofst2x 2.4g: [0]:11b, [1]:ofdm_highrate, [2]:ofdm_lowrate\n"
|
||||||
|
" chan=" "\t1-4" "\t5-9" "\t10-13");
|
||||||
|
for (type = 0; type < 3; type++) {
|
||||||
|
AICWFDBG(LOGINFO, "\n [%d] =", type);
|
||||||
|
for (ch_grp = 0; ch_grp < 3; ch_grp++) {
|
||||||
|
AICWFDBG(LOGINFO, "\t%d", txpwr_ofst2x_v3->pwrofst2x_tbl_2g4[type][ch_grp]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGINFO, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss)
|
void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss)
|
||||||
{
|
{
|
||||||
txpwr_loss->loss_enable_2g4 = userconfig_info.txpwr_loss.loss_enable_2g4;
|
txpwr_loss->loss_enable_2g4 = userconfig_info.txpwr_loss.loss_enable_2g4;
|
||||||
@@ -2322,6 +2479,101 @@ void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss)
|
|||||||
txpwr_loss->loss_enable_2g4, txpwr_loss->loss_value_2g4,
|
txpwr_loss->loss_enable_2g4, txpwr_loss->loss_value_2g4,
|
||||||
txpwr_loss->loss_enable_5g, txpwr_loss->loss_value_5g);
|
txpwr_loss->loss_enable_5g, txpwr_loss->loss_value_5g);
|
||||||
}
|
}
|
||||||
|
s8_l get_txpwr_max(s8_l power)
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
if(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 ||
|
||||||
|
g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D89X2 ){
|
||||||
|
for (i = 0; i <= 11; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i <= 9; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i <= 11; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i <= 7; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i <= 9; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i <= 11; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((userconfig_info.txpwr_loss.loss_enable_2g4 == 1) ||
|
||||||
|
(userconfig_info.txpwr_loss.loss_enable_5g == 1)) {
|
||||||
|
if (userconfig_info.txpwr_loss.loss_value_2g4 <
|
||||||
|
userconfig_info.txpwr_loss.loss_value_5g)
|
||||||
|
power += userconfig_info.txpwr_loss.loss_value_5g;
|
||||||
|
else
|
||||||
|
power += userconfig_info.txpwr_loss.loss_value_2g4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81 ||
|
||||||
|
g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D80N){
|
||||||
|
for (i = 0; i <= 11; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i <= 9; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i <= 11; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[i];
|
||||||
|
}
|
||||||
|
for (i = 4; i <= 11; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i <= 9; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i <= 11; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((userconfig_info.txpwr_loss.loss_enable_2g4 == 1) ||
|
||||||
|
(userconfig_info.txpwr_loss.loss_enable_5g == 1)) {
|
||||||
|
if (userconfig_info.txpwr_loss.loss_value_2g4 <
|
||||||
|
userconfig_info.txpwr_loss.loss_value_5g)
|
||||||
|
power += userconfig_info.txpwr_loss.loss_value_5g;
|
||||||
|
else
|
||||||
|
power += userconfig_info.txpwr_loss.loss_value_2g4;
|
||||||
|
}
|
||||||
|
|
||||||
|
}else if(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DC || g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW){
|
||||||
|
for (i = 0; i <= 11; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i <= 9; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i <= 11; i++){
|
||||||
|
if(power < userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[i])
|
||||||
|
power = userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "%s:txpwr_max:%d \r\n",__func__,power);
|
||||||
|
return power;
|
||||||
|
}
|
||||||
|
|
||||||
void set_txpwr_loss_ofst(s8_l value)
|
void set_txpwr_loss_ofst(s8_l value)
|
||||||
{
|
{
|
||||||
userconfig_info.txpwr_loss.loss_enable_2g4 = 1;
|
userconfig_info.txpwr_loss.loss_enable_2g4 = 1;
|
||||||
@@ -3115,7 +3367,7 @@ int8_t rwnx_plat_powerlimit_save(u8_l band, char *channel, u8_l bw, char *limit,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rwnx_plat_powerlimit_parsing(char *buffer, int size, char *cc)
|
void rwnx_plat_powerlimit_parsing(char *buffer, int size)
|
||||||
{
|
{
|
||||||
#define LD_STAGE_EXC_MAPPING 0
|
#define LD_STAGE_EXC_MAPPING 0
|
||||||
#define LD_STAGE_TAB_DEFINE 1
|
#define LD_STAGE_TAB_DEFINE 1
|
||||||
@@ -3465,11 +3717,21 @@ static int rwnx_plat_userconfig_load(struct rwnx_hw *rwnx_hw) {
|
|||||||
#ifdef CONFIG_POWER_LIMIT
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
rwnx_plat_powerlimit_load_8800dcdw(rwnx_hw, PRODUCT_ID_AIC8800DW);
|
rwnx_plat_powerlimit_load_8800dcdw(rwnx_hw, PRODUCT_ID_AIC8800DW);
|
||||||
#endif
|
#endif
|
||||||
|
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN){
|
||||||
|
rwnx_plat_userconfig_load_8800dln(rwnx_hw);
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
rwnx_plat_powerlimit_load_8800dln(rwnx_hw);
|
||||||
|
#endif
|
||||||
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){
|
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){
|
||||||
rwnx_plat_userconfig_load_8800d80(rwnx_hw);
|
rwnx_plat_userconfig_load_8800d80(rwnx_hw);
|
||||||
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 ||
|
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 ||
|
||||||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
|
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
|
||||||
rwnx_plat_userconfig_load_8800d80x2(rwnx_hw);
|
rwnx_plat_userconfig_load_8800d80x2(rwnx_hw);
|
||||||
|
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N){
|
||||||
|
rwnx_plat_userconfig_load_8800d80n(rwnx_hw);
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
rwnx_plat_powerlimit_load_8800d80n(rwnx_hw);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -71,10 +71,12 @@ typedef struct
|
|||||||
txpwr_lvl_conf_v3_t txpwr_lvl_v3;
|
txpwr_lvl_conf_v3_t txpwr_lvl_v3;
|
||||||
txpwr_lvl_conf_v4_t txpwr_lvl_v4;
|
txpwr_lvl_conf_v4_t txpwr_lvl_v4;
|
||||||
txpwr_lvl_adj_conf_t txpwr_lvl_adj;
|
txpwr_lvl_adj_conf_t txpwr_lvl_adj;
|
||||||
|
txpwr_lvl_adj_conf_v2_t txpwr_lvl_adj_v2;
|
||||||
txpwr_loss_conf_t txpwr_loss;
|
txpwr_loss_conf_t txpwr_loss;
|
||||||
txpwr_ofst_conf_t txpwr_ofst;
|
txpwr_ofst_conf_t txpwr_ofst;
|
||||||
txpwr_ofst2x_conf_t txpwr_ofst2x;
|
txpwr_ofst2x_conf_t txpwr_ofst2x;
|
||||||
txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2;
|
txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2;
|
||||||
|
txpwr_ofst2x_conf_v3_t txpwr_ofst2x_v3;
|
||||||
xtal_cap_conf_t xtal_cap;
|
xtal_cap_conf_t xtal_cap;
|
||||||
} userconfig_info_t;
|
} userconfig_info_t;
|
||||||
|
|
||||||
@@ -85,6 +87,7 @@ typedef enum {
|
|||||||
REGIONS_FCC,
|
REGIONS_FCC,
|
||||||
REGIONS_ETSI,
|
REGIONS_ETSI,
|
||||||
REGIONS_JP,
|
REGIONS_JP,
|
||||||
|
REGIONS_KCC,
|
||||||
REGIONS_DEFAULT,
|
REGIONS_DEFAULT,
|
||||||
} Regions_code;
|
} Regions_code;
|
||||||
|
|
||||||
@@ -156,10 +159,13 @@ void get_userconfig_txpwr_lvl_v2_in_fdrv(txpwr_lvl_conf_v2_t *txpwr_lvl_v2);
|
|||||||
void get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_conf_v3_t *txpwr_lvl_v3);
|
void get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_conf_v3_t *txpwr_lvl_v3);
|
||||||
void get_userconfig_txpwr_lvl_v4_in_fdrv(txpwr_lvl_conf_v4_t *txpwr_lvl_v4);
|
void get_userconfig_txpwr_lvl_v4_in_fdrv(txpwr_lvl_conf_v4_t *txpwr_lvl_v4);
|
||||||
void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj);
|
void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj);
|
||||||
|
void get_userconfig_txpwr_lvl_adj_v2_in_fdrv(txpwr_lvl_adj_conf_v2_t *txpwr_lvl_adj_v2);
|
||||||
void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst);
|
void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst);
|
||||||
void get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x_conf_t *txpwr_ofst2x);
|
void get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x_conf_t *txpwr_ofst2x);
|
||||||
void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x_v2);
|
void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x_v2);
|
||||||
|
void get_userconfig_txpwr_ofst2x_v3_in_fdrv(txpwr_ofst2x_conf_v3_t *txpwr_ofst2x_v3);
|
||||||
void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss);
|
void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss);
|
||||||
|
s8_l get_txpwr_max(s8_l power);
|
||||||
void set_txpwr_loss_ofst(s8_l value);
|
void set_txpwr_loss_ofst(s8_l value);
|
||||||
void rwnx_plat_userconfig_parsing(char *buffer, int size);
|
void rwnx_plat_userconfig_parsing(char *buffer, int size);
|
||||||
|
|
||||||
@@ -169,7 +175,7 @@ u8 get_region_index(char * name);
|
|||||||
|
|
||||||
#ifdef CONFIG_POWER_LIMIT
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
int8_t rwnx_plat_powerlimit_save(u8_l band, char *channel, u8_l bw, char *limit, char *name);
|
int8_t rwnx_plat_powerlimit_save(u8_l band, char *channel, u8_l bw, char *limit, char *name);
|
||||||
void rwnx_plat_powerlimit_parsing(char *buffer, int size, char *cc);
|
void rwnx_plat_powerlimit_parsing(char *buffer, int size);
|
||||||
int8_t get_powerlimit_by_freq(uint8_t band, uint16_t freq, uint8_t r_idx);
|
int8_t get_powerlimit_by_freq(uint8_t band, uint16_t freq, uint8_t r_idx);
|
||||||
int8_t get_powerlimit_by_chnum(uint8_t chnum, uint8_t r_idx, uint8_t bw);
|
int8_t get_powerlimit_by_chnum(uint8_t chnum, uint8_t r_idx, uint8_t bw);
|
||||||
#endif
|
#endif
|
||||||
@@ -182,5 +188,17 @@ static inline unsigned int rwnx_platform_get_irq(struct rwnx_plat *rwnx_plat)
|
|||||||
{
|
{
|
||||||
return rwnx_plat->pci_dev->irq;
|
return rwnx_plat->pci_dev->irq;
|
||||||
}
|
}
|
||||||
|
int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw, u32** buffer, const char *filename);
|
||||||
|
void rwnx_release_firmware_common(u32** buffer);
|
||||||
|
int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
|
||||||
|
char *filename);
|
||||||
|
int rwnx_plat_bin_fw_upload_2_with_version(struct rwnx_hw *rwnx_hw, u32 fw_addr,
|
||||||
|
char *filename, char *version_str, int version_size);
|
||||||
|
int rwnx_atoi2(char *value, int c_len);
|
||||||
|
int rwnx_atoi(char *value);
|
||||||
|
void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap);
|
||||||
|
void rwnx_plat_nvram_set_value(char *command, char *value);
|
||||||
|
void rwnx_plat_nvram_set_value_8800d80x2(char *command, char *value);
|
||||||
|
void rwnx_plat_userconfig_parsing_8800d80x2(char *buffer, int size);
|
||||||
|
|
||||||
#endif /* _RWNX_PLATFORM_H_ */
|
#endif /* _RWNX_PLATFORM_H_ */
|
||||||
|
|||||||
@@ -182,28 +182,27 @@ static const struct radar_types fcc_radar_types = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define JP_PATTERN FCC_PATTERN
|
#define JP_PATTERN FCC_PATTERN
|
||||||
|
//JP_PATTERN(1, 2, 8, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||||
static const struct radar_detector_specs jp_radar_ref_types_riu[] = {
|
static const struct radar_detector_specs jp_radar_ref_types_riu[] = {
|
||||||
JP_PATTERN(0, 0, 8, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(0, 0, 4, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(1, 2, 8, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(1, 0, 4, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(2, 0, 8, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(2, 0, 4, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(3, 0, 8, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(3, 0, 6, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(4, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(4, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(5, 6, 20, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(5, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(6, 10, 28, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(6, 48, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG),
|
||||||
JP_PATTERN(7, 50, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG),
|
JP_PATTERN(7, 0, 4, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(8, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct radar_detector_specs jp_radar_ref_types_fcu[] = {
|
static const struct radar_detector_specs jp_radar_ref_types_fcu[] = {
|
||||||
JP_PATTERN(0, 0, 8, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(0, 0, 4, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(1, 2, 6, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(1, 0, 4, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(2, 0, 8, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(2, 0, 4, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(3, 2, 2, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(3, 0, 6, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(4, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(4, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(5, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(5, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(6, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT),
|
JP_PATTERN(6, 48, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG),
|
||||||
JP_PATTERN(7, 50, 104, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG),
|
JP_PATTERN(7, 0, 4, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
|
||||||
JP_PATTERN(8, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct radar_types jp_radar_types = {
|
static const struct radar_types jp_radar_types = {
|
||||||
@@ -219,33 +218,6 @@ static const struct radar_types *dfs_domains[] = {
|
|||||||
&jp_radar_types,
|
&jp_radar_types,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct pri_sequence - sequence of pulses matching one PRI
|
|
||||||
* @head: list_head
|
|
||||||
* @pri: pulse repetition interval (PRI) in usecs
|
|
||||||
* @dur: duration of sequence in usecs
|
|
||||||
* @count: number of pulses in this sequence
|
|
||||||
* @count_falses: number of not matching pulses in this sequence
|
|
||||||
* @first_ts: time stamp of first pulse in usecs
|
|
||||||
* @last_ts: time stamp of last pulse in usecs
|
|
||||||
* @deadline_ts: deadline when this sequence becomes invalid (first_ts + dur)
|
|
||||||
* @ppb_thresh: Number of pulses to validate detection
|
|
||||||
* (need for weather radar whose value depends of pri)
|
|
||||||
*/
|
|
||||||
struct pri_sequence {
|
|
||||||
struct list_head head;
|
|
||||||
u32 pri;
|
|
||||||
u32 dur;
|
|
||||||
u32 count;
|
|
||||||
u32 count_falses;
|
|
||||||
u64 first_ts;
|
|
||||||
u64 last_ts;
|
|
||||||
u64 deadline_ts;
|
|
||||||
u8 ppb_thresh;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct pulse_elem - elements in pulse queue
|
* struct pulse_elem - elements in pulse queue
|
||||||
* @ts: time stamp in usecs
|
* @ts: time stamp in usecs
|
||||||
@@ -804,9 +776,9 @@ struct pri_sequence *pde_long_add_pulse(struct rwnx_radar *radar, struct pri_det
|
|||||||
struct pri_sequence *ps;
|
struct pri_sequence *ps;
|
||||||
const struct radar_detector_specs *rs = pde->rs;
|
const struct radar_detector_specs *rs = pde->rs;
|
||||||
|
|
||||||
if(radar->status != RWNX_RADAR_CAC_BUSY) {
|
//if(radar->status != RWNX_RADAR_CAC_BUSY) {
|
||||||
return NULL;
|
// return NULL;
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (list_empty(&pde->sequences)) {
|
if (list_empty(&pde->sequences)) {
|
||||||
/* First pulse, create a new sequence */
|
/* First pulse, create a new sequence */
|
||||||
@@ -1407,6 +1379,29 @@ static void rwnx_radar_process_pulse(struct work_struct *ws)
|
|||||||
rm->ts[rm->idx] = dpd->last_pulse_ts + pri;
|
rm->ts[rm->idx] = dpd->last_pulse_ts + pri;
|
||||||
}
|
}
|
||||||
rm->idx = (rm->idx + 1) % RWNX_RADARR_DUMP_NB;
|
rm->idx = (rm->idx + 1) % RWNX_RADARR_DUMP_NB;
|
||||||
|
|
||||||
|
if(rm->cnt == 1)
|
||||||
|
{
|
||||||
|
struct radar_detector_specs *spc;
|
||||||
|
int k;
|
||||||
|
AICWFDBG(LOGINFO, "dpd: en = %d, region = %d, ntype = %d", dpd->enabled, dpd->region, dpd->num_radar_types);
|
||||||
|
AICWFDBG(LOGINFO, "id wid.{min, max} pri.{min, max, num}, ppb, thd, tlrn, type");
|
||||||
|
for (k = 0; k < dpd->num_radar_types; k++)
|
||||||
|
{
|
||||||
|
spc =(struct radar_detector_specs *)&dpd->radar_spec[k];
|
||||||
|
AICWFDBG(LOGINFO, "%d %3d, %3d %4d %4d %d %2d %2d %d %d",
|
||||||
|
spc->type_id,
|
||||||
|
spc->width_min,
|
||||||
|
spc->width_max,
|
||||||
|
spc->pri_min,
|
||||||
|
spc->pri_max,
|
||||||
|
spc->num_pri,
|
||||||
|
spc->ppb,
|
||||||
|
spc->ppb_thresh,
|
||||||
|
spc->max_pri_tolerance,
|
||||||
|
spc->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if((radar->status != RWNX_RADAR_CAC_BUSY) && (radar->status != RWNX_RADAR_INSERVICE_BUSY)) {
|
if((radar->status != RWNX_RADAR_CAC_BUSY) && (radar->status != RWNX_RADAR_INSERVICE_BUSY)) {
|
||||||
@@ -1480,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);
|
||||||
@@ -1602,6 +1597,7 @@ void rwnx_radar_start_cac(struct rwnx_radar *radar, u32 cac_time_ms,
|
|||||||
{
|
{
|
||||||
WARN(radar->cac_vif != NULL, "CAC already in progress");
|
WARN(radar->cac_vif != NULL, "CAC already in progress");
|
||||||
radar->cac_vif = vif;
|
radar->cac_vif = vif;
|
||||||
|
AICWFDBG(LOGINFO, "%s DFS: cac time = %u ms", __func__, cac_time_ms);
|
||||||
schedule_delayed_work(&radar->cac_work, msecs_to_jiffies(cac_time_ms));
|
schedule_delayed_work(&radar->cac_work, msecs_to_jiffies(cac_time_ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1621,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);
|
||||||
@@ -1714,8 +1710,8 @@ int rwnx_radar_dump_pattern_detector(char *buf, size_t len,
|
|||||||
}
|
}
|
||||||
size_needed += sizeof(info);
|
size_needed += sizeof(info);
|
||||||
|
|
||||||
return size_needed;
|
|
||||||
}
|
}
|
||||||
|
return size_needed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
|||||||
@@ -32,6 +32,34 @@ enum rwnx_radar_detector {
|
|||||||
radar to upper layer. */
|
radar to upper layer. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct pri_sequence - sequence of pulses matching one PRI
|
||||||
|
* @head: list_head
|
||||||
|
* @pri: pulse repetition interval (PRI) in usecs
|
||||||
|
* @dur: duration of sequence in usecs
|
||||||
|
* @count: number of pulses in this sequence
|
||||||
|
* @count_falses: number of not matching pulses in this sequence
|
||||||
|
* @first_ts: time stamp of first pulse in usecs
|
||||||
|
* @last_ts: time stamp of last pulse in usecs
|
||||||
|
* @deadline_ts: deadline when this sequence becomes invalid (first_ts + dur)
|
||||||
|
* @ppb_thresh: Number of pulses to validate detection
|
||||||
|
* (need for weather radar whose value depends of pri)
|
||||||
|
*/
|
||||||
|
struct pri_sequence {
|
||||||
|
struct list_head head;
|
||||||
|
u32 pri;
|
||||||
|
u32 dur;
|
||||||
|
u32 count;
|
||||||
|
u32 count_falses;
|
||||||
|
u64 first_ts;
|
||||||
|
u64 last_ts;
|
||||||
|
u64 deadline_ts;
|
||||||
|
u8 ppb_thresh;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_RWNX_RADAR
|
#ifdef CONFIG_RWNX_RADAR
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
@@ -137,6 +165,9 @@ int rwnx_radar_dump_pattern_detector(char *buf, size_t len,
|
|||||||
struct rwnx_radar *radar, u8 chain);
|
struct rwnx_radar *radar, u8 chain);
|
||||||
int rwnx_radar_dump_radar_detected(char *buf, size_t len,
|
int rwnx_radar_dump_radar_detected(char *buf, size_t len,
|
||||||
struct rwnx_radar *radar, u8 chain);
|
struct rwnx_radar *radar, u8 chain);
|
||||||
|
struct pri_detector *pri_detector_init(struct dfs_pattern_detector *dpd,
|
||||||
|
u16 radar_type, u16 freq);
|
||||||
|
void print_radar_detect_info(struct pri_detector *pde, struct pri_sequence *ps);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|||||||
@@ -812,6 +812,7 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
|||||||
aicwf_nl_send_frame_rpt_msg(rwnx_vif, WIFI_AUTH, mgmt->sa, rxvect->rssi1);
|
aicwf_nl_send_frame_rpt_msg(rwnx_vif, WIFI_AUTH, mgmt->sa, rxvect->rssi1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (ieee80211_is_probe_req(mgmt->frame_control)) {
|
if (ieee80211_is_probe_req(mgmt->frame_control)) {
|
||||||
if (!rwnx_vif->ap.start)
|
if (!rwnx_vif->ap.start)
|
||||||
return;
|
return;
|
||||||
@@ -830,6 +831,7 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
|||||||
AICWFDBG(LOGERROR, "usb probe_rsp pool full, drop %pM\n", mgmt->sa);
|
AICWFDBG(LOGERROR, "usb probe_rsp pool full, drop %pM\n", mgmt->sa);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1308,7 +1310,7 @@ static void rwnx_rx_add_rtap_hdr(struct rwnx_hw* rwnx_hw,
|
|||||||
|
|
||||||
// Check for HE frames
|
// Check for HE frames
|
||||||
if (rxvect->format_mod == FORMATMOD_HE_SU) {
|
if (rxvect->format_mod == FORMATMOD_HE_SU) {
|
||||||
struct ieee80211_radiotap_he he;
|
struct ieee80211_radiotap_he he = {0};
|
||||||
#define HE_PREP(f, val) cpu_to_le16(FIELD_PREP(IEEE80211_RADIOTAP_HE_##f, val))
|
#define HE_PREP(f, val) cpu_to_le16(FIELD_PREP(IEEE80211_RADIOTAP_HE_##f, val))
|
||||||
#define D1_KNOWN(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_##f##_KNOWN)
|
#define D1_KNOWN(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_##f##_KNOWN)
|
||||||
#define D2_KNOWN(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_##f##_KNOWN)
|
#define D2_KNOWN(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_##f##_KNOWN)
|
||||||
@@ -1364,8 +1366,18 @@ static void rwnx_rx_add_rtap_hdr(struct rwnx_hw* rwnx_hw,
|
|||||||
while ((pos - (u8 *)rtap) & 1)
|
while ((pos - (u8 *)rtap) & 1)
|
||||||
pos++;
|
pos++;
|
||||||
rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_HE);
|
rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_HE);
|
||||||
memcpy(pos, &he, sizeof(he));
|
put_unaligned_le16(le16_to_cpu(he.data1), pos);
|
||||||
pos += sizeof(he);
|
pos += 2;
|
||||||
|
put_unaligned_le16(le16_to_cpu(he.data2), pos);
|
||||||
|
pos += 2;
|
||||||
|
put_unaligned_le16(le16_to_cpu(he.data3), pos);
|
||||||
|
pos += 2;
|
||||||
|
put_unaligned_le16(le16_to_cpu(he.data4), pos);
|
||||||
|
pos += 2;
|
||||||
|
put_unaligned_le16(le16_to_cpu(he.data5), pos);
|
||||||
|
pos += 2;
|
||||||
|
put_unaligned_le16(le16_to_cpu(he.data6), pos);
|
||||||
|
pos += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rx Chains
|
// Rx Chains
|
||||||
@@ -1833,8 +1845,7 @@ bool reord_rxframes_process(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *pr
|
|||||||
return bPktInBuf;
|
return bPktInBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv,
|
void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *preorder_ctrl)
|
||||||
struct reord_ctrl *preorder_ctrl)
|
|
||||||
{
|
{
|
||||||
struct list_head *phead, *plist;
|
struct list_head *phead, *plist;
|
||||||
struct recv_msdu *prframe;
|
struct recv_msdu *prframe;
|
||||||
@@ -1927,8 +1938,6 @@ int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv,
|
|||||||
struct reord_ctrl_info *reord_info;
|
struct reord_ctrl_info *reord_info;
|
||||||
struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif;
|
struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif;
|
||||||
struct ethhdr *eh = (struct ethhdr *)(skb->data);
|
struct ethhdr *eh = (struct ethhdr *)(skb->data);
|
||||||
u8 *da = eh->h_dest;
|
|
||||||
u8 is_mcast = ((*da) & 0x01)? 1 : 0;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
struct recv_msdu *pframe;
|
struct recv_msdu *pframe;
|
||||||
@@ -1949,7 +1958,7 @@ int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv,
|
|||||||
preorder_ctrl = pframe->preorder_ctrl;
|
preorder_ctrl = pframe->preorder_ctrl;
|
||||||
pframe->is_amsdu = is_amsdu;
|
pframe->is_amsdu = is_amsdu;
|
||||||
|
|
||||||
if ((ntohs(eh->h_proto) == ETH_P_PAE) || is_mcast)
|
if (ntohs(eh->h_proto) == ETH_P_PAE)
|
||||||
return reord_single_frame_ind(rx_priv, pframe);
|
return reord_single_frame_ind(rx_priv, pframe);
|
||||||
|
|
||||||
if((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
|
if((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
|
||||||
@@ -2127,7 +2136,10 @@ void remove_sec_hdr_mgmt_frame(struct hw_rxhdr *hw_rxhdr,struct sk_buff *skb)
|
|||||||
if(!hw_rxhdr->hwvect.ga_frame){
|
if(!hw_rxhdr->hwvect.ga_frame){
|
||||||
if(((skb->data[0] & 0x0C) == 0) && (skb->data[1] & 0x40) == 0x40){ //protect management frame
|
if(((skb->data[0] & 0x0C) == 0) && (skb->data[1] & 0x40) == 0x40){ //protect management frame
|
||||||
printk("frame type %x\n",skb->data[0]);
|
printk("frame type %x\n",skb->data[0]);
|
||||||
if(hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_CCMP128){
|
if((hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_CCMP128) ||
|
||||||
|
(hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_CCMP256) ||
|
||||||
|
(hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_GCMP128) ||
|
||||||
|
(hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_GCMP256)) {
|
||||||
memcpy(mgmt_header,skb->data,hdr_len);
|
memcpy(mgmt_header,skb->data,hdr_len);
|
||||||
skb_pull(skb,8);
|
skb_pull(skb,8);
|
||||||
memcpy(skb->data,mgmt_header,hdr_len);
|
memcpy(skb->data,mgmt_header,hdr_len);
|
||||||
@@ -2250,7 +2262,14 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
|
|||||||
u8 is_amsdu = 0;
|
u8 is_amsdu = 0;
|
||||||
bool resend = false, forward = true;
|
bool resend = false, forward = true;
|
||||||
const struct ethhdr *eth;
|
const struct ethhdr *eth;
|
||||||
|
#ifdef CONFIG_SUPPORT_4ADDR
|
||||||
|
u8_l b_4addr = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BR_SUPPORT
|
||||||
|
int vif_idx;
|
||||||
|
struct rwnx_vif *vif_itr = NULL;
|
||||||
|
struct rwnx_sta *cur_sta;
|
||||||
|
#endif
|
||||||
REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_RWNXDATAIND);
|
REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_RWNXDATAIND);
|
||||||
hw_rxhdr = (struct hw_rxhdr *)skb->data;
|
hw_rxhdr = (struct hw_rxhdr *)skb->data;
|
||||||
|
|
||||||
@@ -2264,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 */
|
||||||
@@ -2326,15 +2350,26 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_reset_tail_pointer(skb);
|
if (!skb_monitor) {
|
||||||
skb->len = 0;
|
if (status == RX_STAT_MONITOR) {
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto check_len_update;
|
||||||
|
}
|
||||||
|
|
||||||
|
//skb_reset_tail_pointer(skb);
|
||||||
|
//skb->len = 0;
|
||||||
skb_reset_tail_pointer(skb_monitor);
|
skb_reset_tail_pointer(skb_monitor);
|
||||||
skb_monitor->len = 0;
|
skb_monitor->len = 0;
|
||||||
skb_put(skb_monitor, frm_len);
|
skb_put(skb_monitor, frm_len);
|
||||||
@@ -2375,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);
|
||||||
@@ -2389,8 +2424,26 @@ check_len_update:
|
|||||||
rwnx_rx_vector_convert(rwnx_hw,
|
rwnx_rx_vector_convert(rwnx_hw,
|
||||||
&hw_rxhdr->hwvect.rx_vect1,
|
&hw_rxhdr->hwvect.rx_vect1,
|
||||||
&hw_rxhdr->hwvect.rx_vect2);
|
&hw_rxhdr->hwvect.rx_vect2);
|
||||||
|
|
||||||
|
#ifndef CONFIG_SUPPORT_4ADDR
|
||||||
|
if (hw_rxhdr->flags_is_4addr) {
|
||||||
|
dev_err(rwnx_hw->dev, "4addr Frame received (%d), skb->len:%u\n", hw_rxhdr->flags_vif_idx, skb->len);
|
||||||
|
print_hex_dump(KERN_ERR,"4addr ",DUMP_PREFIX_NONE, 16, 1, skb->data, skb->len, false);
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
skb_pull(skb, msdu_offset + 2); //+2 since sdio allign 58->60
|
skb_pull(skb, msdu_offset + 2); //+2 since sdio allign 58->60
|
||||||
#define MAC_FCTRL_MOREFRAG 0x0400
|
#define MAC_FCTRL_MOREFRAG 0x0400
|
||||||
|
|
||||||
|
#ifdef CONFIG_SUPPORT_4ADDR
|
||||||
|
if (hw_rxhdr->flags_is_4addr) {
|
||||||
|
hdr_len += 6;
|
||||||
|
b_4addr = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
frame_ctrl = (skb->data[1] << 8) | skb->data[0];
|
frame_ctrl = (skb->data[1] << 8) | skb->data[0];
|
||||||
seq_num = ((skb->data[22] & 0xf0) >> 4) | (skb->data[23] << 4);
|
seq_num = ((skb->data[22] & 0xf0) >> 4) | (skb->data[23] << 4);
|
||||||
frag_num = (skb->data[22] & 0x0f);
|
frag_num = (skb->data[22] & 0x0f);
|
||||||
@@ -2398,28 +2451,86 @@ check_len_update:
|
|||||||
|
|
||||||
if ((skb->data[0] & 0x0f) == 0x08) {
|
if ((skb->data[0] & 0x0f) == 0x08) {
|
||||||
if ((skb->data[0] & 0x80) == 0x80) {//qos data
|
if ((skb->data[0] & 0x80) == 0x80) {//qos data
|
||||||
hdr_len = 26;
|
hdr_len += 2;
|
||||||
|
#ifdef CONFIG_SUPPORT_4ADDR
|
||||||
|
tid = b_4addr ? (skb->data[30] & 0x0F) : (skb->data[24] & 0x0F);
|
||||||
|
#else
|
||||||
tid = skb->data[24] & 0x0F;
|
tid = skb->data[24] & 0x0F;
|
||||||
|
#endif
|
||||||
is_qos = 1;
|
is_qos = 1;
|
||||||
|
#ifdef CONFIG_SUPPORT_4ADDR
|
||||||
|
if (b_4addr) {
|
||||||
|
if (skb->data[30] & 0x80)
|
||||||
|
is_amsdu = 1;
|
||||||
|
} else {
|
||||||
if (skb->data[24] & 0x80)
|
if (skb->data[24] & 0x80)
|
||||||
is_amsdu = 1;
|
is_amsdu = 1;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (skb->data[24] & 0x80)
|
||||||
|
is_amsdu = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if(skb->data[1] & 0x80)// htc
|
if(skb->data[1] & 0x80)// htc
|
||||||
hdr_len += 4;
|
hdr_len += 4;
|
||||||
|
|
||||||
if((skb->data[1] & 0x3) == 0x1) {// to ds
|
#ifdef CONFIG_SUPPORT_4ADDR
|
||||||
memcpy(ra, &skb->data[16], MAC_ADDR_LEN);//destination addr
|
if (b_4addr) {
|
||||||
memcpy(ta, &skb->data[10], MAC_ADDR_LEN);//source addr
|
if ((skb->data[1] & 0x3) != 0x3) {
|
||||||
} else if((skb->data[1] & 0x3) == 0x2) { //from ds
|
printk("aicwf: 4addr DS error, to_from ds:%d\n", skb->data[1] & 0x3);
|
||||||
memcpy(ta, &skb->data[16], MAC_ADDR_LEN);//destination addr
|
print_hex_dump(KERN_ERR,"rx_4addr ",DUMP_PREFIX_NONE, 16, 1, skb->data, skb->len, false);
|
||||||
memcpy(ra, &skb->data[4], MAC_ADDR_LEN);//BSSID
|
|
||||||
}
|
}
|
||||||
|
memcpy(ra, &skb->data[16], MAC_ADDR_LEN);
|
||||||
|
memcpy(ta, &skb->data[24], MAC_ADDR_LEN);
|
||||||
|
printk("aicwf 4addr: da: %pM, sa: %pM\n", ra, ta);
|
||||||
|
} else {
|
||||||
|
//printk("aicwf: to_from ds:%d\n", skb->data[1] & 0x3);
|
||||||
|
if((skb->data[1] & 0x3) == 0x1) {// to ds
|
||||||
|
memcpy(ra, &skb->data[16], MAC_ADDR_LEN);
|
||||||
|
memcpy(ta, &skb->data[10], MAC_ADDR_LEN);
|
||||||
|
} else if((skb->data[1] & 0x3) == 0x2) { //from ds
|
||||||
|
memcpy(ta, &skb->data[16], MAC_ADDR_LEN);
|
||||||
|
memcpy(ra, &skb->data[4], MAC_ADDR_LEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if((skb->data[1] & 0x3) == 0x1) {// to ds
|
||||||
|
memcpy(ra, &skb->data[16], MAC_ADDR_LEN);
|
||||||
|
memcpy(ta, &skb->data[10], MAC_ADDR_LEN);
|
||||||
|
} else if((skb->data[1] & 0x3) == 0x2) { //from ds
|
||||||
|
memcpy(ta, &skb->data[16], MAC_ADDR_LEN);
|
||||||
|
memcpy(ra, &skb->data[4], MAC_ADDR_LEN);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BR_SUPPORT
|
||||||
|
if((skb->data[1] & 0x3) == 0x2) {
|
||||||
|
for (vif_idx = 0; vif_idx < NX_VIRT_DEV_MAX; vif_idx++) {
|
||||||
|
vif_itr = rwnx_hw->vif_table[vif_idx];
|
||||||
|
if (vif_itr && vif_itr->up && RWNX_VIF_TYPE(vif_itr) == NL80211_IFTYPE_AP) {
|
||||||
|
spin_lock_bh(&vif_itr->rwnx_hw->cb_lock);
|
||||||
|
list_for_each_entry(cur_sta, &vif_itr->ap.sta_list, list) {
|
||||||
|
if (!memcmp(cur_sta->mac_addr, ta, MAC_ADDR_LEN)) {
|
||||||
|
//printk("aicwf filter out, %pM\n", ta);
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
spin_unlock_bh(&vif_itr->rwnx_hw->cb_lock);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&vif_itr->rwnx_hw->cb_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pull_len += (hdr_len + 8);
|
pull_len += (hdr_len + 8);
|
||||||
|
|
||||||
switch (hw_rxhdr->hwvect.decr_status) {
|
switch (hw_rxhdr->hwvect.decr_status) {
|
||||||
case RWNX_RX_HD_DECR_CCMP128:
|
case RWNX_RX_HD_DECR_CCMP128:
|
||||||
|
case RWNX_RX_HD_DECR_CCMP256:
|
||||||
|
case RWNX_RX_HD_DECR_GCMP128:
|
||||||
|
case RWNX_RX_HD_DECR_GCMP256:
|
||||||
pull_len += 8;//ccmp_header
|
pull_len += 8;//ccmp_header
|
||||||
//skb_pull(&skb->data[skb->len-8], 8); //ccmp_mic_len
|
//skb_pull(&skb->data[skb->len-8], 8); //ccmp_mic_len
|
||||||
memcpy(ether_type, &skb->data[hdr_len + 6 + 8], 2);
|
memcpy(ether_type, &skb->data[hdr_len + 6 + 8], 2);
|
||||||
@@ -2441,17 +2552,33 @@ check_len_update:
|
|||||||
memcpy(ether_type, &skb->data[hdr_len + 6], 2);
|
memcpy(ether_type, &skb->data[hdr_len + 6], 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if((ether_type[0] == 0x8e && ether_type[1] == 0x88) || (ether_type[0] == 0x88 && ether_type[1] == 0x8e))
|
||||||
|
printk("rx eapol\n");
|
||||||
|
|
||||||
|
if (is_amsdu) {
|
||||||
|
//Check NETGEAR R7000 router's AMSDU packet format for compliance. start
|
||||||
|
AICWFDBG(LOGDEBUG, "%s is amsdu pkt pull_len:%d %x %x %x\r\n", __func__,
|
||||||
|
pull_len, skb->data[pull_len - 8],
|
||||||
|
skb->data[pull_len - 7],
|
||||||
|
skb->data[pull_len - 2]);
|
||||||
|
if (skb->data[pull_len - 8] == 0xAA &&
|
||||||
|
skb->data[pull_len - 7] == 0xAA &&
|
||||||
|
skb->data[pull_len - 2] > 0x06){
|
||||||
|
AICWFDBG(LOGERROR, "%s amsdu pkt not regular \r\n", __func__);
|
||||||
|
is_amsdu = 0;
|
||||||
|
}else{
|
||||||
|
skb_pull(skb, pull_len-8);
|
||||||
|
}
|
||||||
|
//Check NETGEAR R7000 router's AMSDU packet format for compliance. end
|
||||||
|
}
|
||||||
|
|
||||||
if(is_amsdu)
|
if(is_amsdu)
|
||||||
hw_rxhdr->flags_is_amsdu = 1;
|
hw_rxhdr->flags_is_amsdu = 1;
|
||||||
else
|
else
|
||||||
hw_rxhdr->flags_is_amsdu = 0;
|
hw_rxhdr->flags_is_amsdu = 0;
|
||||||
|
|
||||||
if((ether_type[0] == 0x8e && ether_type[1] == 0x88) || (ether_type[0] == 0x88 && ether_type[1] == 0x8e))
|
|
||||||
printk("rx eapol\n");
|
|
||||||
if (is_amsdu) {
|
|
||||||
skb_pull(skb, pull_len-8);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA)
|
if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA)
|
||||||
sta_idx = hw_rxhdr->flags_dst_idx;
|
sta_idx = hw_rxhdr->flags_dst_idx;
|
||||||
|
|
||||||
@@ -2629,7 +2756,8 @@ check_len_update:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) {
|
if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
printk("aicwf: 4addr flag error\n");
|
||||||
|
#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
|
||||||
@@ -2675,7 +2803,7 @@ check_len_update:
|
|||||||
|
|
||||||
#ifdef CONFIG_DYNAMIC_PERPWR
|
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||||
sta = &rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx];
|
sta = &rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx];
|
||||||
rssi_update_txpwrloss(sta, hw_rxhdr->hwvect.rx_vect1.rssi1);
|
rssi_update_txpwrloss(sta, hw_rxhdr->hwvect.rx_vect1.rssi1, rwnx_vif);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_BAND_STEERING
|
#ifdef CONFIG_BAND_STEERING
|
||||||
(&rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx])->rssi = hw_rxhdr->hwvect.rx_vect1.rssi1;
|
(&rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx])->rssi = hw_rxhdr->hwvect.rx_vect1.rssi1;
|
||||||
|
|||||||
@@ -353,10 +353,15 @@ struct DHCPInfo {
|
|||||||
u8 options[308]; /* 312 - cookie */
|
u8 options[308]; /* 312 - cookie */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int reord_flush_tid(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u8 tid);
|
||||||
|
bool reord_rxframes_process(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *preorder_ctrl, int bforced);
|
||||||
|
|
||||||
u8 rwnx_unsup_rx_vec_ind(void *pthis, void *hostid);
|
u8 rwnx_unsup_rx_vec_ind(void *pthis, void *hostid);
|
||||||
u8 rwnx_rxdataind(void *pthis, void *hostid);
|
u8 rwnx_rxdataind(void *pthis, void *hostid);
|
||||||
u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv);
|
u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv);
|
||||||
int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv);
|
int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv);
|
||||||
|
void rwnx_rx_data_skb_resend(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, struct sk_buff *skb);
|
||||||
|
|
||||||
#ifdef CONFIG_USB_MSG_IN_EP
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
int aicwf_process_msg_rxframes(struct aicwf_rx_priv *rx_priv);
|
int aicwf_process_msg_rxframes(struct aicwf_rx_priv *rx_priv);
|
||||||
#endif
|
#endif
|
||||||
@@ -373,11 +378,20 @@ int reord_need_check(struct reord_ctrl *preorder_ctrl, u16 seq_num);
|
|||||||
int reord_rxframe_enqueue(struct reord_ctrl *preorder_ctrl, struct recv_msdu *prframe);
|
int reord_rxframe_enqueue(struct reord_ctrl *preorder_ctrl, struct recv_msdu *prframe);
|
||||||
void reord_timeout_worker(struct work_struct *work);
|
void reord_timeout_worker(struct work_struct *work);
|
||||||
int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prframe);
|
int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prframe);
|
||||||
|
void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *preorder_ctrl);
|
||||||
|
void remove_sec_hdr_mgmt_frame(struct hw_rxhdr *hw_rxhdr,struct sk_buff *skb);
|
||||||
|
int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 seq_num, u8 tid, u8 forward, u8 is_amsdu);
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
|
||||||
void reord_timeout_handler (ulong data);
|
void reord_timeout_handler (ulong data);
|
||||||
#else
|
#else
|
||||||
void reord_timeout_handler (struct timer_list *t);
|
void reord_timeout_handler (struct timer_list *t);
|
||||||
#endif
|
#endif
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||||
|
void defrag_timeout_cb(ulong data);
|
||||||
|
#else
|
||||||
|
void defrag_timeout_cb(struct timer_list *t);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx,
|
void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx,
|
||||||
|
|||||||
@@ -115,12 +115,21 @@ 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 AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||||
|
skb_put(skb, 2 + sizeof(mgmt->u.action.tdls_discover_resp));
|
||||||
|
mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
|
||||||
|
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.capability =
|
||||||
|
cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code));
|
||||||
|
#else
|
||||||
skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
|
skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
|
||||||
mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
|
mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
|
||||||
mgmt->u.action.u.tdls_discover_resp.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
|
mgmt->u.action.u.tdls_discover_resp.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
|
||||||
mgmt->u.action.u.tdls_discover_resp.dialog_token = dialog_token;
|
mgmt->u.action.u.tdls_discover_resp.dialog_token = dialog_token;
|
||||||
mgmt->u.action.u.tdls_discover_resp.capability =
|
mgmt->u.action.u.tdls_discover_resp.capability =
|
||||||
cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code));
|
cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code));
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|||||||
@@ -1833,7 +1833,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_BAND_STEERING
|
#if 0//def CONFIG_BAND_STEERING
|
||||||
void rwnx_probersp_work(struct work_struct *work)
|
void rwnx_probersp_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct ap_probe_rsp *rsp = container_of(work, struct ap_probe_rsp, rsp_work);
|
struct ap_probe_rsp *rsp = container_of(work, struct ap_probe_rsp, rsp_work);
|
||||||
@@ -1841,7 +1841,6 @@ void rwnx_probersp_work(struct work_struct *work)
|
|||||||
struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw;
|
struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw;
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
struct rwnx_bcn *bcn = &rwnx_vif->ap.bcn;
|
struct rwnx_bcn *bcn = &rwnx_vif->ap.bcn;
|
||||||
unsigned int len = bcn->len;
|
|
||||||
u8_l *buf;
|
u8_l *buf;
|
||||||
struct ieee80211_mgmt *mgmt;
|
struct ieee80211_mgmt *mgmt;
|
||||||
bool robust;
|
bool robust;
|
||||||
@@ -1852,13 +1851,13 @@ void rwnx_probersp_work(struct work_struct *work)
|
|||||||
struct rwnx_sw_txhdr *sw_txhdr;
|
struct rwnx_sw_txhdr *sw_txhdr;
|
||||||
struct txdesc_api *desc;
|
struct txdesc_api *desc;
|
||||||
headroom = sizeof(struct rwnx_txhdr);
|
headroom = sizeof(struct rwnx_txhdr);
|
||||||
frame_len = len;
|
frame_len = bcn->len;
|
||||||
|
|
||||||
if (aicwf_band_steering_block_chk(rwnx_vif, rsp->da)) {
|
if (aicwf_band_steering_block_chk(rwnx_vif, rsp->da)) {
|
||||||
AICWFDBG(LOGSTEER, "usb %s, %d, probe_rsp refuse temp %pM\n", __func__, rwnx_vif->ap.freq, rsp->da);
|
AICWFDBG(LOGSTEER, "usb %s, %d, probe_rsp refuse temp %pM\n", __func__, rwnx_vif->ap.freq, rsp->da);
|
||||||
goto free_use;
|
goto free_use;
|
||||||
}
|
}
|
||||||
if (!bcn->head || bcn->head_len == 0 || bcn->head_len > frame_len) {
|
if (frame_len == 0 || !bcn->head || bcn->head_len == 0 || bcn->head_len > frame_len) {
|
||||||
AICWFDBG(LOGSTEER, "%s bcn head NULL\n", __func__);
|
AICWFDBG(LOGSTEER, "%s bcn head NULL\n", __func__);
|
||||||
goto free_use;
|
goto free_use;
|
||||||
}
|
}
|
||||||
@@ -1992,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;
|
||||||
@@ -2013,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) ||
|
||||||
@@ -2024,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;
|
||||||
|
|
||||||
@@ -2347,7 +2349,8 @@ int rwnx_txdatacfm(void *pthis, void *host_id)
|
|||||||
/* Check status in the header. If status is null, it means that the buffer
|
/* Check status in the header. If status is null, it means that the buffer
|
||||||
* was not transmitted and we have to return immediately */
|
* was not transmitted and we have to return immediately */
|
||||||
if (rwnx_txst.value == 0) {
|
if (rwnx_txst.value == 0) {
|
||||||
return -1;
|
//return -1;
|
||||||
|
rwnx_txst.tx_done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AICWF_USB_SUPPORT
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "ipc_shared.h"
|
#include "ipc_shared.h"
|
||||||
#include "rwnx_txq.h"
|
#include "rwnx_txq.h"
|
||||||
#include "hal_desc.h"
|
#include "hal_desc.h"
|
||||||
|
#include "aicwf_tcp_ack.h"
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||||
#define IEEE80211_NUM_TIDS 16
|
#define IEEE80211_NUM_TIDS 16
|
||||||
@@ -171,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);
|
||||||
|
|
||||||
@@ -197,6 +199,8 @@ void rwnx_tx_push(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr, int flags);
|
|||||||
#ifdef CONFIG_BAND_STEERING
|
#ifdef CONFIG_BAND_STEERING
|
||||||
void rwnx_probersp_work(struct work_struct *work);
|
void rwnx_probersp_work(struct work_struct *work);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_FILTER_TCP_ACK
|
||||||
|
int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _RWNX_TX_H_ */
|
#endif /* _RWNX_TX_H_ */
|
||||||
|
|||||||
@@ -393,5 +393,6 @@ void rwnx_txq_confirm_any(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq,
|
|||||||
void rwnx_hwq_init(struct rwnx_hw *rwnx_hw);
|
void rwnx_hwq_init(struct rwnx_hw *rwnx_hw);
|
||||||
void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq);
|
void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq);
|
||||||
void rwnx_hwq_process_all(struct rwnx_hw *rwnx_hw);
|
void rwnx_hwq_process_all(struct rwnx_hw *rwnx_hw);
|
||||||
|
void rwnx_txq_flush(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq);
|
||||||
|
|
||||||
#endif /* _RWNX_TXQ_H_ */
|
#endif /* _RWNX_TXQ_H_ */
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ struct rwnx_ipc_rxbuf_elems {
|
|||||||
struct sk_buff *skb[RWNX_RXBUFF_MAX];
|
struct sk_buff *skb[RWNX_RXBUFF_MAX];
|
||||||
int idx;
|
int idx;
|
||||||
};
|
};
|
||||||
|
int rwnx_init_aic(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
#endif /* CONFIG_RWNX_FULLMAC */
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
#endif /* _RWNX_IPC_UTILS_H_ */
|
#endif /* _RWNX_IPC_UTILS_H_ */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#define RWNX_VERS_REV "1a4b0054d2M (master)"
|
#define RWNX_VERS_REV "1a4b0054d2M (master)"
|
||||||
#define RWNX_VERS_MOD "6.4.3.0"
|
#define RWNX_VERS_MOD "6.4.3.0"
|
||||||
#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)"
|
#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)"
|
||||||
#define RELEASE_DATE "2025_1018_71b66e7b"
|
#define RELEASE_DATE "2026_0123_5f7be68d"
|
||||||
|
|
||||||
|
|||||||
@@ -39,5 +39,6 @@ extern void aicwf_usb_host_txdesc_push(struct usb_host_env_tag *env, const int q
|
|||||||
|
|
||||||
extern void aicwf_usb_host_tx_cfm_handler(struct usb_host_env_tag *env, u32 *data);
|
extern void aicwf_usb_host_tx_cfm_handler(struct usb_host_env_tag *env, u32 *data);
|
||||||
extern int aicwf_rwnx_usb_platform_init(struct aic_usb_dev *usbdev);
|
extern int aicwf_rwnx_usb_platform_init(struct aic_usb_dev *usbdev);
|
||||||
|
volatile struct txdesc_host *aicwf_usb_host_txdesc_get(struct usb_host_env_tag *env, const int queue_idx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,14 +7,16 @@ CONFIG_M2D_OTA_AUTO_SUPPORT = n
|
|||||||
CONFIG_LINK_DET_5G = y
|
CONFIG_LINK_DET_5G = y
|
||||||
CONFIG_FOR_IPCAM = n
|
CONFIG_FOR_IPCAM = n
|
||||||
CONFIG_USB_SUSPEND_REBOOT_TIME = n
|
CONFIG_USB_SUSPEND_REBOOT_TIME = n
|
||||||
CONFIG_SUPPORT_USB_SUSP = n
|
|
||||||
CONFIG_RADAR_OR_IR_DETECT =n
|
CONFIG_RADAR_OR_IR_DETECT =n
|
||||||
|
CONFIG_LOAD_BT_CONF = n
|
||||||
|
CONFIG_FLASH_CALRES = n
|
||||||
|
CONFIG_WOWLAN ?= n
|
||||||
# Need to set fw path in BOARD_KERNEL_CMDLINE
|
# Need to set fw path in BOARD_KERNEL_CMDLINE
|
||||||
CONFIG_USE_FW_REQUEST ?= n
|
CONFIG_USE_FW_REQUEST ?= n
|
||||||
CONFIG_PREALLOC_RX_SKB ?= n
|
CONFIG_PREALLOC_RX_SKB ?= n
|
||||||
CONFIG_PREALLOC_TXQ ?= y
|
CONFIG_PREALLOC_TXQ ?= y
|
||||||
CONFIG_BAND_STEERING = n
|
CONFIG_BAND_STEERING = n
|
||||||
|
CONFIG_PRBREQ_REPORT = n
|
||||||
|
|
||||||
# Platform support list
|
# Platform support list
|
||||||
CONFIG_PLATFORM_ROCKCHIP ?= n
|
CONFIG_PLATFORM_ROCKCHIP ?= n
|
||||||
@@ -44,7 +46,11 @@ ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ
|
|||||||
ccflags-$(CONFIG_USB_SUSPEND_REBOOT_TIME) += -DCONFIG_USB_SUSPEND_REBOOT_TIME
|
ccflags-$(CONFIG_USB_SUSPEND_REBOOT_TIME) += -DCONFIG_USB_SUSPEND_REBOOT_TIME
|
||||||
ccflags-$(CONFIG_SUPPORT_USB_SUSP) += -DCONFIG_SUPPORT_USB_SUSP
|
ccflags-$(CONFIG_SUPPORT_USB_SUSP) += -DCONFIG_SUPPORT_USB_SUSP
|
||||||
ccflags-$(CONFIG_RADAR_OR_IR_DETECT) += -DCONFIG_RADAR_OR_IR_DETECT
|
ccflags-$(CONFIG_RADAR_OR_IR_DETECT) += -DCONFIG_RADAR_OR_IR_DETECT
|
||||||
|
ccflags-$(CONFIG_LOAD_BT_CONF) += -DCONFIG_LOAD_BT_CONF
|
||||||
|
ccflags-$(CONFIG_FLASH_CALRES) += -DCONFIG_FLASH_CALRES
|
||||||
ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING
|
ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING
|
||||||
|
ccflags-$(CONFIG_PRBREQ_REPORT) += -DCONFIG_PRBREQ_REPORT
|
||||||
|
ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN
|
||||||
|
|
||||||
obj-$(CONFIG_AIC_LOADFW_SUPPORT) := $(MODULE_NAME).o
|
obj-$(CONFIG_AIC_LOADFW_SUPPORT) := $(MODULE_NAME).o
|
||||||
$(MODULE_NAME)-y := aic_bluetooth_main.o \
|
$(MODULE_NAME)-y := aic_bluetooth_main.o \
|
||||||
@@ -67,7 +73,7 @@ ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
|
|||||||
#ARCH ?= arm
|
#ARCH ?= arm
|
||||||
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
|
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
|
||||||
KDIR := /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/kernel
|
KDIR := /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/kernel
|
||||||
ARCH ?=$(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
|
ARCH ?= arm
|
||||||
CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
|
CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
|
||||||
#KDIR := /home/yaya/E/Rockchip/3399/rk3399-android-10/kernel
|
#KDIR := /home/yaya/E/Rockchip/3399/rk3399-android-10/kernel
|
||||||
#ARCH ?= arm64
|
#ARCH ?= arm64
|
||||||
@@ -91,12 +97,13 @@ endif
|
|||||||
|
|
||||||
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
||||||
ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU
|
ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU
|
||||||
KVER := $(or $(KVER), $(kernelver), $(KERNELRELEASE), $(shell uname -r))
|
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
|
||||||
ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
|
SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
|
||||||
CROSS_COMPILE ?=
|
ARCH ?= $(SUBARCH)
|
||||||
|
CROSS_COMPILE :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,27 +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
|
||||||
|
* different RX aggregation settings and a user_ext_flags field that is not
|
||||||
#define CFG_PWROFST_COVER_CALIB 1
|
* part of this firmware generation.
|
||||||
#ifdef 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 0
|
|
||||||
#ifdef CONFIG_BAND_STEERING
|
|
||||||
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 1
|
|
||||||
#else
|
|
||||||
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CFG_USER_EXT_FLAGS_EN (CFG_PWROFST_COVER_CALIB || CFG_USER_CHAN_MAX_TXPWR_EN || CFG_USER_TX_USE_ANA_F|| CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE)
|
|
||||||
|
|
||||||
u32 patch_tbl_d80[][2] =
|
u32 patch_tbl_d80[][2] =
|
||||||
{
|
{
|
||||||
#ifdef USE_5G
|
#ifdef USE_5G
|
||||||
@@ -67,32 +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
|
|
||||||
|
|
||||||
#if CFG_USER_EXT_FLAGS_EN
|
|
||||||
{0x0188, 0x00000000
|
|
||||||
#if CFG_PWROFST_COVER_CALIB
|
|
||||||
| USER_PWROFST_COVER_CALIB_FLAG
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_CHAN_MAX_TXPWR_EN
|
|
||||||
| USER_CHAN_MAX_TXPWR_EN_FLAG
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_TX_USE_ANA_F
|
|
||||||
| USER_TX_USE_ANA_F_FLAG
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE
|
|
||||||
| USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG
|
|
||||||
#endif
|
|
||||||
}, // user_ext_flags
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_RADAR_OR_IR_DETECT
|
|
||||||
{0x0019c,0x00000B00},
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//adap test
|
//adap test
|
||||||
@@ -113,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;
|
||||||
@@ -159,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;
|
||||||
@@ -303,6 +234,7 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){
|
|||||||
int syscfg_num;
|
int syscfg_num;
|
||||||
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(usb_dev, mem_addr, &rd_mem_addr_cfm);
|
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -314,6 +246,21 @@ 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);
|
||||||
|
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);
|
||||||
|
if (ret) {
|
||||||
|
printk("%x rd fail: %d\n", cache_mem_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
rd_mem_addr_cfm.memdata |= 0x01;
|
||||||
|
ret = rwnx_send_dbg_mem_write_req(usb_dev, cache_mem_addr, rd_mem_addr_cfm.memdata);
|
||||||
|
if (ret) {
|
||||||
|
printk("%x write fail: %d\n", cache_mem_addr, 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;
|
||||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||||
@@ -337,7 +284,7 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info)
|
static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info, const char *filename)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint32_t ext_patch_nb = patch_info->ext_patch_nb;
|
uint32_t ext_patch_nb = patch_info->ext_patch_nb;
|
||||||
@@ -354,7 +301,7 @@ static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_p
|
|||||||
addr = *(patch_info->ext_patch_param + (index * 2) + 1);
|
addr = *(patch_info->ext_patch_param + (index * 2) + 1);
|
||||||
memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name));
|
memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name));
|
||||||
sprintf(ext_patch_file_name,"%s%d.bin",
|
sprintf(ext_patch_file_name,"%s%d.bin",
|
||||||
FW_PATCH_BASE_NAME_8800D80_U02_EXT,
|
filename,
|
||||||
id);
|
id);
|
||||||
AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n",
|
AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n",
|
||||||
__func__,ext_patch_file_name, id, addr);
|
__func__,ext_patch_file_name, id, addr);
|
||||||
@@ -386,7 +333,6 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (chip_id == CHIP_REV_U01) {
|
if (chip_id == CHIP_REV_U01) {
|
||||||
head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80);
|
head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80);
|
||||||
} else {
|
} else {
|
||||||
@@ -414,11 +360,10 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
printk("addr_adid 0x%x, addr_patch 0x%x\n", patch_info.addr_adid, patch_info.addr_patch);
|
printk("addr_adid 0x%x, addr_patch 0x%x\n", patch_info.addr_adid, patch_info.addr_patch);
|
||||||
#endif
|
|
||||||
if(testmode == FW_NORMAL_MODE){
|
if(testmode == FW_NORMAL_MODE){
|
||||||
|
|
||||||
if (chip_id != CHIP_REV_U01){
|
if (chip_id != CHIP_REV_U01){
|
||||||
#if 0
|
|
||||||
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80_U02)) {
|
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80_U02)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -426,14 +371,13 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) {
|
if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80_U02_EXT)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aicbt_patch_table_load(usb_dev, head)) {
|
if (aicbt_patch_table_load(usb_dev, head)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (IS_CHIP_ID_H()){
|
if (IS_CHIP_ID_H()){
|
||||||
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80_U02, FW_BASE_NAME_8800D80_H_U02))
|
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80_U02, FW_BASE_NAME_8800D80_H_U02))
|
||||||
@@ -456,7 +400,6 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
#if 0
|
|
||||||
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80)) {
|
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -472,7 +415,6 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80, FW_BASE_NAME_8800D80)) {
|
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80, FW_BASE_NAME_8800D80)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -482,7 +424,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
|||||||
}
|
}
|
||||||
}else if(testmode == FW_TEST_MODE){
|
}else if(testmode == FW_TEST_MODE){
|
||||||
if (chip_id != CHIP_REV_U01){
|
if (chip_id != CHIP_REV_U01){
|
||||||
#if 0
|
|
||||||
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80_U02)) {
|
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80_U02)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -491,7 +433,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) {
|
if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80_U02_EXT)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,7 +450,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80_U02, FW_RF_BASE_NAME_8800D80_U02)) {
|
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80_U02, FW_RF_BASE_NAME_8800D80_U02)) {
|
||||||
AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__);
|
AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -41,21 +41,32 @@ typedef struct {
|
|||||||
|
|
||||||
#define USER_PWROFST_COVER_CALIB_FLAG (0x01U << 0)
|
#define USER_PWROFST_COVER_CALIB_FLAG (0x01U << 0)
|
||||||
#define USER_CHAN_MAX_TXPWR_EN_FLAG (0x01U << 1)
|
#define USER_CHAN_MAX_TXPWR_EN_FLAG (0x01U << 1)
|
||||||
#define USER_TX_USE_ANA_F_FLAG (0x01U << 2)
|
|
||||||
#define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3)
|
#define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3)
|
||||||
#define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4)
|
#define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4)
|
||||||
|
#define USER_RF_WITH_SAW_EN_FLAG (0x01U << 10)
|
||||||
|
#define USER_SETCH_LOFT_CALIB_EN_FLAG (0x01U << 11)
|
||||||
|
#define USER_SETCH_RXDC_CALIB_EN_FLAG (0x01U << 12)
|
||||||
|
|
||||||
#ifdef CONFIG_POWER_LIMIT
|
#define USER_EXT_FLAGS_DEFAULT_D80X2 \
|
||||||
#define CFG_USER_CHAN_MAX_TXPWR_EN 1
|
(USER_PWROFST_COVER_CALIB_FLAG | \
|
||||||
|
USER_CHAN_MAX_TXPWR_EN_FLAG | \
|
||||||
|
USER_SETCH_LOFT_CALIB_EN_FLAG)
|
||||||
|
|
||||||
|
#define CFG_USER_PWROFST_COVER_CALIB_EN (1)
|
||||||
|
#if (defined(CONFIG_POWER_LIMIT))
|
||||||
|
#define CFG_USER_CHAN_MAX_TXPWR_EN (1)
|
||||||
#else
|
#else
|
||||||
#define CFG_USER_CHAN_MAX_TXPWR_EN 0
|
#define CFG_USER_CHAN_MAX_TXPWR_EN (0)
|
||||||
#endif
|
#endif
|
||||||
#define CFG_USER_TX_USE_ANA_F 0
|
#if (defined(CONFIG_PRBREQ_REPORT))
|
||||||
#ifdef CONFIG_BAND_STEERING
|
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (1)
|
||||||
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 1
|
|
||||||
#else
|
#else
|
||||||
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 0
|
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (0)
|
||||||
#endif
|
#endif
|
||||||
|
#define CFG_USER_HE_MU_EDCA_UPDATE_DISABLE (0)
|
||||||
|
#define CFG_USER_RF_WITH_SAW_EN (0)
|
||||||
|
#define CFG_USER_SETCH_LOFT_CALIB_EN (1)
|
||||||
|
#define CFG_USER_SETCH_RXDC_CALIB_EN (0)
|
||||||
|
|
||||||
u32 patch_tbl_d80x2[][2] =
|
u32 patch_tbl_d80x2[][2] =
|
||||||
{
|
{
|
||||||
@@ -71,29 +82,35 @@ u32 patch_tbl_d80x2[][2] =
|
|||||||
{0x0228, 0x50000a00},//ss aggr
|
{0x0228, 0x50000a00},//ss aggr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#ifdef CONFIG_FLASH_CALRES
|
||||||
#ifdef USE_5G
|
{0x0234, 0x0000004F}, // cal_res_stored_in_flash_flags
|
||||||
{0x00b4, 0xf3010001},
|
|
||||||
#else
|
|
||||||
{0x00b4, 0xf3010000},
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_PLATFORM_HI
|
|
||||||
{0x0170, 0x00000001},//rx aggr counter
|
|
||||||
#else
|
|
||||||
{0x0170, 0x0000000A},//rx aggr counter
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{0x01f0, 0x00000001
|
{0x01f0,
|
||||||
#if CFG_USER_CHAN_MAX_TXPWR_EN
|
(USER_EXT_FLAGS_DEFAULT_D80X2 |
|
||||||
| USER_CHAN_MAX_TXPWR_EN_FLAG
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_TX_USE_ANA_F
|
|
||||||
| USER_TX_USE_ANA_F_FLAG
|
|
||||||
#endif
|
|
||||||
#if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE
|
#if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE
|
||||||
| USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG
|
USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG |
|
||||||
#endif
|
#endif
|
||||||
|
#if CFG_USER_HE_MU_EDCA_UPDATE_DISABLE
|
||||||
|
USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG |
|
||||||
|
#endif
|
||||||
|
#if CFG_USER_RF_WITH_SAW_EN
|
||||||
|
USER_RF_WITH_SAW_EN_FLAG |
|
||||||
|
#endif
|
||||||
|
#if CFG_USER_SETCH_RXDC_CALIB_EN
|
||||||
|
USER_SETCH_RXDC_CALIB_EN_FLAG |
|
||||||
|
#endif
|
||||||
|
0) & ~(
|
||||||
|
#if !CFG_USER_PWROFST_COVER_CALIB_EN
|
||||||
|
USER_PWROFST_COVER_CALIB_FLAG |
|
||||||
|
#endif
|
||||||
|
#if !CFG_USER_CHAN_MAX_TXPWR_EN
|
||||||
|
USER_CHAN_MAX_TXPWR_EN_FLAG |
|
||||||
|
#endif
|
||||||
|
#if !CFG_USER_SETCH_LOFT_CALIB_EN
|
||||||
|
USER_SETCH_LOFT_CALIB_EN_FLAG |
|
||||||
|
#endif
|
||||||
|
0)
|
||||||
}, // user_ext_flags
|
}, // user_ext_flags
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -301,7 +318,39 @@ int system_config_8800d80x2(struct aic_usb_dev *usb_dev){
|
|||||||
int ret, cnt;
|
int ret, cnt;
|
||||||
const u32 mem_addr = 0x40500000;
|
const u32 mem_addr = 0x40500000;
|
||||||
const u32 mem_addr2 = 0x40500004;
|
const u32 mem_addr2 = 0x40500004;
|
||||||
|
const u32 mem_addr3 = 0x40800000;
|
||||||
|
const u32 mem_mask3 = (0x03UL << 24) | (0x01UL << 6) | (0x01UL << 1);
|
||||||
|
const u32 mem_data3 = (0x02UL << 24) | (0x01UL << 6);
|
||||||
|
const u32 mem_addr4 = 0x40800014;
|
||||||
|
const u32 mem_data4 = 0x00000820;
|
||||||
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||||
|
|
||||||
|
/* fix usb2.0 rx_err */
|
||||||
|
ret = rwnx_send_dbg_mem_mask_write_req(usb_dev, mem_addr3, mem_mask3, mem_data3);
|
||||||
|
if (ret) {
|
||||||
|
printk("%x mask write fail: %d\n", mem_addr3, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = rwnx_send_dbg_mem_write_req(usb_dev, mem_addr4, mem_data4);
|
||||||
|
if (ret) {
|
||||||
|
printk("%x write fail: %d\n", mem_addr4, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr3, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
printk("%x rd fail: %d\n", mem_addr3, ret);
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
printk("[%08x]=%08x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
|
||||||
|
}
|
||||||
|
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr4, &rd_mem_addr_cfm);
|
||||||
|
if (ret) {
|
||||||
|
printk("%x rd fail: %d\n", mem_addr4, ret);
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
printk("[%08x]=%08x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
|
||||||
|
}
|
||||||
|
|
||||||
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm);
|
ret = rwnx_send_dbg_mem_read_req(usb_dev, 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", mem_addr, ret);
|
||||||
@@ -319,7 +368,7 @@ int system_config_8800d80x2(struct aic_usb_dev *usb_dev){
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 1
|
|
||||||
syscfg_num = sizeof(syscfg_tbl_8800d80x2) / sizeof(u32) / 2;
|
syscfg_num = sizeof(syscfg_tbl_8800d80x2) / sizeof(u32) / 2;
|
||||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||||
ret = rwnx_send_dbg_mem_write_req(usb_dev, syscfg_tbl_8800d80x2[cnt][0], syscfg_tbl_8800d80x2[cnt][1]);
|
ret = rwnx_send_dbg_mem_write_req(usb_dev, syscfg_tbl_8800d80x2[cnt][0], syscfg_tbl_8800d80x2[cnt][1]);
|
||||||
@@ -337,13 +386,12 @@ int system_config_8800d80x2(struct aic_usb_dev *usb_dev){
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info)
|
static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info, const char *filename)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint32_t ext_patch_nb = patch_info->ext_patch_nb;
|
uint32_t ext_patch_nb = patch_info->ext_patch_nb;
|
||||||
@@ -351,16 +399,26 @@ static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_p
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
uint32_t id = 0;
|
uint32_t id = 0;
|
||||||
uint32_t addr = 0;
|
uint32_t addr = 0;
|
||||||
|
uint32_t mem_w_add = 0;
|
||||||
|
uint32_t mem_w_data = 0;
|
||||||
|
|
||||||
if (ext_patch_nb > 0){
|
if (ext_patch_nb > 0){
|
||||||
|
AICWFDBG(LOGDEBUG, "[0x40480000]: 0x00040220\n");
|
||||||
|
mem_w_add = 0x40580000;
|
||||||
|
mem_w_data = 0x00040220;
|
||||||
|
AICWFDBG(LOGDEBUG, "%s addr:0x%x data:0x%x \n", __func__, mem_w_add, mem_w_data);
|
||||||
|
ret = rwnx_send_dbg_mem_write_req(usb_dev, mem_w_add, mem_w_data);
|
||||||
|
if (ret) {
|
||||||
|
printk("%x wr fail: %d\n", mem_w_add, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
for (index = 0; index < patch_info->ext_patch_nb; index++){
|
for (index = 0; index < patch_info->ext_patch_nb; index++){
|
||||||
id = *(patch_info->ext_patch_param + (index * 2));
|
id = *(patch_info->ext_patch_param + (index * 2));
|
||||||
addr = *(patch_info->ext_patch_param + (index * 2) + 1);
|
addr = *(patch_info->ext_patch_param + (index * 2) + 1);
|
||||||
memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name));
|
memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name));
|
||||||
sprintf(ext_patch_file_name,"%s%d.bin",
|
sprintf(ext_patch_file_name,"%s%d.bin",
|
||||||
FW_PATCH_BASE_NAME_8800D80X2_U03_EXT,
|
filename,
|
||||||
id);
|
id);
|
||||||
AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n",
|
AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n",
|
||||||
__func__,ext_patch_file_name, id, addr);
|
__func__,ext_patch_file_name, id, addr);
|
||||||
@@ -393,6 +451,10 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_LOAD_BT_CONF
|
||||||
|
aicbt_parse_config(usb_dev, FW_BT_CONF_NAME_8800D80X2);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (chip_id < CHIP_REV_U05) {
|
if (chip_id < CHIP_REV_U05) {
|
||||||
head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80X2_U03);
|
head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80X2_U03);
|
||||||
} else {
|
} else {
|
||||||
@@ -480,7 +542,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) {
|
if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U03_EXT)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,7 +577,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
|||||||
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80X2_U05)) {
|
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80X2_U05)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) {
|
if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U05_EXT)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (aicbt_patch_table_load(usb_dev, head)) {
|
if (aicbt_patch_table_load(usb_dev, head)) {
|
||||||
@@ -545,7 +607,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) {
|
if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U03_EXT)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,15 +618,6 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
|||||||
mdelay(100);
|
mdelay(100);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (chip_mcu_id) {
|
|
||||||
int ret = 0;
|
|
||||||
ret = rwnx_plat_flash_bin_upload_android(usb_dev, FLASH_BIN_ADDR_8800M80X2, FLASH_BIN_8800M80X2);
|
|
||||||
if (ret && ret!= ENOENT) {
|
|
||||||
AICWFDBG(LOGERROR,"%s flash bin download fail \r\n", __func__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, FW_RF_BASE_NAME_8800D80X2)) {
|
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, FW_RF_BASE_NAME_8800D80X2)) {
|
||||||
AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__);
|
AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -582,7 +635,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) {
|
if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U05_EXT)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,7 +666,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
|||||||
data & mask = "0x46 0x00" 0x00 0x00 0x00 0x00 0x00 0x00 0x00 "0x30 0xff 0xff 0x43 0x52 0x45 0x4c 0x42"
|
data & mask = "0x46 0x00" 0x00 0x00 0x00 0x00 0x00 0x00 0x00 "0x30 0xff 0xff 0x43 0x52 0x45 0x4c 0x42"
|
||||||
using data & mask value condition to wakeup host_wake_bt gpio
|
using data & mask value condition to wakeup host_wake_bt gpio
|
||||||
*/
|
*/
|
||||||
|
int ret;
|
||||||
struct ble_wakeup_param_t* wakeup_param = (struct ble_wakeup_param_t*)kmalloc(sizeof(struct ble_wakeup_param_t), GFP_KERNEL);
|
struct ble_wakeup_param_t* wakeup_param = (struct ble_wakeup_param_t*)kmalloc(sizeof(struct ble_wakeup_param_t), GFP_KERNEL);
|
||||||
uint32_t *write_blocks = (uint32_t *)wakeup_param;
|
uint32_t *write_blocks = (uint32_t *)wakeup_param;
|
||||||
|
|
||||||
@@ -744,7 +797,6 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
|||||||
}
|
}
|
||||||
//rwnx_send_dbg_start_app_req(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80, HOST_START_APP_AUTO);
|
//rwnx_send_dbg_start_app_req(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80, HOST_START_APP_AUTO);
|
||||||
|
|
||||||
int ret;
|
|
||||||
ret = rwnx_send_dbg_mem_write_req(usb_dev, 0x40500048, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80);
|
ret = rwnx_send_dbg_mem_write_req(usb_dev, 0x40500048, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk("%x write fail\n", ret);
|
printk("%x write fail\n", ret);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#define USB_DEVICE_ID_AIC_8800D80X2 0x8D90
|
#define USB_DEVICE_ID_AIC_8800D80X2 0x8D90
|
||||||
#define USB_DEVICE_ID_AIC_8800D81X2 0x8D91
|
#define USB_DEVICE_ID_AIC_8800D81X2 0x8D91
|
||||||
#define USB_DEVICE_ID_AIC_8800D89X2 0x8D99
|
#define USB_DEVICE_ID_AIC_8800D89X2 0x8D99
|
||||||
|
#define USB_DEVICE_ID_AIC_8800D40X2 0x8D92
|
||||||
|
|
||||||
#ifdef CONFIG_FOR_IPCAM
|
#ifdef CONFIG_FOR_IPCAM
|
||||||
#define FW_BASE_NAME_8800D80X2 "fmacfw_8800d80x2_ipc.bin"
|
#define FW_BASE_NAME_8800D80X2 "fmacfw_8800d80x2_ipc.bin"
|
||||||
@@ -22,12 +23,14 @@
|
|||||||
#define FW_ADID_BASE_NAME_8800D80X2_U05 "fw_adid_8800d80x2_u05.bin"
|
#define FW_ADID_BASE_NAME_8800D80X2_U05 "fw_adid_8800d80x2_u05.bin"
|
||||||
#define FW_PATCH_TABLE_NAME_8800D80X2_U05 "fw_patch_table_8800d80x2_u05.bin"
|
#define FW_PATCH_TABLE_NAME_8800D80X2_U05 "fw_patch_table_8800d80x2_u05.bin"
|
||||||
|
|
||||||
|
#define FW_BT_CONF_NAME_8800D80X2 "aicbt.conf"
|
||||||
|
|
||||||
#define FLASH_BIN_8800M80X2 "host_wb_8800m80x2.bin"
|
#define FLASH_BIN_8800M80X2 "host_wb_8800m80x2.bin"
|
||||||
|
|
||||||
#define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt"
|
#define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt"
|
||||||
|
|
||||||
#define RAM_FMAC_FW_ADDR_8800D80X2 0x120000
|
#define RAM_FMAC_FW_ADDR_8800D80X2 0x128000
|
||||||
#define RAM_FMAC_RF_FW_ADDR_8800D80X2 0x120000
|
#define RAM_FMAC_RF_FW_ADDR_8800D80X2 0x128000
|
||||||
|
|
||||||
#define FW_RAM_ADID_BASE_ADDR_8800D80X2_U03 0x003018f8
|
#define FW_RAM_ADID_BASE_ADDR_8800D80X2_U03 0x003018f8
|
||||||
#define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U03 0x0030b494
|
#define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U03 0x0030b494
|
||||||
@@ -35,7 +38,7 @@
|
|||||||
#define FW_RAM_ADID_BASE_ADDR_8800D80X2_U05 0x003018f8
|
#define FW_RAM_ADID_BASE_ADDR_8800D80X2_U05 0x003018f8
|
||||||
#define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U05 0x0030b48c
|
#define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U05 0x0030b48c
|
||||||
|
|
||||||
#define FLASH_BIN_ADDR_8800M80X2 0x8000000
|
#define FLASH_BIN_ADDR_8800M80X2 0x4000000
|
||||||
|
|
||||||
|
|
||||||
int aicwf_patch_config_8800d80x2(struct aic_usb_dev *usb_dev);
|
int aicwf_patch_config_8800d80x2(struct aic_usb_dev *usb_dev);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#define DATA_BUF_MAX 2048
|
#define DATA_BUF_MAX 2048
|
||||||
#define TXPKT_BLOCKSIZE 512
|
#define TXPKT_BLOCKSIZE 512
|
||||||
#define MAX_AGGR_TXPKT_LEN (1536*32)
|
#define MAX_AGGR_TXPKT_LEN (1536*32)
|
||||||
#define CMD_TX_TIMEOUT 2000
|
#define CMD_TX_TIMEOUT 5000
|
||||||
#define TX_ALIGNMENT 4
|
#define TX_ALIGNMENT 4
|
||||||
|
|
||||||
#define RX_HWHRD_LEN 60 //58->60 word allined
|
#define RX_HWHRD_LEN 60 //58->60 word allined
|
||||||
|
|||||||
@@ -20,20 +20,6 @@ extern int flash_erase_len;
|
|||||||
int flash_write_size = 0;
|
int flash_write_size = 0;
|
||||||
u32 flash_write_bin_crc = 0;
|
u32 flash_write_bin_crc = 0;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int8_t enable;
|
|
||||||
int8_t dsss;
|
|
||||||
int8_t ofdmlowrate_2g4;
|
|
||||||
int8_t ofdm64qam_2g4;
|
|
||||||
int8_t ofdm256qam_2g4;
|
|
||||||
int8_t ofdm1024qam_2g4;
|
|
||||||
int8_t ofdmlowrate_5g;
|
|
||||||
int8_t ofdm64qam_5g;
|
|
||||||
int8_t ofdm256qam_5g;
|
|
||||||
int8_t ofdm1024qam_5g;
|
|
||||||
} txpwr_idx_conf_t;
|
|
||||||
|
|
||||||
|
|
||||||
txpwr_idx_conf_t userconfig_txpwr_idx = {
|
txpwr_idx_conf_t userconfig_txpwr_idx = {
|
||||||
.enable = 1,
|
.enable = 1,
|
||||||
@@ -49,17 +35,6 @@ txpwr_idx_conf_t userconfig_txpwr_idx = {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int8_t enable;
|
|
||||||
int8_t chan_1_4;
|
|
||||||
int8_t chan_5_9;
|
|
||||||
int8_t chan_10_13;
|
|
||||||
int8_t chan_36_64;
|
|
||||||
int8_t chan_100_120;
|
|
||||||
int8_t chan_122_140;
|
|
||||||
int8_t chan_142_165;
|
|
||||||
} txpwr_ofst_conf_t;
|
|
||||||
|
|
||||||
txpwr_ofst_conf_t userconfig_txpwr_ofst = {
|
txpwr_ofst_conf_t userconfig_txpwr_ofst = {
|
||||||
.enable = 1,
|
.enable = 1,
|
||||||
@@ -72,13 +47,6 @@ txpwr_ofst_conf_t userconfig_txpwr_ofst = {
|
|||||||
.chan_142_165 = 0
|
.chan_142_165 = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int8_t enable;
|
|
||||||
int8_t xtal_cap;
|
|
||||||
int8_t xtal_cap_fine;
|
|
||||||
} xtal_cap_conf_t;
|
|
||||||
|
|
||||||
|
|
||||||
xtal_cap_conf_t userconfig_xtal_cap = {
|
xtal_cap_conf_t userconfig_xtal_cap = {
|
||||||
.enable = 0,
|
.enable = 0,
|
||||||
@@ -757,7 +725,7 @@ int rwnx_plat_flash_bin_upload_android(struct aic_usb_dev *usbdev, u32 fw_addr,
|
|||||||
int err=0;
|
int err=0;
|
||||||
const u32 mem_addr = fw_addr;
|
const u32 mem_addr = fw_addr;
|
||||||
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||||
u32 crc = ~0UL;
|
u32 crc = (u32)~0UL;
|
||||||
|
|
||||||
/* load aic firmware */
|
/* load aic firmware */
|
||||||
size = aic_load_firmware(&dst, filename, dev);
|
size = aic_load_firmware(&dst, filename, dev);
|
||||||
@@ -1285,6 +1253,149 @@ static struct aicbt_info_t aicbt_info[] = {
|
|||||||
},//PRODUCT_ID_AIC8800D80X2
|
},//PRODUCT_ID_AIC8800D80X2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_LOAD_BT_CONF
|
||||||
|
static const char *aicbt_find_tag(const u8 *file_data, unsigned int file_size,
|
||||||
|
const char *tag_name, unsigned int tag_len)
|
||||||
|
{
|
||||||
|
unsigned int line_start = 0, tag_name_len = strlen(tag_name);
|
||||||
|
const char *comment_symbols = "#;";
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
while (line_start < file_size) {
|
||||||
|
unsigned int line_end = line_start;
|
||||||
|
|
||||||
|
while (line_end < file_size && file_data[line_end] != '\n' && file_data[line_end] != '\r') {
|
||||||
|
line_end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line_end - line_start >= tag_name_len &&
|
||||||
|
!strncmp((const char*)&file_data[line_start], tag_name, tag_name_len))
|
||||||
|
{
|
||||||
|
const char *value_start = (const char*)&file_data[line_start + tag_name_len];
|
||||||
|
const char *value_end = (const char*)&file_data[line_end];
|
||||||
|
|
||||||
|
while (value_start < value_end && (*value_start == ' ' || *value_start == '=')) {
|
||||||
|
value_start++;
|
||||||
|
}
|
||||||
|
const char *comment_pos = value_start;
|
||||||
|
while (comment_pos < value_end && !strchr(comment_symbols, *comment_pos)) {
|
||||||
|
comment_pos++;
|
||||||
|
}
|
||||||
|
while (comment_pos > value_start && (*(comment_pos-1) == ' ' || *(comment_pos-1) == '\t')) {
|
||||||
|
comment_pos--;
|
||||||
|
}
|
||||||
|
if (comment_pos > value_start) {
|
||||||
|
return value_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
line_start = line_end;
|
||||||
|
while (line_start < file_size && (file_data[line_start] == '\n' || file_data[line_start] == '\r')) {
|
||||||
|
line_start++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicbt_parse_config(struct aic_usb_dev *usbdev, const char *filename)
|
||||||
|
{
|
||||||
|
struct device *dev = usbdev->dev;
|
||||||
|
u32 *dst = NULL;
|
||||||
|
int size;
|
||||||
|
const u8 *tag_ptr;
|
||||||
|
u32 tmp_val;
|
||||||
|
//char *filename = "aicbt.conf";
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
size = aic_load_firmware((u32 **)&dst, filename, dev);
|
||||||
|
if (size <= 0) {
|
||||||
|
AICWFDBG(LOGERROR, "%s: load %s fail (%d)\n", __func__, filename, size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag_ptr = aicbt_find_tag((char*)dst, size, "BTMODE=", strlen("0"));
|
||||||
|
if (tag_ptr) {
|
||||||
|
if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].btmode) != 1 ||
|
||||||
|
aicbt_info[usbdev->chipid].btmode > AICBT_BTMODE_BT_ONLY_COANT) {
|
||||||
|
aicbt_info[usbdev->chipid].btmode = AICBT_BTMODE_DEFAULT;
|
||||||
|
AICWFDBG(LOGERROR, "BTMODE invalid, use default %02X\n", AICBT_BTMODE_DEFAULT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aicbt_info[usbdev->chipid].btmode = AICBT_BTMODE_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag_ptr = aicbt_find_tag((char*)dst, size, "BTPORT=", strlen("0"));
|
||||||
|
if (tag_ptr) {
|
||||||
|
if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].btport) != 1 ||
|
||||||
|
aicbt_info[usbdev->chipid].btport > AICBT_BTPORT_UART) {
|
||||||
|
aicbt_info[usbdev->chipid].btport = AICBT_BTPORT_DEFAULT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aicbt_info[usbdev->chipid].btport = AICBT_BTPORT_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag_ptr = aicbt_find_tag((char*)dst, size, "UART_BAUD=", 0);
|
||||||
|
if (tag_ptr) {
|
||||||
|
if (sscanf(tag_ptr, "%u", &tmp_val) == 1) {
|
||||||
|
if(tmp_val >= AICBT_UART_BAUD_115200 && tmp_val <= AICBT_UART_BAUD_3_25M) {
|
||||||
|
aicbt_info[usbdev->chipid].uart_baud = tmp_val;
|
||||||
|
} else {
|
||||||
|
aicbt_info[usbdev->chipid].uart_baud = AICBT_UART_BAUD_DEFAULT;
|
||||||
|
AICWFDBG(LOGERROR, "UART_BAUD %u invalid, use default %d\n", tmp_val, AICBT_UART_BAUD_DEFAULT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aicbt_info[usbdev->chipid].uart_baud = AICBT_UART_BAUD_DEFAULT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aicbt_info[usbdev->chipid].uart_baud = AICBT_UART_BAUD_DEFAULT;
|
||||||
|
}
|
||||||
|
tag_ptr = aicbt_find_tag((char*)dst, size, "UART_FC=", strlen("0"));
|
||||||
|
if (tag_ptr) {
|
||||||
|
if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].uart_flowctrl) != 1 ||
|
||||||
|
aicbt_info[usbdev->chipid].uart_flowctrl > AICBT_UART_FLOWCTRL_ENABLE) {
|
||||||
|
aicbt_info[usbdev->chipid].uart_flowctrl = AICBT_UART_FC_DEFAULT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aicbt_info[usbdev->chipid].uart_flowctrl = AICBT_UART_FC_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag_ptr = aicbt_find_tag((char*)dst, size, "LPM_ENABLE=", strlen("0"));
|
||||||
|
if (tag_ptr) {
|
||||||
|
if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].lpm_enable) != 1 ||
|
||||||
|
aicbt_info[usbdev->chipid].lpm_enable > 1) {
|
||||||
|
aicbt_info[usbdev->chipid].lpm_enable = AICBT_LPM_ENABLE_DEFAULT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aicbt_info[usbdev->chipid].lpm_enable = AICBT_LPM_ENABLE_DEFAULT;
|
||||||
|
}
|
||||||
|
tag_ptr = aicbt_find_tag((char*)dst, size, "TXPWR_LVL=", strlen("0x6F2F"));
|
||||||
|
if (tag_ptr) {
|
||||||
|
if (sscanf(tag_ptr, "%08x", &tmp_val) == 1) {
|
||||||
|
if (tmp_val >= 0 || tmp_val <= 0X7F7F) {
|
||||||
|
aicbt_info[usbdev->chipid].txpwr_lvl = tmp_val;
|
||||||
|
} else {
|
||||||
|
aicbt_info[usbdev->chipid].txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aicbt_info[usbdev->chipid].txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aicbt_info[usbdev->chipid].txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT;
|
||||||
|
}
|
||||||
|
vfree(dst);
|
||||||
|
AICWFDBG(LOGINFO, "%s: btmode %d btport %d uart baud %d uart fc %d lpm %d txpwrlvl %4X\n",
|
||||||
|
__func__,
|
||||||
|
aicbt_info[usbdev->chipid].btmode,
|
||||||
|
aicbt_info[usbdev->chipid].btport,
|
||||||
|
aicbt_info[usbdev->chipid].uart_baud,
|
||||||
|
aicbt_info[usbdev->chipid].uart_flowctrl,
|
||||||
|
aicbt_info[usbdev->chipid].lpm_enable,
|
||||||
|
aicbt_info[usbdev->chipid].txpwr_lvl);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *_head)
|
int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *_head)
|
||||||
{
|
{
|
||||||
struct aicbt_patch_table *head, *p;
|
struct aicbt_patch_table *head, *p;
|
||||||
@@ -1307,11 +1418,12 @@ int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table
|
|||||||
*(data + 15) = aicbt_info[usbdev->chipid].lpm_enable;
|
*(data + 15) = aicbt_info[usbdev->chipid].lpm_enable;
|
||||||
*(data + 17) = aicbt_info[usbdev->chipid].txpwr_lvl;
|
*(data + 17) = aicbt_info[usbdev->chipid].txpwr_lvl;
|
||||||
|
|
||||||
printk("%s bt btmode[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].btmode);
|
printk("%s bt btmode[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].btmode);
|
||||||
printk("%s bt uart_baud[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_baud);
|
printk("%s bt btport[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].btport);
|
||||||
printk("%s bt uart_flowctrl[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_flowctrl);
|
printk("%s bt uart_baud[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_baud);
|
||||||
printk("%s bt lpm_enable[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].lpm_enable);
|
printk("%s bt uart_flowctrl[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_flowctrl);
|
||||||
printk("%s bt tx_pwr[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].txpwr_lvl);
|
printk("%s bt lpm_enable[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].lpm_enable);
|
||||||
|
printk("%s bt tx_pwr[%d]:%4X\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].txpwr_lvl);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (p->type == 0x06) {
|
if (p->type == 0x06) {
|
||||||
@@ -1326,7 +1438,8 @@ int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table
|
|||||||
data += 2;
|
data += 2;
|
||||||
}
|
}
|
||||||
if (p->type == AICBT_PT_PWRON)
|
if (p->type == AICBT_PT_PWRON)
|
||||||
udelay(500);
|
mdelay(100);
|
||||||
|
// udelay(500);
|
||||||
}
|
}
|
||||||
aicbt_patch_table_free(head);
|
aicbt_patch_table_free(head);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1334,7 +1447,6 @@ int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table
|
|||||||
|
|
||||||
int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t)
|
int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t)
|
||||||
{
|
{
|
||||||
uint8_t *patch_info_array = (uint8_t*)patch_info;
|
|
||||||
int base_len = 0;
|
int base_len = 0;
|
||||||
int memcpy_len = 0;
|
int memcpy_len = 0;
|
||||||
|
|
||||||
@@ -1349,17 +1461,35 @@ int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_
|
|||||||
patch_info->info_len = head_t->len;
|
patch_info->info_len = head_t->len;
|
||||||
memcpy_len = patch_info->info_len;
|
memcpy_len = patch_info->info_len;
|
||||||
}
|
}
|
||||||
|
head_t->len = patch_info->info_len;
|
||||||
AICWFDBG(LOGDEBUG, "%s memcpy_len:%d \r\n", __func__, memcpy_len);
|
AICWFDBG(LOGDEBUG, "%s memcpy_len:%d \r\n", __func__, memcpy_len);
|
||||||
|
|
||||||
if (patch_info->info_len == 0)
|
if (patch_info->info_len == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memcpy(((patch_info_array) + sizeof(patch_info->info_len)),
|
if (memcpy_len >= 1) {
|
||||||
head_t->data,
|
patch_info->adid_addrinf = head_t->data[0];
|
||||||
memcpy_len * sizeof(uint32_t) * 2);
|
patch_info->addr_adid = head_t->data[1];
|
||||||
|
}
|
||||||
|
if (memcpy_len >= 2) {
|
||||||
|
patch_info->patch_addrinf = head_t->data[2];
|
||||||
|
patch_info->addr_patch = head_t->data[3];
|
||||||
|
}
|
||||||
|
if (memcpy_len >= 3) {
|
||||||
|
patch_info->reset_addr = head_t->data[4];
|
||||||
|
patch_info->reset_val = head_t->data[5];
|
||||||
|
}
|
||||||
|
if (memcpy_len >= 4) {
|
||||||
|
patch_info->adid_flag_addr = head_t->data[6];
|
||||||
|
patch_info->adid_flag = head_t->data[7];
|
||||||
|
}
|
||||||
|
if (memcpy_len >= 5) {
|
||||||
|
patch_info->ext_patch_nb_addr = head_t->data[8];
|
||||||
|
patch_info->ext_patch_nb = head_t->data[9];
|
||||||
|
}
|
||||||
AICWFDBG(LOGDEBUG, "%s adid_addrinf:%x addr_adid:%x \r\n", __func__,
|
AICWFDBG(LOGDEBUG, "%s adid_addrinf:%x addr_adid:%x \r\n", __func__,
|
||||||
((struct aicbt_patch_info_t *)patch_info_array)->adid_addrinf,
|
patch_info->adid_addrinf,
|
||||||
((struct aicbt_patch_info_t *)patch_info_array)->addr_adid);
|
patch_info->addr_adid);
|
||||||
|
|
||||||
if (patch_info->ext_patch_nb > 0){
|
if (patch_info->ext_patch_nb > 0){
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|||||||
@@ -9,6 +9,53 @@ struct aicbt_patch_table {
|
|||||||
struct aicbt_patch_table *next;
|
struct aicbt_patch_table *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int8_t enable;
|
||||||
|
int8_t dsss;
|
||||||
|
int8_t ofdmlowrate_2g4;
|
||||||
|
int8_t ofdm64qam_2g4;
|
||||||
|
int8_t ofdm256qam_2g4;
|
||||||
|
int8_t ofdm1024qam_2g4;
|
||||||
|
int8_t ofdmlowrate_5g;
|
||||||
|
int8_t ofdm64qam_5g;
|
||||||
|
int8_t ofdm256qam_5g;
|
||||||
|
int8_t ofdm1024qam_5g;
|
||||||
|
} txpwr_idx_conf_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int8_t enable;
|
||||||
|
int8_t chan_1_4;
|
||||||
|
int8_t chan_5_9;
|
||||||
|
int8_t chan_10_13;
|
||||||
|
int8_t chan_36_64;
|
||||||
|
int8_t chan_100_120;
|
||||||
|
int8_t chan_122_140;
|
||||||
|
int8_t chan_142_165;
|
||||||
|
} txpwr_ofst_conf_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int8_t enable;
|
||||||
|
int8_t xtal_cap;
|
||||||
|
int8_t xtal_cap_fine;
|
||||||
|
} xtal_cap_conf_t;
|
||||||
|
|
||||||
|
u32 aic_crc32(u8 *p, u32 len, u32 crc);
|
||||||
|
void get_fw_path(char* fw_path);
|
||||||
|
void set_testmode(int val);
|
||||||
|
int get_testmode(void);
|
||||||
|
int get_hardware_info(void);
|
||||||
|
int get_adap_test(void);
|
||||||
|
int get_flash_bin_size(void);
|
||||||
|
u32 get_flash_bin_crc(void);
|
||||||
|
void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap);
|
||||||
|
void get_userconfig_txpwr_idx(txpwr_idx_conf_t *txpwr_idx);
|
||||||
|
void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst);
|
||||||
|
void rwnx_plat_userconfig_set_value(char *command, char *value);
|
||||||
|
void rwnx_plat_userconfig_parsing(char *buffer, int size);
|
||||||
|
|
||||||
int aic_bt_platform_init(struct aic_usb_dev *sdiodev);
|
int aic_bt_platform_init(struct aic_usb_dev *sdiodev);
|
||||||
|
|
||||||
@@ -30,6 +77,9 @@ int8_t rwnx_atoi(char *value);
|
|||||||
uint32_t rwnx_atoli(char *value);
|
uint32_t rwnx_atoli(char *value);
|
||||||
int aicbt_patch_table_free(struct aicbt_patch_table *head);
|
int aicbt_patch_table_free(struct aicbt_patch_table *head);
|
||||||
struct aicbt_patch_table *aicbt_patch_table_alloc(struct aic_usb_dev *usbdev, const char *filename);
|
struct aicbt_patch_table *aicbt_patch_table_alloc(struct aic_usb_dev *usbdev, const char *filename);
|
||||||
|
#ifdef CONFIG_LOAD_BT_CONF
|
||||||
|
void aicbt_parse_config(struct aic_usb_dev *usbdev, const char *filename);
|
||||||
|
#endif
|
||||||
int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t);
|
int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t);
|
||||||
int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *_head);
|
int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *_head);
|
||||||
|
|
||||||
|
|||||||
@@ -240,7 +240,6 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len)
|
|||||||
struct aicwf_bus *bus = usbdev->bus_if;
|
struct aicwf_bus *bus = usbdev->bus_if;
|
||||||
u8 *buffer = bus->cmd_buf;
|
u8 *buffer = bus->cmd_buf;
|
||||||
u16 index = 0;
|
u16 index = 0;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
memset(buffer, 0, CMD_BUF_MAX);
|
memset(buffer, 0, CMD_BUF_MAX);
|
||||||
buffer[0] = (len+4) & 0x00ff;
|
buffer[0] = (len+4) & 0x00ff;
|
||||||
@@ -262,10 +261,7 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len)
|
|||||||
index += 2;
|
index += 2;
|
||||||
memcpy(&buffer[index], (u8 *)msg->param, msg->param_len);
|
memcpy(&buffer[index], (u8 *)msg->param, msg->param_len);
|
||||||
|
|
||||||
ret = aicwf_bus_txmsg(bus, buffer, len + 8);
|
aicwf_bus_txmsg(bus, buffer, len + 8);
|
||||||
if (ret == -EIO) {
|
|
||||||
ret = aicwf_bus_txmsg(bus, buffer, len + 8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *rwnx_msg_zalloc(lmac_msg_id_t const id,
|
static inline void *rwnx_msg_zalloc(lmac_msg_id_t const id,
|
||||||
@@ -336,7 +332,10 @@ static int rwnx_send_msg(struct aic_usb_dev *usbdev, const void *msg_params,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!reqcfm)
|
if(!reqcfm)
|
||||||
|
{
|
||||||
kfree(cmd);
|
kfree(cmd);
|
||||||
|
rwnx_msg_free(msg, msg_params);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -408,7 +407,7 @@ int rwnx_send_dbg_mem_write_req(struct aic_usb_dev *usbdev, u32 mem_addr, u32 me
|
|||||||
{
|
{
|
||||||
struct dbg_mem_write_req *mem_write_req;
|
struct dbg_mem_write_req *mem_write_req;
|
||||||
|
|
||||||
// printk("%s mem_addr:%x mem_data:%x\r\n", __func__, mem_addr, mem_data);
|
//printk("%s mem_addr:%x mem_data:%x\r\n", __func__, mem_addr, mem_data);
|
||||||
|
|
||||||
/* Build the DBG_MEM_WRITE_REQ message */
|
/* Build the DBG_MEM_WRITE_REQ message */
|
||||||
mem_write_req = rwnx_msg_zalloc(DBG_MEM_WRITE_REQ, TASK_DBG, DRV_TASK_ID,
|
mem_write_req = rwnx_msg_zalloc(DBG_MEM_WRITE_REQ, TASK_DBG, DRV_TASK_ID,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include "aicwf_debug.h"
|
#include "aicwf_debug.h"
|
||||||
|
#include "aicwf_txq_prealloc.h"
|
||||||
|
|
||||||
struct prealloc_txq{
|
struct prealloc_txq{
|
||||||
int prealloced;
|
int prealloced;
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
#ifndef __AICWF_TXQ_PREALLOC_H
|
||||||
|
#define __AICWF_TXQ_PREALLOC_H
|
||||||
|
|
||||||
|
void *aicwf_prealloc_txq_alloc(size_t size);
|
||||||
void aicwf_prealloc_txq_free(void);
|
void aicwf_prealloc_txq_free(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -985,7 +985,7 @@ u32 patch_tbl[][2] ={
|
|||||||
#ifdef CONFIG_USB_SUSPEND_REBOOT_TIME
|
#ifdef CONFIG_USB_SUSPEND_REBOOT_TIME
|
||||||
{0x0110, 0x03e80001}//reboot time when usb suspend,0001 enables reboot on suspend, default 0x3e8 = 1000ms reboot
|
{0x0110, 0x03e80001}//reboot time when usb suspend,0001 enables reboot on suspend, default 0x3e8 = 1000ms reboot
|
||||||
#else
|
#else
|
||||||
#ifdef CONFIG_SUPPORT_USB_SUSP
|
#ifdef CONFIG_WOWLAN
|
||||||
//USB SUSP keep working 0x0100:enable 0x0000:disable
|
//USB SUSP keep working 0x0100:enable 0x0000:disable
|
||||||
{0x0110, 0x00000100}
|
{0x0110, 0x00000100}
|
||||||
#endif
|
#endif
|
||||||
@@ -1367,6 +1367,14 @@ static int aicloadfw_chipmatch(struct aic_usb_dev *usb_dev, u16 vid, u16 pid){
|
|||||||
usb_dev->chipid = PRODUCT_ID_AIC8800D89X2;
|
usb_dev->chipid = PRODUCT_ID_AIC8800D89X2;
|
||||||
AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__);
|
AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
|
}else if(pid == USB_DEVICE_ID_AIC_8800D40X2 && vid == USB_VENDOR_ID_AIC_V2){
|
||||||
|
usb_dev->chipid = PRODUCT_ID_AIC8800D80X2;
|
||||||
|
AICWFDBG(LOGINFO, "%s USE AIC8800D40X2\r\n", __func__);
|
||||||
|
return 0;
|
||||||
|
}else if(pid == USB_DEVICE_ID_AIC_8800D81 && vid == USB_VENDOR_ID_AIC_V2){
|
||||||
|
usb_dev->chipid = PRODUCT_ID_AIC8800D81;
|
||||||
|
AICWFDBG(LOGINFO, "%s USE AIC8800D81 (368b:8d81)\r\n", __func__);
|
||||||
|
return 0;
|
||||||
}else{
|
}else{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1846,6 +1854,8 @@ static struct usb_device_id aicwf_usb_id_table[] = {
|
|||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D80X2)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D80X2)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D81X2)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D81X2)},
|
||||||
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D89X2)},
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D89X2)},
|
||||||
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D40X2)},
|
||||||
|
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D81)}, /* 368b:8d81 */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -42,11 +42,12 @@ enum AICWF_IC{
|
|||||||
PRODUCT_ID_AIC8800D80X2,
|
PRODUCT_ID_AIC8800D80X2,
|
||||||
PRODUCT_ID_AIC8800D81X2,
|
PRODUCT_ID_AIC8800D81X2,
|
||||||
PRODUCT_ID_AIC8800D89X2,
|
PRODUCT_ID_AIC8800D89X2,
|
||||||
|
PRODUCT_ID_AIC8800D40X2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define AICWF_USB_RX_URBS (20)
|
#define AICWF_USB_RX_URBS (20)
|
||||||
#define AICWF_USB_TX_URBS (30)
|
#define AICWF_USB_TX_URBS (100)
|
||||||
#define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4)
|
#define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4)
|
||||||
#define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3)
|
#define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3)
|
||||||
#define AICWF_USB_MAX_PKT_SIZE (2048)
|
#define AICWF_USB_MAX_PKT_SIZE (2048)
|
||||||
@@ -233,6 +234,8 @@ extern void aicwf_usb_tx_flowctrl(struct aic_usb_dev *usb_dev, bool state);
|
|||||||
int usb_bustx_thread(void *data);
|
int usb_bustx_thread(void *data);
|
||||||
int usb_busrx_thread(void *data);
|
int usb_busrx_thread(void *data);
|
||||||
int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv);
|
int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv);
|
||||||
|
int aicfw_download_fw_8800(struct aic_usb_dev *usb_dev);
|
||||||
|
int aicfw_download_fw(struct aic_usb_dev *usb_dev);
|
||||||
|
|
||||||
#endif /* AICWF_USB_SUPPORT */
|
#endif /* AICWF_USB_SUPPORT */
|
||||||
#endif /* _AICWF_USB_H_ */
|
#endif /* _AICWF_USB_H_ */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#define RWNX_VERS_REV "1a4b0054d2M (master)"
|
#define RWNX_VERS_REV "1a4b0054d2M (master)"
|
||||||
#define RWNX_VERS_MOD "6.4.3.0"
|
#define RWNX_VERS_MOD "6.4.3.0"
|
||||||
#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)"
|
#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)"
|
||||||
#define RELEASE_DATE "2025_0423_71b66e7b"
|
#define RELEASE_DATE "2026_0123_5f7be68d"
|
||||||
|
|||||||
@@ -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*");
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# AIC USERCONFIG 2021/0911/2127
|
||||||
|
|
||||||
|
# txpwr_idx
|
||||||
|
enable=1
|
||||||
|
dsss=9
|
||||||
|
ofdmlowrate_2g4=10
|
||||||
|
ofdm64qam_2g4=10
|
||||||
|
ofdm256qam_2g4=9
|
||||||
|
ofdm1024qam_2g4=8
|
||||||
|
ofdmlowrate_5g=10
|
||||||
|
ofdm64qam_5g=9
|
||||||
|
ofdm256qam_5g=9
|
||||||
|
ofdm1024qam_5g=8
|
||||||
|
|
||||||
|
# txpwr_ofst
|
||||||
|
ofst_enable=0
|
||||||
|
ofst_chan_1_4=0
|
||||||
|
ofst_chan_5_9=0
|
||||||
|
ofst_chan_10_13=0
|
||||||
|
ofst_chan_36_64=0
|
||||||
|
ofst_chan_100_120=0
|
||||||
|
ofst_chan_122_140=0
|
||||||
|
ofst_chan_142_165=0
|
||||||
|
|
||||||
|
# xtal cap
|
||||||
|
xtal_enable=0
|
||||||
|
xtal_cap=24
|
||||||
|
xtal_cap_fine=31
|
||||||
|
|
||||||
|
# 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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user