mirror of
https://github.com/shenmintao/aic8800d80.git
synced 2026-09-26 17:44:16 +00:00
Compare commits
65
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b72eea9564 | ||
|
|
defc058cd4 | ||
|
|
9cf132d9b5 | ||
|
|
2c4ab4b421 | ||
|
|
c97644a43a | ||
|
|
7ec1a4fbb1 | ||
|
|
94c72da6d8 | ||
|
|
3e9a02549b | ||
|
|
264f29db21 | ||
|
|
27af5add83 | ||
|
|
9594c5c99a | ||
|
|
31b726adbd | ||
|
|
2895da26d8 | ||
|
|
dd74ae66f7 | ||
|
|
e93a7d2b6b | ||
|
|
30505069fa | ||
|
|
3006aae254 | ||
|
|
b26fef2910 | ||
|
|
8f0b982ec9 | ||
|
|
5e990a5468 | ||
|
|
9747ee3110 | ||
|
|
40379fee97 | ||
|
|
c096067ef3 | ||
|
|
8e0135c948 | ||
|
|
81b8b3335e | ||
|
|
531d16c4d6 | ||
|
|
40f00e69af | ||
|
|
a1f8d3bcb6 | ||
|
|
43ca679bea | ||
|
|
80afe144d1 | ||
|
|
13488f30dc | ||
|
|
050844d924 | ||
|
|
eb3aad9e8d | ||
|
|
e53523ba48 | ||
|
|
0d7a07e8aa | ||
|
|
800a7b93ba | ||
|
|
13baa9b0b1 | ||
|
|
6550131e18 | ||
|
|
268c4f7122 | ||
|
|
c83ae8b4e6 | ||
|
|
4b31d02392 | ||
|
|
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,7 @@
|
||||
/.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
|
||||
|
||||
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 dependency installation
|
||||
- Automatic driver compilation and installation
|
||||
- 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
|
||||
- Colored output and logging
|
||||
- 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,43 @@
|
||||
# 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.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Choose the branch for your hardware revision before installing.** If the
|
||||
> driver log reports `chip_id=7, chip_mcu_id=1` on an AIC8800D80 or
|
||||
> AIC8800DC/DW device, use the
|
||||
> [`legacy-mcu1`](https://github.com/shenmintao/aic8800d80/tree/legacy-mcu1)
|
||||
> branch. It contains the matched legacy firmware and loader profile required
|
||||
> to avoid the deterministic firmware upload timeout at `0x170400`. Use
|
||||
> `main` when `chip_mcu_id=0` or when the MCU revision is unknown.
|
||||
>
|
||||
> Hardware revision determines the firmware branch. MCU1 devices should use
|
||||
> `legacy-mcu1`, which also initializes Bluetooth for the
|
||||
> kernel's standard `btusb` driver. After switching branches, rerun
|
||||
> `sudo ./install.sh` and reboot; switching the Git branch alone does not
|
||||
> replace the firmware already installed under `/lib/firmware`.
|
||||
|
||||
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.
|
||||
|
||||
> **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.
|
||||
> [!NOTE]
|
||||
> **Maintained branches:** This repository now maintains two hardware branches:
|
||||
> `main` for `chip_mcu_id=0` or an unknown MCU revision, and `legacy-mcu1` for
|
||||
> `chip_mcu_id=1`. Wi-Fi, the kernel's standard `btusb` Bluetooth path, and the
|
||||
> device-scoped ZLP support are integrated into both branches. The former
|
||||
> separate `bluetooth` branch is retired and should no longer be used.
|
||||
|
||||
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.
|
||||
|
||||
### 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.
|
||||
@@ -13,25 +45,49 @@ I did not develop this software, The code is sourced from the Tenda U11 driver.
|
||||
### Attention
|
||||
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
|
||||
|
||||
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 2: Manual Installation
|
||||
|
||||
#### 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
|
||||
sudo cp aic.rules /lib/udev/rules.d/
|
||||
sudo cp aic.rules /usr/lib/udev/rules.d/
|
||||
```
|
||||
|
||||
#### Copy firmware:
|
||||
|
||||
Copy the aic8800D80 folder from ./fw to /lib/firmware/:
|
||||
Copy the firmware directories from `./fw` to `/lib/firmware/`:
|
||||
|
||||
```bash
|
||||
sudo cp -r ./fw/aic8800D80 /lib/firmware/
|
||||
sudo cp -r ./fw/aic8800* /lib/firmware/
|
||||
```
|
||||
#### Navigate to the driver directory:
|
||||
|
||||
@@ -98,3 +154,52 @@ If the device is still not active, check the kernel logs for any errors related
|
||||
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}=="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}=="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"
|
||||
@@ -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}=="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}=="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 3e9a02549bc98d350bff1e0fb0501f841f9d8e55
|
||||
%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^20260924git3e9a025-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> - 3e9a025-1
|
||||
- Build the current main branch, which adds the Linux 7.1+ TDLS discovery
|
||||
response length fix, the SUN60IW2P1 USB transfer settings, OpenWrt
|
||||
cfg80211 backport version handling and the 6.12 stable
|
||||
set_monitor_channel() fix.
|
||||
|
||||
* Fri Aug 21 2026 Heyde Moura <moura.heyde@gmail.com> - e93a7d2-1
|
||||
- Build the current main branch, which carries the Linux 7.2 cfg80211 and
|
||||
strncpy() fixes needed to compile on Bazzite 44.
|
||||
|
||||
* Tue Jul 28 2026 ccyuen1 - 13baa9b-2
|
||||
- Disable automatic creation of debuginfo packages to fix issue #77.
|
||||
- Require usb_modeswitch as package dependency instead of file dependency to fix issue #77.
|
||||
|
||||
* 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 ==="
|
||||
+89
-29
@@ -17,6 +17,29 @@ YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
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() {
|
||||
echo ""
|
||||
echo -e "${BLUE}━━━ $1 ━━━${NC}"
|
||||
@@ -58,46 +81,73 @@ fi
|
||||
|
||||
print_section "2. Checking DKMS directory"
|
||||
|
||||
if [ -d "/usr/src/aic8800-1.0.0" ]; then
|
||||
echo -e "${GREEN}✓${NC} /usr/src/aic8800-1.0.0 directory exists"
|
||||
echo ""
|
||||
echo "Content:"
|
||||
ls -la /usr/src/aic8800-1.0.0/
|
||||
echo ""
|
||||
echo "Detected package: ${DRV_NAME}/${DRV_VERSION}"
|
||||
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 "Content:"
|
||||
ls -la "$source_dir/"
|
||||
echo ""
|
||||
|
||||
echo "Checking drivers/aic8800 inside DKMS:"
|
||||
if [ -d "/usr/src/aic8800-1.0.0/drivers/aic8800" ]; then
|
||||
echo -e "${GREEN}✓${NC} drivers/aic8800 copied to DKMS"
|
||||
ls -la /usr/src/aic8800-1.0.0/drivers/aic8800/
|
||||
else
|
||||
echo -e "${RED}✗${NC} drivers/aic8800 NOT copied correctly!"
|
||||
fi
|
||||
echo "Checking drivers/aic8800 inside DKMS:"
|
||||
if [ -d "$source_dir/drivers/aic8800" ]; then
|
||||
echo -e "${GREEN}✓${NC} drivers/aic8800 copied to DKMS"
|
||||
ls -la "$source_dir/drivers/aic8800/"
|
||||
else
|
||||
echo -e "${RED}✗${NC} drivers/aic8800 NOT copied correctly!"
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
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
|
||||
|
||||
print_section "3. Checking DKMS build logs"
|
||||
|
||||
if [ -f "/var/lib/dkms/aic8800/1.0.0/build/make.log" ]; then
|
||||
echo -e "${GREEN}✓${NC} Build log found"
|
||||
mapfile -t BUILD_LOGS < <(find "/var/lib/dkms/${DRV_NAME}" -type f -name make.log -print 2>/dev/null | sort)
|
||||
|
||||
if [ "${#BUILD_LOGS[@]}" -gt 0 ]; then
|
||||
for build_log in "${BUILD_LOGS[@]}"; do
|
||||
echo -e "${GREEN}✓${NC} Build log found: $build_log"
|
||||
echo ""
|
||||
echo "Last 50 lines of make.log:"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
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 "Last 50 lines of make.log:"
|
||||
echo -e "${GREEN}✓${NC} Installer log found: $INSTALL_LOG"
|
||||
echo "Last 50 lines of installer log:"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
tail -50 /var/lib/dkms/aic8800/1.0.0/build/make.log
|
||||
tail -50 "$INSTALL_LOG"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
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
|
||||
|
||||
print_section "4. Checking dkms.conf"
|
||||
|
||||
if [ -f "/usr/src/aic8800-1.0.0/dkms.conf" ]; then
|
||||
echo -e "${GREEN}✓${NC} dkms.conf found"
|
||||
echo ""
|
||||
echo "dkms.conf content:"
|
||||
cat /usr/src/aic8800-1.0.0/dkms.conf
|
||||
if [ "${#DKMS_SOURCE_DIRS[@]}" -gt 0 ]; then
|
||||
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 ""
|
||||
cat "$source_dir/dkms.conf"
|
||||
echo ""
|
||||
else
|
||||
echo -e "${RED}✗${NC} dkms.conf NOT FOUND in $source_dir"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo -e "${RED}✗${NC} dkms.conf NOT FOUND!"
|
||||
echo -e "${RED}✗${NC} No DKMS source directory available to inspect"
|
||||
fi
|
||||
|
||||
if [ -f "./dkms.conf" ]; then
|
||||
@@ -120,13 +170,23 @@ print_section "6. System information"
|
||||
echo "Kernel: $(uname -r)"
|
||||
echo "Architecture: $(uname -m)"
|
||||
echo ""
|
||||
echo "GCC version:"
|
||||
gcc --version | head -1
|
||||
echo "Compiler version:"
|
||||
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 "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"
|
||||
|
||||
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_VERSION="1.0.0"
|
||||
MAKE="KVER=${kernelver} 'make' -C drivers/aic8800"
|
||||
CLEAN="KVER=${kernelver} 'make' -C drivers/aic8800 clean"
|
||||
MAKE="KVER=${kernelver} KDIR=/lib/modules/${kernelver}/build 'make' -C drivers/aic8800"
|
||||
CLEAN="KVER=${kernelver} KDIR=/lib/modules/${kernelver}/build 'make' -C drivers/aic8800 clean"
|
||||
|
||||
# Main module (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"
|
||||
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"
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
CONFIG_AIC_LOADFW_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_AIC_ZLP_QUIRK) += aic_zlp_quirk/
|
||||
|
||||
########## config option ##########
|
||||
export CONFIG_USE_FW_REQUEST = n
|
||||
export CONFIG_PREALLOC_RX_SKB = y
|
||||
export CONFIG_PREALLOC_TXQ = y
|
||||
export CONFIG_WOWLAN = n
|
||||
###################################
|
||||
|
||||
########## platform support list ##########
|
||||
@@ -47,34 +50,49 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
||||
KVER ?= $(shell uname -r)
|
||||
KDIR = /lib/modules/$(KVER)/build
|
||||
KDIR ?= /lib/modules/$(KVER)/build
|
||||
PWD = $(shell pwd)
|
||||
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)
|
||||
CROSS_COMPILE ?=
|
||||
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
|
||||
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:
|
||||
mkdir -p $(MODDESTDIR)
|
||||
mkdir -p $(BTMODDESTDIR)
|
||||
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 aic_zlp_quirk/aic_zlp_quirk.ko $(BTMODDESTDIR)/
|
||||
/sbin/depmod -a ${KVER}
|
||||
|
||||
uninstall:
|
||||
rm -rfv $(MODDESTDIR)/aic_load_fw.ko
|
||||
rm -rfv $(MODDESTDIR)/aic8800_fdrv.ko
|
||||
rm -rfv $(BTMODDESTDIR)/aic_zlp_quirk.ko
|
||||
/sbin/depmod -a ${KVER}
|
||||
|
||||
clean:
|
||||
cd aic_load_fw/;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/
|
||||
|
||||
@@ -2,6 +2,16 @@ EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS)
|
||||
EXTRA_CFLAGS += -Wno-implicit-fallthrough
|
||||
#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
|
||||
|
||||
CONFIG_AIC8800_WLAN_SUPPORT = m
|
||||
@@ -74,7 +84,11 @@ CONFIG_VHT_FOR_OLD_KERNEL = n
|
||||
CONFIG_COEX = y
|
||||
CONFIG_ALIGN_8BYTES = y
|
||||
CONFIG_TXRX_THREAD_PRIO = y
|
||||
ifdef CONFIG_ARCH_SUN60IW2P1
|
||||
CONFIG_USB_ALIGN_DATA = n
|
||||
else
|
||||
CONFIG_USB_ALIGN_DATA = y
|
||||
endif
|
||||
CONFIG_RX_TASKLET = n
|
||||
CONFIG_TX_TASKLET = n
|
||||
CONFIG_RX_NETIF_RECV_SKB = y
|
||||
@@ -82,18 +96,22 @@ CONFIG_BR_SUPPORT = n
|
||||
CONFIG_USB_MSG_OUT_EP = y
|
||||
CONFIG_USB_MSG_IN_EP = y
|
||||
CONFIG_USB_RX_REASSEMBLE = n
|
||||
CONFIG_WOWLAN = n
|
||||
CONFIG_WOWLAN ?= n
|
||||
|
||||
#DCDW support tx aggr, D80 support both
|
||||
CONFIG_USB_RX_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
|
||||
endif
|
||||
CONFIG_GPIO_WAKEUP = n
|
||||
CONFIG_CREATE_TRACE_POINTS = n
|
||||
CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y
|
||||
CONFIG_USE_USB_ZERO_PACKET = y
|
||||
CONFIG_DEBUG_FS = n
|
||||
CONFIG_DEBUG_FS ?= n
|
||||
CONFIG_STA_SCAN_WHEN_P2P_WORKING = y
|
||||
CONFIG_SET_VENDOR_EXTENSION_IE = n
|
||||
CONFIG_VENDOR_GPIO = n
|
||||
@@ -114,6 +132,7 @@ CONFIG_LOFT_CALIB = n
|
||||
CONFIG_GKI = n
|
||||
CONFIG_SCHED_SCAN = n
|
||||
CONFIG_TEMP_COMP = n
|
||||
CONFIG_TEMP_CONTROL = n
|
||||
CONFIG_POWER_LIMIT = n
|
||||
CONFIG_EXT_FEM_8800DCDW = n
|
||||
# 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_PERPWR = n
|
||||
CONFIG_BAND_STEERING = n
|
||||
CONFIG_PRBREQ_REPORT = n
|
||||
CONFIG_SUPPORT_4ADDR = n
|
||||
|
||||
#support D80X2 can write rf result to file
|
||||
CONFIG_WRITE_FILE_D80X2 = n
|
||||
@@ -151,7 +172,7 @@ CONFIG_RWNX_BCMC ?= y
|
||||
|
||||
# Enable Monitor+Data interface support (need FW support)
|
||||
CONFIG_RWNX_MON_DATA =n
|
||||
CONFIG_RWNX_MON_XMIT ?= n
|
||||
CONFIG_RWNX_MON_XMIT ?= y
|
||||
CONFIG_RWNX_MON_RXFILTER ?= n
|
||||
|
||||
CONFIG_FILTER_TCP_ACK =y
|
||||
@@ -189,7 +210,9 @@ $(MODULE_NAME)-y := \
|
||||
aic_priv_cmd.o \
|
||||
aicwf_compat_8800dc.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 \
|
||||
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_PERPWR) += -DCONFIG_DYNAMIC_PERPWR
|
||||
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
|
||||
|
||||
ifeq ($(CONFIG_SDIO_SUPPORT), y)
|
||||
@@ -338,10 +363,10 @@ ccflags-$(CONFIG_GKI) += -DCONFIG_GKI
|
||||
ccflags-$(CONFIG_SCHED_SCAN) += -DCONFIG_SCHED_SCAN
|
||||
ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK
|
||||
ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP
|
||||
ccflags-$(CONFIG_TEMP_CONTROL) += -DCONFIG_TEMP_CONTROL
|
||||
ccflags-$(CONFIG_POWER_LIMIT) += -DCONFIG_POWER_LIMIT
|
||||
ccflags-$(CONFIG_EXT_FEM_8800DCDW) += -DCONFIG_EXT_FEM_8800DCDW
|
||||
ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN
|
||||
|
||||
# Platform support list
|
||||
CONFIG_PLATFORM_ROCKCHIP ?= n
|
||||
CONFIG_PLATFORM_ALLWINNER ?= n
|
||||
@@ -380,11 +405,13 @@ KDIR ?= /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
||||
KVER := $(or $(KVER), $(kernelver), $(KERNELRELEASE), $(shell uname -r))
|
||||
KVER ?= $(shell uname -r)
|
||||
KDIR ?= /lib/modules/$(KVER)/build
|
||||
#KDIR ?= ~/D/Workspace/CyberQuantum/Linux/linux-4.15/
|
||||
PWD ?= $(shell pwd)
|
||||
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 ?=
|
||||
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
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*****************************************************************************/
|
||||
* 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_
|
||||
#include <linux/version.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/if_arp.h>
|
||||
#include <net/ip.h>
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||
#include <net/ipx.h>
|
||||
#endif
|
||||
#include <linux/atalk.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/if_pppox.h>
|
||||
@@ -54,6 +61,7 @@
|
||||
#define MAGIC_CODE_LEN 2
|
||||
#define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
How database records network address:
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
static void __nat25_db_print(struct rwnx_vif *vif)
|
||||
{
|
||||
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));
|
||||
|
||||
#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 */
|
||||
/*---------------------------------------------------*/
|
||||
@@ -849,7 +872,6 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
|
||||
|
||||
case NAT25_LOOKUP: {
|
||||
printk("NAT25: Lookup ARP\n");
|
||||
|
||||
arp_ptr += arp->ar_hln;
|
||||
sender = (unsigned int *)arp_ptr;
|
||||
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 */
|
||||
/*---------------------------------------------------*/
|
||||
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_AARP))) {
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||
unsigned char ipx_header[2] = {0xFF, 0xFF};
|
||||
struct ipxhdr *ipx = NULL;
|
||||
#endif
|
||||
struct elapaarp *ea = NULL;
|
||||
struct ddpehdr *ddp = NULL;
|
||||
unsigned char *framePtr = skb->data + ETH_HLEN;
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||
if (protocol == __constant_htons(ETH_P_IPX)) {
|
||||
printk("NAT25: Protocol=IPX (Ethernet II)\n");
|
||||
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)) {
|
||||
printk("NAT25: Protocol=IPX (Ethernet 802.3)\n");
|
||||
ipx = (struct ipxhdr *)framePtr;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
unsigned char ipx_8022_type = 0xE0;
|
||||
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 */
|
||||
|
||||
framePtr += 3; /* eliminate the 802.2 header */
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||
if (!memcmp(ipx_snap_id, framePtr, 5)) {
|
||||
framePtr += 5; /* eliminate the SNAP header */
|
||||
|
||||
printk("NAT25: Protocol=IPX (Ethernet SNAP)\n");
|
||||
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 */
|
||||
|
||||
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]);
|
||||
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 */
|
||||
|
||||
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
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
|
||||
/* IPX */
|
||||
if (ipx != NULL) {
|
||||
switch (method) {
|
||||
@@ -997,10 +1036,11 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
|
||||
/* AARP */
|
||||
else if (ea != NULL) {
|
||||
if (ea != NULL) {
|
||||
/* Sanity check fields. */
|
||||
if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) {
|
||||
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
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*****************************************************************************/
|
||||
* 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_
|
||||
#define _AIC_BR_EXT_H_
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/ctype.h>
|
||||
#include "rwnx_defs.h"
|
||||
#include "rwnx_msg_tx.h"
|
||||
@@ -90,6 +88,7 @@ enum {
|
||||
EXEC_FLASH_OPER,
|
||||
RDWR_PWRADD2X,
|
||||
RDWR_EFUSE_PWRADD2X,
|
||||
GET_RSSI=0x52,
|
||||
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,
|
||||
settx_param.mode, settx_param.rate, settx_param.length, settx_param.tx_intv_us);
|
||||
#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;
|
||||
get_userconfig_txpwr_loss(txpwr_loss);
|
||||
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);
|
||||
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);
|
||||
return (6 * 12);
|
||||
} 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
|
||||
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, 0, NULL, &cfm);
|
||||
} 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 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};
|
||||
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);
|
||||
} 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);
|
||||
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};
|
||||
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);
|
||||
@@ -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);
|
||||
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;
|
||||
} 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;
|
||||
} else if ((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // ant0/1
|
||||
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
|
||||
if (argc > 3) {
|
||||
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};
|
||||
AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst);
|
||||
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
|
||||
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
|
||||
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 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};
|
||||
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);
|
||||
} 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);
|
||||
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};
|
||||
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);
|
||||
@@ -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);
|
||||
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;
|
||||
} 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;
|
||||
} 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;
|
||||
@@ -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
|
||||
if (argc > 3) {
|
||||
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};
|
||||
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);
|
||||
@@ -1273,6 +1279,49 @@ static int aic_priv_cmd_set_pll_test (struct rwnx_hw *rwnx_hw, int argc, char *a
|
||||
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)
|
||||
{
|
||||
u8_l func = 0;
|
||||
@@ -1340,6 +1389,12 @@ static int aic_priv_cmd_country_set(struct rwnx_hw *rwnx_hw, int argc,
|
||||
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]);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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" },
|
||||
{ "set_pll_test", aic_priv_cmd_set_pll_test,
|
||||
"<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,
|
||||
"<val> = 0/ant0, 1/ant1, 2/both" },
|
||||
{ "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"},
|
||||
{"check_flash", aic_priv_cmd_check_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.
|
||||
{ "help", aic_priv_cmd_help,
|
||||
@@ -1716,7 +1832,7 @@ void set_vendor_extension_ie(char *command){
|
||||
|
||||
}
|
||||
#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,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
#else
|
||||
@@ -1724,7 +1840,7 @@ int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
#endif
|
||||
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)
|
||||
#else
|
||||
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_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);
|
||||
#else
|
||||
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));
|
||||
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)) {
|
||||
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"))) {
|
||||
skip = strlen(CMD_SET_COUNTRY) + 1;
|
||||
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) {
|
||||
AICWFDBG(LOGERROR, "%s: invalid country code\n", __func__);
|
||||
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->usbdev->chipid == PRODUCT_ID_AIC8800DW ||
|
||||
(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_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);
|
||||
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;
|
||||
skip = strlen(CMD_SET_MON_FREQ) + 1;
|
||||
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);
|
||||
#else
|
||||
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 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_ */
|
||||
|
||||
|
||||
@@ -323,6 +323,13 @@ static int aicwf_vendor_subcmd_set_country_code(struct wiphy *wiphy, struct wire
|
||||
const struct nlattr *iter;
|
||||
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) {
|
||||
type = nla_type(iter);
|
||||
switch (type) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define _AIC_VENDOR_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "rwnx_defs.h"
|
||||
|
||||
#define GOOGLE_OUI 0x001A11
|
||||
#define BRCM_OUI 0x001018
|
||||
@@ -342,5 +343,10 @@ typedef struct wl_mkeep_alive_pkt {
|
||||
u8 data[1];
|
||||
} 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 */
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#include "rwnx_main.h"
|
||||
#include "rwnx_msg_tx.h"
|
||||
#include "reg_access.h"
|
||||
#include "aicwf_compat_8800d80.h"
|
||||
|
||||
#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"
|
||||
|
||||
extern char aic_fw_path[200];
|
||||
@@ -40,23 +38,10 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){
|
||||
int size;
|
||||
u32 *dst=NULL;
|
||||
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
|
||||
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
|
||||
|
||||
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);
|
||||
|
||||
/* parsing the file */
|
||||
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code);
|
||||
rwnx_plat_powerlimit_parsing((char *)dst, size);
|
||||
|
||||
rwnx_release_firmware_common(&dst);
|
||||
|
||||
@@ -111,3 +96,37 @@ int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw)
|
||||
}
|
||||
#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);
|
||||
#endif
|
||||
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_msg_tx.h"
|
||||
#include "reg_access.h"
|
||||
#include "aicwf_compat_8800d80x2.h"
|
||||
|
||||
#define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_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;
|
||||
|
||||
#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
|
||||
|
||||
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);
|
||||
|
||||
/* parsing the file */
|
||||
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code);
|
||||
rwnx_plat_powerlimit_parsing((char *)dst, size);
|
||||
|
||||
rwnx_release_firmware_common(&dst);
|
||||
|
||||
|
||||
@@ -45,8 +45,6 @@
|
||||
#define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt"
|
||||
#define FW_POWERLIMIT_NAME_8800DC "aic_powerlimit_8800dc.txt"
|
||||
#define FW_POWERLIMIT_NAME_8800DW "aic_powerlimit_8800dw.txt"
|
||||
#define FW_USERCONFIG_NAME_8800DW_W311 "aic_userconfig_8800dw_w311.txt"
|
||||
#define FW_USERCONFIG_NAME_8800DW_U2 "aic_userconfig_8800dw_u2.txt"
|
||||
|
||||
#ifdef CONFIG_LOAD_BT_PATCH_IN_FDRV
|
||||
enum aicbt_patch_table_type {
|
||||
@@ -169,6 +167,7 @@ u32 syscfg_tbl_masked_8800dc[][3] = {
|
||||
{0x700010A0, (0x1 << 11), (0x1 << 11)},
|
||||
{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
|
||||
{0x70001038, (0x1 << 8), (0x1 << 8)},
|
||||
{0x70001084, (0x3 << 13), (0x0 << 13)},
|
||||
{0x70001094, (0x3 << 2), (0x0 << 2)},
|
||||
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
|
||||
{0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)),
|
||||
@@ -186,6 +185,7 @@ u32 syscfg_tbl_masked_8800dc[][3] = {
|
||||
{0x700010A0, (0x1 << 11), (0x1 << 11)},
|
||||
{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
|
||||
{0x70001038, (0x1 << 8), (0x1 << 8)},
|
||||
{0x70001084, (0x3 << 13), (0x0 << 13)},
|
||||
{0x70001094, (0x3 << 2), (0x0 << 2)},
|
||||
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
|
||||
{0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)),
|
||||
@@ -211,6 +211,7 @@ u32 syscfg_tbl_masked_8800dc_h[][3] = {
|
||||
{0x700010A0, (0x1 << 11), (0x1 << 11)},
|
||||
//{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
|
||||
{0x70001038, (0x1 << 8), (0x1 << 8)},
|
||||
{0x70001084, (0x3 << 13), (0x0 << 13)},
|
||||
{0x70001094, (0x3 << 2), (0x0 << 2)},
|
||||
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
|
||||
#if defined(CONFIG_VRF_DCDC_MODE)
|
||||
@@ -242,7 +243,6 @@ u32 syscfg_tbl_8800dc[][2] = {
|
||||
|
||||
u32 patch_tbl_wifisetting[][2] =
|
||||
{
|
||||
{0x0004, 0x00020010}, //wdt_reboot_type, wdt_period_sec
|
||||
#if !defined(CONFIG_FPGA_VERIFICATION)
|
||||
{0x0090, 0x0013FC00}, //rx_ringbuf_start2
|
||||
#endif
|
||||
@@ -251,10 +251,9 @@ u32 patch_tbl_wifisetting[][2] =
|
||||
{0x0120, 0x140A0100}, //usb agg tx params(total cnt, aggr cnt, out en, global out nak)
|
||||
#endif //CONFIG_USB_TX_AGGR
|
||||
{0x00b0, 0xAD180100},
|
||||
#ifdef CONFIG_BAND_STEERING
|
||||
#ifdef CONFIG_PRBREQ_REPORT
|
||||
{0x0138, 0x00010a00}, //apm probe resp offload en
|
||||
#endif
|
||||
{0x0084, 0x00000040},
|
||||
};
|
||||
|
||||
u32 jump_tbl[][2] =
|
||||
@@ -1872,104 +1871,104 @@ const uint32_t txgain_map_femkct[96] =
|
||||
const uint32_t txgain_map_femkct_h[96] =
|
||||
{
|
||||
//11b
|
||||
0x00ffd872,//15
|
||||
0x00ffd880,//16
|
||||
0x00ffd972,//17
|
||||
0x00ffd980,//18
|
||||
0x00ffd990,//19
|
||||
0x00ffda72,//20
|
||||
0x00ffda80,//21
|
||||
0x00ffdb72,//22
|
||||
0x00ffdb80,//23
|
||||
0x00ffdc72,//24
|
||||
0x00ffdc80,//25
|
||||
0x00ffdd72,//26
|
||||
0x00ffdd80,//27
|
||||
0x00ffde72,//28
|
||||
0x00ffde80,//29
|
||||
0x00ffdf72,//30
|
||||
0x00ffd072,//-1
|
||||
0x00ffd072,//0
|
||||
0x00ffd080,//1
|
||||
0x00ffd172,//2
|
||||
0x00ffd180,//3
|
||||
0x00ffd272,//4
|
||||
0x00ffd280,//5
|
||||
0x00ffd379,//6
|
||||
0x00ffd46d,//7
|
||||
0x00ffd479,//8
|
||||
0x00ffd572,//9
|
||||
0x00ffd580,//10
|
||||
0x00ffd672,//11
|
||||
0x00ffd680,//12
|
||||
0x00ffd772,//13
|
||||
0x00ffd780,//14
|
||||
0x00ffd86c,//15
|
||||
0x00ffd879,//16
|
||||
0x00ffd96c,//17
|
||||
0x00ffd979,//18
|
||||
0x00ffd988,//19
|
||||
0x00ffda6c,//20
|
||||
0x00ffda79,//21
|
||||
0x00ffdb6c,//22
|
||||
0x00ffdb79,//23
|
||||
0x00ffdc6c,//24
|
||||
0x00ffdc79,//25
|
||||
0x00ffdd6c,//26
|
||||
0x00ffdd79,//27
|
||||
0x00ffde6c,//28
|
||||
0x00ffde79,//29
|
||||
0x00ffdf6c,//30
|
||||
0x00ffd06c,//-1
|
||||
0x00ffd06c,//0
|
||||
0x00ffd079,//1
|
||||
0x00ffd16c,//2
|
||||
0x00ffd179,//3
|
||||
0x00ffd26c,//4
|
||||
0x00ffd279,//5
|
||||
0x00ffd372,//6
|
||||
0x00ffd467,//7
|
||||
0x00ffd472,//8
|
||||
0x00ffd56c,//9
|
||||
0x00ffd579,//10
|
||||
0x00ffd66c,//11
|
||||
0x00ffd679,//12
|
||||
0x00ffd76c,//13
|
||||
0x00ffd779,//14
|
||||
//high
|
||||
0x00ffc880,//11
|
||||
0x00ffc972,//12
|
||||
0x00ffc980,//13
|
||||
0x00ffca72,//14
|
||||
0x00ffca80,//15
|
||||
0x00ffcb72,//16
|
||||
0x00ffcb80,//17
|
||||
0x00ffcc72,//18
|
||||
0x00ffcc80,//19
|
||||
0x00ffcc90,//20
|
||||
0x00ffcd72,//21
|
||||
0x00ffcd80,//22
|
||||
0x00ffce72,//23
|
||||
0x00ffce80,//24
|
||||
0x00ffcf72,//25
|
||||
0x00ffcf80,//26
|
||||
0x00ffc080,//-5
|
||||
0x00ffc172,//-4
|
||||
0x00ffc180,//-3
|
||||
0x00ffc272,//-2
|
||||
0x00ffc280,//-1
|
||||
0x00ffc372,//0
|
||||
0x00ffc380,//1
|
||||
0x00ffc472,//2
|
||||
0x00ffc480,//3
|
||||
0x00ffc572,//4
|
||||
0x00ffc580,//5
|
||||
0x00ffc672,//6
|
||||
0x00ffc680,//7
|
||||
0x00ffc772,//8
|
||||
0x00ffc780,//9
|
||||
0x00ffc872,//10
|
||||
0x00ffc879,//11
|
||||
0x00ffc96c,//12
|
||||
0x00ffc979,//13
|
||||
0x00ffca6c,//14
|
||||
0x00ffca79,//15
|
||||
0x00ffcb6c,//16
|
||||
0x00ffcb79,//17
|
||||
0x00ffcc6c,//18
|
||||
0x00ffcc79,//19
|
||||
0x00ffcc88,//20
|
||||
0x00ffcd6c,//21
|
||||
0x00ffcd79,//22
|
||||
0x00ffce6c,//23
|
||||
0x00ffce79,//24
|
||||
0x00ffcf6c,//25
|
||||
0x00ffcf79,//26
|
||||
0x00ffc079,//-5
|
||||
0x00ffc16c,//-4
|
||||
0x00ffc179,//-3
|
||||
0x00ffc26c,//-2
|
||||
0x00ffc279,//-1
|
||||
0x00ffc36c,//0
|
||||
0x00ffc379,//1
|
||||
0x00ffc46c,//2
|
||||
0x00ffc479,//3
|
||||
0x00ffc56c,//4
|
||||
0x00ffc579,//5
|
||||
0x00ffc66c,//6
|
||||
0x00ffc679,//7
|
||||
0x00ffc76c,//8
|
||||
0x00ffc779,//9
|
||||
0x00ffc86c,//10
|
||||
//low
|
||||
0x00ffc880,//11
|
||||
0x00ffc972,//12
|
||||
0x00ffc980,//13
|
||||
0x00ffca72,//14
|
||||
0x00ffca80,//15
|
||||
0x00ffcb72,//16
|
||||
0x00ffcb80,//17
|
||||
0x00ffcc72,//18
|
||||
0x00ffcc80,//19
|
||||
0x00ffcc90,//20
|
||||
0x00ffcd72,//21
|
||||
0x00ffcd80,//22
|
||||
0x00ffce72,//23
|
||||
0x00ffce80,//24
|
||||
0x00ffcf72,//25
|
||||
0x00ffcf80,//26
|
||||
0x00ffc080,//-5
|
||||
0x00ffc172,//-4
|
||||
0x00ffc180,//-3
|
||||
0x00ffc272,//-2
|
||||
0x00ffc280,//-1
|
||||
0x00ffc372,//0
|
||||
0x00ffc380,//1
|
||||
0x00ffc472,//2
|
||||
0x00ffc480,//3
|
||||
0x00ffc572,//4
|
||||
0x00ffc580,//5
|
||||
0x00ffc672,//6
|
||||
0x00ffc680,//7
|
||||
0x00ffc772,//8
|
||||
0x00ffc780,//9
|
||||
0x00ffc872,//10
|
||||
0x00ffc879,//11
|
||||
0x00ffc96c,//12
|
||||
0x00ffc979,//13
|
||||
0x00ffca6c,//14
|
||||
0x00ffca79,//15
|
||||
0x00ffcb6c,//16
|
||||
0x00ffcb79,//17
|
||||
0x00ffcc6c,//18
|
||||
0x00ffcc79,//19
|
||||
0x00ffcc88,//20
|
||||
0x00ffcd6c,//21
|
||||
0x00ffcd79,//22
|
||||
0x00ffce6c,//23
|
||||
0x00ffce79,//24
|
||||
0x00ffcf6c,//25
|
||||
0x00ffcf79,//26
|
||||
0x00ffc079,//-5
|
||||
0x00ffc16c,//-4
|
||||
0x00ffc179,//-3
|
||||
0x00ffc26c,//-2
|
||||
0x00ffc279,//-1
|
||||
0x00ffc36c,//0
|
||||
0x00ffc379,//1
|
||||
0x00ffc46c,//2
|
||||
0x00ffc479,//3
|
||||
0x00ffc56c,//4
|
||||
0x00ffc579,//5
|
||||
0x00ffc66c,//6
|
||||
0x00ffc679,//7
|
||||
0x00ffc76c,//8
|
||||
0x00ffc779,//9
|
||||
0x00ffc86c,//10
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -2205,6 +2204,141 @@ uint32_t wifi_txgain_table_24g_1_8800dcdw_femkct[32] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_5M10M
|
||||
u32 wifi_rxgain_table_24g_dcdw_5m[64] = {
|
||||
0x82f282d1,//index 0
|
||||
0x9591a200,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x42f282d1,//index 1
|
||||
0x95923400,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x22f282d1,//index 2
|
||||
0x9592c600,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282d1,//index 3
|
||||
0x9591a200,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x06f282d1,//index 4
|
||||
0x9591a200,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x0ef282d1,//index 5
|
||||
0x9591a200,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x0ef282d3,//index 6
|
||||
0x95923400,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x0ef282d7,//index 7
|
||||
0x9595a200,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282d2,//index 8
|
||||
0x95951000,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282f4,//index 9
|
||||
0x95951000,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282e6,//index 10
|
||||
0x9595a200,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282e6,//index 11
|
||||
0x9599a200,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282e6,//index 12
|
||||
0x959da200,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282e6,//index 13
|
||||
0x959f5800,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x06f282e6,//index 14
|
||||
0x959f5800,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x0ef282e6,//index 15
|
||||
0x959f5800,
|
||||
0x80808419,
|
||||
0x000000f0
|
||||
};
|
||||
|
||||
u32 wifi_rxgain_table_24g_dcdw_10m[64] = {
|
||||
0x82f282d1,//index 0
|
||||
0x9591a320,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x42f282d1,//index 1
|
||||
0x95923520,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x22f282d1,//index 2
|
||||
0x9592c720,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282d1,//index 3
|
||||
0x9591a320,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x06f282d1,//index 4
|
||||
0x9591a320,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x0ef282d1,//index 5
|
||||
0x9591a320,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x0ef282d3,//index 6
|
||||
0x95923520,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x0ef282d7,//index 7
|
||||
0x9595a320,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282d2,//index 8
|
||||
0x95951120,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282f4,//index 9
|
||||
0x95951120,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282e6,//index 10
|
||||
0x9595a320,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282e6,//index 11
|
||||
0x9599a320,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282e6,//index 12
|
||||
0x959da320,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x02f282e6,//index 13
|
||||
0x959f5920,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x06f282e6,//index 14
|
||||
0x959f5920,
|
||||
0x80808419,
|
||||
0x000000f0,
|
||||
0x0ef282e6,//index 15
|
||||
0x959f5920,
|
||||
0x80808419,
|
||||
0x000000f0
|
||||
};
|
||||
#endif
|
||||
u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = {
|
||||
0x82f282d1,//index 0
|
||||
0x9591a324,
|
||||
@@ -2923,7 +3057,13 @@ int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_c
|
||||
|
||||
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32, 0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256)))
|
||||
return -1;
|
||||
#ifdef CONFIG_5M10M
|
||||
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 0, (u8_l *)wifi_rxgain_table_24g_dcdw_5m, 256)))
|
||||
return -1;
|
||||
|
||||
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 48, 0, (u8_l *)wifi_rxgain_table_24g_dcdw_10m, 256)))
|
||||
return -1;
|
||||
#endif
|
||||
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
|
||||
return -1;
|
||||
}
|
||||
@@ -3038,81 +3178,61 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out)
|
||||
uint32_t misc_ram_addr;
|
||||
uint32_t ram_base_addr, ram_word_cnt;
|
||||
uint32_t bit_mask[4];
|
||||
uint32_t dpd_info_read_addr = 0xfe004;
|
||||
uint32_t boot_argc_read_addr = 0x1220f0;
|
||||
uint32_t flash_size_mem_addr = 0x40038030;
|
||||
uint8_t flash_size = 0;
|
||||
int i;
|
||||
if (valid_out) {
|
||||
*valid_out = 0;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, boot_argc_read_addr, &cfm);
|
||||
if (ret) {
|
||||
AICWFDBG(LOGERROR, "boot argc [0x%x] rd fail: %d\n", boot_argc_read_addr, ret);
|
||||
return ret;
|
||||
if (testmode == FW_RFTEST_MODE) {
|
||||
uint32_t vect1 = 0;
|
||||
uint32_t vect2 = 0;
|
||||
cfg_base = RAM_LMAC_FW_ADDR + 0x0004;
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm);
|
||||
if (ret) {
|
||||
AICWFDBG(LOGERROR, "cfg_base:%x vcet1 rd fail: %d\n", cfg_base, ret);
|
||||
return ret;
|
||||
}
|
||||
vect1 = cfm.memdata;
|
||||
if ((vect1 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) {
|
||||
AICWFDBG(LOGERROR, "vect1 invalid: %x\n", vect1);
|
||||
return ret;
|
||||
}
|
||||
cfg_base = RAM_LMAC_FW_ADDR + 0x0008;
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm);
|
||||
if (ret) {
|
||||
AICWFDBG(LOGERROR, "cfg_base:%x vcet2 rd fail: %d\n", cfg_base, ret);
|
||||
return ret;
|
||||
}
|
||||
vect2 = cfm.memdata;
|
||||
if ((vect2 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) {
|
||||
AICWFDBG(LOGERROR, "vect2 invalid: %x\n", vect2);
|
||||
return ret;
|
||||
}
|
||||
cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
|
||||
}
|
||||
printk("boot argc %x\n", cfm.memdata);
|
||||
if (cfm.memdata & 0x10) {
|
||||
*valid_out = 1;
|
||||
// init misc ram
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm);
|
||||
if (ret) {
|
||||
AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
|
||||
return ret;
|
||||
}
|
||||
if (chip_mcu_id) {
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, flash_size_mem_addr, &cfm);
|
||||
misc_ram_addr = cfm.memdata;
|
||||
AICWFDBG(LOGERROR, "misc_ram_addr=%x\n", misc_ram_addr);
|
||||
// bit_mask
|
||||
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask);
|
||||
ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4;
|
||||
for (i = 0; i < ram_word_cnt; i++) {
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm);
|
||||
if (ret) {
|
||||
AICWFDBG(LOGERROR, "flash size[0x%x] rd fail: %d\n", flash_size_mem_addr, ret);
|
||||
AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret);
|
||||
return ret;
|
||||
}
|
||||
flash_size = cfm.memdata & 0xff;
|
||||
printk("flash size %x\n", flash_size);
|
||||
if (flash_size == 0x16) {
|
||||
dpd_info_read_addr += 0x4300000;
|
||||
} else if (flash_size == 0x15) {
|
||||
dpd_info_read_addr += 0x4100000;
|
||||
} else if (flash_size == 0x18) {
|
||||
dpd_info_read_addr += 0x4700000;
|
||||
} else {
|
||||
dpd_info_read_addr += 0x4100000;
|
||||
}
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, dpd_info_read_addr, &cfm);
|
||||
if (ret) {
|
||||
AICWFDBG(LOGERROR, "dpd info [0x%x] rd fail: %d\n", dpd_info_read_addr, ret);
|
||||
return ret;
|
||||
}
|
||||
if (cfm.memdata & (1<<7)) {
|
||||
if (valid_out) {
|
||||
*valid_out = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (testmode == FW_RFTEST_MODE) {
|
||||
cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
|
||||
}
|
||||
// init misc ram
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm);
|
||||
if (ret) {
|
||||
AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
|
||||
return ret;
|
||||
}
|
||||
misc_ram_addr = cfm.memdata;
|
||||
AICWFDBG(LOGERROR, "misc_ram_addr=%x\n", misc_ram_addr);
|
||||
// bit_mask
|
||||
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask);
|
||||
ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4;
|
||||
for (i = 0; i < ram_word_cnt; i++) {
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm);
|
||||
if (ret) {
|
||||
AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret);
|
||||
return ret;
|
||||
}
|
||||
bit_mask[i] = cfm.memdata;
|
||||
}
|
||||
AICWFDBG(LOGTRACE, "bit_mask:%x,%x,%x,%x\n",bit_mask[0],bit_mask[1],bit_mask[2],bit_mask[3]);
|
||||
if ((bit_mask[0] == 0) && ((bit_mask[1] & 0xFFF00000) == 0x80000000) &&
|
||||
(bit_mask[2] == 0) && ((bit_mask[3] & 0xFFFFFF00) == 0x00000000)) {
|
||||
if (valid_out) {
|
||||
*valid_out = 1;
|
||||
}
|
||||
bit_mask[i] = cfm.memdata;
|
||||
}
|
||||
AICWFDBG(LOGTRACE, "bit_mask:%x,%x,%x,%x\n",bit_mask[0],bit_mask[1],bit_mask[2],bit_mask[3]);
|
||||
if ((bit_mask[0] == 0) && ((bit_mask[1] & 0xFFF00000) == 0x80000000) &&
|
||||
(bit_mask[2] == 0) && ((bit_mask[3] & 0xFFFFFF00) == 0x00000000)) {
|
||||
if (valid_out) {
|
||||
*valid_out = 1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@@ -3511,17 +3631,6 @@ int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){
|
||||
int size;
|
||||
u32 *dst=NULL;
|
||||
char *filename = FW_USERCONFIG_NAME_8800DW;
|
||||
if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA
|
||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS3
|
||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS5
|
||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS6) {
|
||||
filename = FW_USERCONFIG_NAME_8800DW_W311;
|
||||
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U2
|
||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS1
|
||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS2
|
||||
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS4) {
|
||||
filename = FW_USERCONFIG_NAME_8800DW_U2;
|
||||
}
|
||||
|
||||
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
||||
|
||||
@@ -3575,7 +3684,7 @@ int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id
|
||||
/* Copy the file on the Embedded side */
|
||||
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||
|
||||
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code);
|
||||
rwnx_plat_powerlimit_parsing((char *)dst, size);
|
||||
|
||||
rwnx_release_firmware_common(&dst);
|
||||
|
||||
@@ -3630,7 +3739,6 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){
|
||||
array3_tbl_t p_syscfg_msk_tbl;
|
||||
int ret, cnt;
|
||||
const u32 mem_addr = 0x40500000;
|
||||
const u32 cache_mem_addr = 0x40100020;
|
||||
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
|
||||
@@ -3644,21 +3752,6 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){
|
||||
chip_mcu_id = 1;
|
||||
}
|
||||
|
||||
if (chip_mcu_id) {
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cache_mem_addr, &rd_mem_addr_cfm);
|
||||
if (ret) {
|
||||
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
|
||||
return;
|
||||
}
|
||||
rd_mem_addr_cfm.memdata |= 0x01;
|
||||
ret = rwnx_send_dbg_mem_write_req(rwnx_hw, cache_mem_addr, rd_mem_addr_cfm.memdata);
|
||||
|
||||
if (ret) {
|
||||
AICWFDBG(LOGERROR, "%x write fail: %d\n", cache_mem_addr, ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm);
|
||||
if (ret) {
|
||||
AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret);
|
||||
|
||||
@@ -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);
|
||||
#endif
|
||||
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__
|
||||
|
||||
|
||||
@@ -11,6 +9,7 @@
|
||||
#define LOGDEBUG 0x0008
|
||||
#define LOGDATA 0x0010
|
||||
#define LOGSTEER 0x0020
|
||||
#define LOGFW 0x0200
|
||||
|
||||
extern int aicwf_dbg_level;
|
||||
void rwnx_data_dump(char* tag, void* data, unsigned long len);
|
||||
@@ -48,6 +47,3 @@ do { \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ static int freq_to_channel(int freq)
|
||||
} else if (freq >= FREQ_6G_MIN && freq <= FREQ_6G_MAX) {
|
||||
return (freq - 5950) / 5;
|
||||
} else {
|
||||
AICWFDBG(LOGERROR, MANAGER_STR"aic Unsupported frequency: %d MHz\n", freq);
|
||||
AICWFDBG(LOGERROR, MANAGER_STR"Unsupported frequency: %d MHz\n", freq);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@ void aicwf_nl_recv_msg(struct sk_buff *skb)
|
||||
rwnx_hook = nl_hook[band][ssid];
|
||||
|
||||
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;
|
||||
}
|
||||
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];
|
||||
|
||||
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;
|
||||
}
|
||||
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];
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
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);}
|
||||
#endif
|
||||
sdio_dbg("%s\n",__func__);
|
||||
if (sdiodev->pwrctl_tsk) {
|
||||
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)
|
||||
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data;
|
||||
#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);
|
||||
#endif
|
||||
|
||||
@@ -1085,11 +1082,7 @@ void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration)
|
||||
spin_lock_bh(&sdiodev->pwrctl_lock);
|
||||
if (!duration) {
|
||||
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);
|
||||
#endif
|
||||
} else {
|
||||
sdiodev->active_duration = duration;
|
||||
timeout = msecs_to_jiffies(sdiodev->active_duration);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <linux/moduleparam.h>
|
||||
#include <net/tcp.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
|
||||
#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 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
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define DATA_BUF_MAX 2048
|
||||
#define TXPKT_BLOCKSIZE 512
|
||||
#define MAX_AGGR_TXPKT_LEN (1536*64)
|
||||
#define CMD_TX_TIMEOUT 2000
|
||||
#define CMD_TX_TIMEOUT 5000
|
||||
#define TX_ALIGNMENT 4
|
||||
|
||||
#ifdef CONFIG_USB_TX_AGGR
|
||||
@@ -155,7 +155,7 @@ struct aicwf_tx_priv {
|
||||
#define DEFRAG_MAX_WAIT 40 //100
|
||||
#ifdef AICWF_RX_REORDER
|
||||
#define MAX_REORD_RXFRAME 250
|
||||
#define REORDER_UPDATE_TIME 500//50
|
||||
#define REORDER_UPDATE_TIME 50
|
||||
#define AICWF_REORDER_WINSIZE 64
|
||||
//SN_LESS(a, b) a-b<0 is ture
|
||||
#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);
|
||||
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);
|
||||
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;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -155,22 +155,24 @@ static void aicwf_usb_msg_rx_buf_put(struct aic_usb_dev *usb_dev, struct aicwf_u
|
||||
}
|
||||
#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;
|
||||
struct rwnx_txq *txq;
|
||||
struct rwnx_sta *sta_tmp = (struct rwnx_sta *)sta;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
struct rwnx_txq *txq;
|
||||
struct rwnx_sta *sta_tmp = (struct rwnx_sta *)sta;
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
//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)
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -295,18 +297,6 @@ static void aicwf_usb_rx_complete(struct urb *urb)
|
||||
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
||||
if(urb->status < 0){
|
||||
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;
|
||||
}else{
|
||||
//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);
|
||||
if(urb->status < 0){
|
||||
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;
|
||||
}else{
|
||||
//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_usb_rx_buf_put(usb_dev, usb_buf);
|
||||
|
||||
msleep(100);
|
||||
mdelay(100);
|
||||
return -1;
|
||||
}else{
|
||||
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;
|
||||
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
||||
|
||||
msleep(100);
|
||||
mdelay(100);
|
||||
return -1;
|
||||
}else{
|
||||
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;
|
||||
aicwf_usb_msg_rx_buf_put(usb_dev, usb_buf);
|
||||
|
||||
msleep(100);
|
||||
mdelay(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1214,9 +1192,6 @@ fail:
|
||||
usb_buf->skb = NULL;
|
||||
aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf,
|
||||
&usb_dev->tx_free_count, &usb_dev->tx_free_lock);
|
||||
if (ret == -ENODEV) {
|
||||
break;
|
||||
}
|
||||
#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) {
|
||||
//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)
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1903,15 +1878,14 @@ static int aicwf_usb_bus_start(struct device *dev)
|
||||
aicwf_usb_state_change(usb_dev, USB_UP_ST);
|
||||
|
||||
usb_dev->rx_prepare_ready = false;
|
||||
aicwf_usb_rx_prepare(usb_dev);
|
||||
aicwf_usb_tx_prepare(usb_dev);
|
||||
#ifdef CONFIG_USB_MSG_IN_EP
|
||||
if(usb_dev->msg_in_pipe){
|
||||
aicwf_usb_msg_rx_prepare(usb_dev);
|
||||
} else {
|
||||
aicwf_usb_rx_prepare(usb_dev);
|
||||
}
|
||||
#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__);
|
||||
return -1;
|
||||
}else{
|
||||
@@ -1981,10 +1955,6 @@ static void aicwf_usb_bus_stop(struct device *dev)
|
||||
if (usb_dev->state == USB_DOWN_ST)
|
||||
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_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");
|
||||
usb_dev->chipid = PRODUCT_ID_AIC8800DW;
|
||||
}else if (usb_dev->chipid == PRODUCT_ID_AIC8800DW) {
|
||||
AICWFDBG(LOGINFO, "AIC8800DW\n");}
|
||||
else if (usb_dev->chipid == PRODUCT_ID_AIC8800D81) {
|
||||
AICWFDBG(LOGINFO, "AIC8800D80\n");
|
||||
} else if(usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 ||
|
||||
usb_dev->chipid == PRODUCT_ID_AIC8800D89X2 ||
|
||||
usb_dev->chipid == PRODUCT_ID_AIC8800D81){
|
||||
AICWFDBG(LOGINFO, "AIC8800DW\n");
|
||||
} else if (usb_dev->chipid == PRODUCT_ID_AIC8800D80N) {
|
||||
AICWFDBG(LOGERROR, "AIC8800D80N change to AIC8800D80WN\n");
|
||||
} else if (usb_dev->chipid == PRODUCT_ID_AIC8800DLN) {
|
||||
AICWFDBG(LOGERROR, "AIC8800DLN change to AIC8800DWN\n");
|
||||
}else if(usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 ||
|
||||
usb_dev->chipid == PRODUCT_ID_AIC8800D89X2){
|
||||
//TODO
|
||||
}else{
|
||||
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;
|
||||
AICWFDBG(LOGINFO, "%s USE AIC8801\r\n", __func__);
|
||||
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_AIC8800FC_CUS2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS3
|
||||
|| 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;
|
||||
}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_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_CUS5 || pid == USB_PRODUCT_ID_AIC8800M80_CUS6
|
||||
|| 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;
|
||||
aicwf_usb_rx_aggr = true;
|
||||
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__);
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -2457,9 +2447,6 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i
|
||||
usb_dev->dev = &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);
|
||||
|
||||
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);
|
||||
goto out_free_bus;
|
||||
}
|
||||
if(usb_dev->msg_in_pipe){
|
||||
aicwf_usb_rx_prepare(usb_dev);
|
||||
}
|
||||
aicwf_hostif_ready();
|
||||
|
||||
#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__);
|
||||
#ifdef CONFIG_WOWLAN
|
||||
#ifndef ANDROID_PLATFORM
|
||||
rwnx_send_dummy_reboot(usb_dev->rwnx_hw);
|
||||
#endif
|
||||
#endif
|
||||
list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) {
|
||||
if (rwnx_vif->ndev){
|
||||
@@ -2633,7 +2619,8 @@ static int aicwf_usb_resume(struct usb_interface *intf)
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -2641,10 +2628,7 @@ static int aicwf_usb_resume(struct usb_interface *intf)
|
||||
netif_tx_wake_all_queues(rwnx_vif->ndev);
|
||||
}
|
||||
}
|
||||
if(usb_dev->msg_in_pipe){
|
||||
aicwf_usb_rx_prepare(usb_dev);
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aicwf_usb_reset_resume(struct usb_interface *intf)
|
||||
@@ -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_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_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(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DW)},
|
||||
{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(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_U2)},
|
||||
{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_CUS5)},
|
||||
{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_CUS2)},
|
||||
{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_CUS8)},
|
||||
{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
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -16,11 +16,17 @@
|
||||
|
||||
/* USB Device ID */
|
||||
#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_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
|
||||
#define USB_PRODUCT_ID_AIC8800 0x8800
|
||||
#define USB_PRODUCT_ID_AIC8801 0x8801
|
||||
@@ -32,15 +38,22 @@
|
||||
#else
|
||||
#define USB_PRODUCT_ID_AIC8801 0x8801
|
||||
#define USB_PRODUCT_ID_AIC8800DC 0x88dc
|
||||
#define USB_PRODUCT_ID_AIC8800DE 0x88de
|
||||
#define USB_PRODUCT_ID_AIC8800DW 0x88dd
|
||||
#define USB_PRODUCT_ID_AIC8800D81 0x8d81
|
||||
#define USB_PRODUCT_ID_AIC8800D41 0x8d41
|
||||
#define USB_PRODUCT_ID_AIC8800D81X2 0x8d91
|
||||
#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_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_AIC8800FC_CUS1 0x88df
|
||||
#define USB_PRODUCT_ID_AIC8800FC_CUS2 0x88E0
|
||||
@@ -49,6 +62,7 @@
|
||||
#define USB_PRODUCT_ID_AIC8800FC_CUS5 0x88E3
|
||||
#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_CUS2 0x8D85
|
||||
#define USB_PRODUCT_ID_AIC8800M80_CUS3 0x8D86
|
||||
@@ -64,6 +78,8 @@ enum AICWF_IC{
|
||||
PRODUCT_ID_AIC8801 = 0,
|
||||
PRODUCT_ID_AIC8800DC,
|
||||
PRODUCT_ID_AIC8800DW,
|
||||
PRODUCT_ID_AIC8800DLN,
|
||||
PRODUCT_ID_AIC8800D80N,
|
||||
PRODUCT_ID_AIC8800D81,
|
||||
PRODUCT_ID_AIC8800D81X2,
|
||||
PRODUCT_ID_AIC8800D89X2
|
||||
@@ -78,7 +94,7 @@ enum AICWF_IC{
|
||||
#define TXQLEN (2048*4)
|
||||
#define AICWF_USB_TX_URBS (50)
|
||||
#else
|
||||
#define AICWF_USB_TX_URBS 50//(100)
|
||||
#define AICWF_USB_TX_URBS 200//(100)
|
||||
#endif
|
||||
#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%
|
||||
@@ -202,8 +218,6 @@ struct aic_usb_dev {
|
||||
#endif
|
||||
u16 chipid;
|
||||
bool tbusy;
|
||||
u16_l vid;
|
||||
u16_l pid;
|
||||
};
|
||||
|
||||
extern void aicwf_usb_exit(void);
|
||||
@@ -214,7 +228,9 @@ int usb_msg_busrx_thread(void *data);
|
||||
#endif
|
||||
int usb_bustx_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);
|
||||
|
||||
|
||||
@@ -400,7 +400,7 @@ static char *aicwf_get_iwe_stream_mac_addr(struct rwnx_hw* rwnx_hw,
|
||||
iwe->cmd = SIOCGIWAP;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -616,8 +616,10 @@ static inline char *aicwf_get_iwe_stream_rate(struct rwnx_hw* rwnx_hw,
|
||||
u16 vht_data_rate = 0;
|
||||
|
||||
u16 he_cap = false;
|
||||
u8 he_ch_width_set = 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 */
|
||||
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_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_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
|
||||
MM_MAX,
|
||||
};
|
||||
@@ -892,6 +899,7 @@ struct mm_ba_add_cfm
|
||||
u8_l tid;
|
||||
/// Status of ba establishment
|
||||
u8_l status;
|
||||
u8_l alligned;
|
||||
};
|
||||
|
||||
/// 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;
|
||||
};
|
||||
|
||||
struct mm_get_sta_info_compat_req
|
||||
{
|
||||
u8_l sta_idx;
|
||||
char pattern[3];
|
||||
};
|
||||
|
||||
struct mm_get_sta_info_cfm
|
||||
{
|
||||
u32_l rate_info;
|
||||
@@ -1412,6 +1426,12 @@ typedef struct
|
||||
s8_l pwrlvl_adj_tbl_5g[6];
|
||||
} 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
|
||||
{
|
||||
union {
|
||||
@@ -1424,7 +1444,10 @@ struct mm_set_txpwr_lvl_req
|
||||
|
||||
struct mm_set_txpwr_lvl_adj_req
|
||||
{
|
||||
union {
|
||||
txpwr_lvl_adj_conf_t txpwr_lvl_adj;
|
||||
txpwr_lvl_adj_conf_v2_t txpwr_lvl_adj_v2;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct
|
||||
@@ -1538,12 +1561,33 @@ typedef struct
|
||||
s8_l pwrofst2x_tbl_6g_ant1[15];
|
||||
} 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
|
||||
{
|
||||
union {
|
||||
txpwr_ofst_conf_t txpwr_ofst;
|
||||
txpwr_ofst2x_conf_t txpwr_ofst2x;
|
||||
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;
|
||||
};
|
||||
|
||||
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.
|
||||
/// Size allocated for the structure depends of the number of group
|
||||
struct mm_mu_group_update_req
|
||||
@@ -2038,6 +2094,7 @@ struct me_sta_add_cfm
|
||||
u8_l status;
|
||||
/// PM state of the station
|
||||
u8_l pm_state;
|
||||
u8_l alligned;
|
||||
};
|
||||
|
||||
/// 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;
|
||||
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_
|
||||
|
||||
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
|
||||
if(cmd->e2a_msg != NULL) {
|
||||
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);
|
||||
if(!empty) {
|
||||
spin_unlock_bh(&cmd_mgr->lock);
|
||||
@@ -155,16 +159,14 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
||||
}
|
||||
} while(!empty);//wait for cmd queue empty
|
||||
} else {
|
||||
spin_lock_bh(&cmd_mgr->lock);
|
||||
}
|
||||
|
||||
|
||||
if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
|
||||
printk(KERN_CRIT"cmd queue crashed\n");
|
||||
cmd->result = -EPIPE;
|
||||
spin_unlock_bh(&cmd_mgr->lock);
|
||||
return -EPIPE;
|
||||
}
|
||||
spin_lock_bh(&cmd_mgr->lock);
|
||||
if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
|
||||
printk(KERN_CRIT"cmd queue crashed\n");
|
||||
cmd->result = -EPIPE;
|
||||
spin_unlock_bh(&cmd_mgr->lock);
|
||||
return -EPIPE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_RWNX_FHOST
|
||||
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);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&cmd_mgr->lock);
|
||||
//spin_unlock_bh(&cmd_mgr->lock);
|
||||
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);
|
||||
|
||||
#ifdef AICWF_SDIO_SUPPORT
|
||||
@@ -234,9 +237,12 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
||||
|
||||
kfree(cmd->a2e_msg);
|
||||
} else {
|
||||
if(cmd_mgr->queue_sz <= 1){
|
||||
WAKE_CMD_WORK(cmd_mgr);
|
||||
}
|
||||
if(cmd_mgr->queue_sz <= 1) {
|
||||
spin_unlock_bh(&cmd_mgr->lock);
|
||||
WAKE_CMD_WORK(cmd_mgr);
|
||||
} else {
|
||||
spin_unlock_bh(&cmd_mgr->lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -559,7 +565,6 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len)
|
||||
{
|
||||
u8 *buffer = NULL;
|
||||
u16 index = 0;
|
||||
int ret = 0;
|
||||
#ifdef AICWF_SDIO_SUPPORT
|
||||
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev;
|
||||
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;
|
||||
memcpy(&buffer[index], (u8 *)msg->param, msg->param_len);
|
||||
|
||||
ret = aicwf_bus_txmsg(bus, buffer, len + 8);
|
||||
if (ret == -EIO) {
|
||||
ret = aicwf_bus_txmsg(bus, buffer, len + 8);
|
||||
}
|
||||
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);
|
||||
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 cmd_mgr_task_process(struct work_struct *work);
|
||||
|
||||
#endif /* _RWNX_CMDS_H_ */
|
||||
|
||||
@@ -23,6 +23,33 @@
|
||||
#define _RWNX_COMPAT_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)
|
||||
#error "Minimum kernel version supported is 3.10"
|
||||
#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
|
||||
#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
|
||||
#endif
|
||||
|
||||
@@ -380,6 +407,7 @@ enum {
|
||||
rwnx_ops_hw_scan(hw, vif, struct cfg80211_scan_request *req)
|
||||
#endif
|
||||
|
||||
u16 rwnx_select_txq(struct rwnx_vif *rwnx_vif, struct sk_buff *skb);
|
||||
/* NET */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
|
||||
#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,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct rwnx_hw *priv = file->private_data;
|
||||
//struct rwnx_hw *priv = file->private_data;
|
||||
char buf[32];
|
||||
int ret;
|
||||
ssize_t read;
|
||||
@@ -1796,7 +1796,7 @@ static ssize_t rwnx_dbgfs_dbg_level_write(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct rwnx_hw *priv = file->private_data;
|
||||
//struct rwnx_hw *priv = file->private_data;
|
||||
char buf[32];
|
||||
int val;
|
||||
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:
|
||||
{
|
||||
r_cfg->formatModTx = formatmod;
|
||||
r_cfg->giAndPreTypeTx = 1;
|
||||
r_cfg->giAndPreTypeTx = 2;
|
||||
r_cfg->mcsIndexTx = mcs;
|
||||
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 */
|
||||
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]);
|
||||
if (&mac[0] == NULL)
|
||||
return 0;
|
||||
|
||||
sta = rwnx_get_sta(priv, mac);
|
||||
if (sta == NULL)
|
||||
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) {}
|
||||
#endif
|
||||
#endif /* CONFIG_RWNX_DEBUGFS */
|
||||
void _rwnx_dbgfs_rc_stat_write(struct rwnx_debugfs *rwnx_debugfs, uint8_t sta_idx);
|
||||
|
||||
|
||||
#endif /* _RWNX_DEBUGFS_H_ */
|
||||
|
||||
@@ -79,20 +79,11 @@
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
|
||||
#ifndef IEEE80211_MAX_AMPDU_BUF
|
||||
#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
|
||||
#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
|
||||
#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
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef IEEE80211_MAX_AMPDU_BUF
|
||||
#define IEEE80211_MAX_AMPDU_BUF 0x100
|
||||
@@ -107,6 +98,7 @@
|
||||
#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40
|
||||
#endif
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL)
|
||||
enum nl80211_ac {
|
||||
NL80211_AC_VO,
|
||||
@@ -237,6 +229,7 @@ struct tmp_feature_sta {
|
||||
u8_l supported_band;
|
||||
};
|
||||
|
||||
#if 0
|
||||
#define MAX_PENDING_PROBES 3
|
||||
struct ap_probe_rsp {
|
||||
u8_l da[6];
|
||||
@@ -244,6 +237,7 @@ struct ap_probe_rsp {
|
||||
bool in_use;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
|
||||
#define NL80211_MESHCONF_POWER_MODE 26
|
||||
@@ -341,6 +335,12 @@ struct apm_probe_sta {
|
||||
u8 sta_mac_addr[6];
|
||||
u8 vif_idx;
|
||||
u64 probe_id;
|
||||
/*
|
||||
* 7.3+ only: the cookie cfg80211_ops::probe_peer() was called with,
|
||||
* echoed back via cfg80211_probe_status() once the probe completes.
|
||||
* See rwnx_cfg80211_probe_client().
|
||||
*/
|
||||
u64 cookie;
|
||||
struct work_struct apmprobestaWork;
|
||||
struct workqueue_struct *apmprobesta_wq;
|
||||
};
|
||||
@@ -388,6 +388,18 @@ enum rwnx_ap_flags {
|
||||
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.
|
||||
* This is also linked within the rwnx_hw vifs list.
|
||||
@@ -402,6 +414,7 @@ struct rwnx_vif {
|
||||
struct rwnx_key key[6];
|
||||
unsigned long drv_flags;
|
||||
atomic_t drv_conn_state;
|
||||
spinlock_t conn_state_lock;
|
||||
u8 drv_vif_index; /* Identifier of the VIF in driver */
|
||||
u8 vif_index; /* Identifier of the station in FW */
|
||||
u8 ch_index; /* Channel context identifier */
|
||||
@@ -458,6 +471,7 @@ struct rwnx_vif {
|
||||
u32_l freq;
|
||||
bool start;
|
||||
#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 next_mesh_pm; /* mesh power save mode for next peer */
|
||||
} ap;
|
||||
@@ -487,12 +501,14 @@ struct rwnx_vif {
|
||||
struct br_ext_info ethBrExtInfo;
|
||||
#endif /* CONFIG_BR_SUPPORT */
|
||||
#ifdef CONFIG_BAND_STEERING
|
||||
struct workqueue_struct *rsp_wq;
|
||||
struct timer_list steer_timer;
|
||||
struct work_struct steer_work;
|
||||
struct b_steer_priv bsteerpriv;
|
||||
#if 0
|
||||
struct workqueue_struct *rsp_wq;
|
||||
struct ap_probe_rsp pb_pool[MAX_PENDING_PROBES];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
@@ -665,6 +681,16 @@ struct rwnx_roc_elem {
|
||||
bool mgmt_roc;
|
||||
/* Indicate if we have switch on the RoC channel */
|
||||
bool on_chan;
|
||||
/*
|
||||
* The cookie reported to cfg80211 for this RoC, via
|
||||
* cfg80211_ready_on_channel() / cfg80211_remain_on_channel_expired().
|
||||
* On 7.3+, for a RoC started directly by cfg80211_ops::remain_on_channel(),
|
||||
* this is the cookie cfg80211 pre-assigned; on every older kernel, and
|
||||
* always for the purely-internal RoC started from inside mgmt_tx, it is
|
||||
* rwnx_hw->roc_cookie_cnt at RoC-start time. See
|
||||
* rwnx_cfg80211_remain_on_channel_().
|
||||
*/
|
||||
u64 cookie;
|
||||
};
|
||||
|
||||
/* Structure containing channel survey information received from MAC */
|
||||
@@ -724,7 +750,7 @@ struct amsdu_subframe_hdr {
|
||||
};
|
||||
|
||||
/* 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 {
|
||||
RWNX_DRV_STATUS_DISCONNECTED = 0,
|
||||
@@ -885,6 +911,7 @@ struct rwnx_hw {
|
||||
char wext_essid[33];
|
||||
int support_freqs[SCAN_CHANNEL_MAX];
|
||||
int support_freqs_number;
|
||||
#endif
|
||||
#ifdef CONFIG_DYNAMIC_PWR
|
||||
struct timer_list pwrloss_timer;
|
||||
struct work_struct pwrloss_work;
|
||||
@@ -892,11 +919,22 @@ struct rwnx_hw {
|
||||
s8 pwrloss_lvl;
|
||||
u8 sta_rssi_idx;
|
||||
#endif
|
||||
#ifdef CONFIG_TEMP_CONTROL
|
||||
struct timer_list tc_timer;
|
||||
struct work_struct tc_work;
|
||||
s8 tc_range;
|
||||
#endif
|
||||
#ifdef CONFIG_BAND_STEERING
|
||||
u8_l iface_idx;
|
||||
struct tmp_feature_sta feature_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX];
|
||||
#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);
|
||||
|
||||
@@ -16,5 +16,7 @@
|
||||
|
||||
int rwnx_dini_platform_init(struct pci_dev *pci_dev,
|
||||
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_ */
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "rwnx_defs.h"
|
||||
#include "ipc_host.h"
|
||||
#include "rwnx_prof.h"
|
||||
|
||||
#include "rwnx_irqs.h"
|
||||
/**
|
||||
* 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_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_vif *rwnx_vif, u8 *addr,
|
||||
@@ -53,13 +68,61 @@ void aicwf_steering_timeout(struct timer_list *t);
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_PWR
|
||||
|
||||
void set_txpwrloss_ctrl(struct rwnx_hw *rwnx_hw, s8 value);
|
||||
#ifdef CONFIG_DYNAMIC_PWR
|
||||
void aicwf_pwrloss_worker(struct work_struct *work);
|
||||
#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
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u64 cookie);
|
||||
#else
|
||||
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u64 *cookie);
|
||||
#endif
|
||||
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_ */
|
||||
|
||||
@@ -55,6 +55,7 @@ struct rwnx_mod_params rwnx_mod_params = {
|
||||
COMMON_PARAM(mutx, true, true)
|
||||
COMMON_PARAM(mutx_on, 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(custchan, false, false)
|
||||
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 &&
|
||||
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 &&
|
||||
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;
|
||||
} 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 &&
|
||||
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 &&
|
||||
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 = false;
|
||||
} else {
|
||||
@@ -1836,28 +1840,33 @@ void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
|
||||
// registration (in rwnx_set_wiphy_params()), so nothing has to be done here
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
|
||||
wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
|
||||
wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
|
||||
wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
|
||||
#endif
|
||||
if (!rwnx_hw->mod_params->custregd)
|
||||
return;
|
||||
|
||||
if (!rwnx_hw->mod_params->custregd)
|
||||
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 (regulatory_set_wiphy_regd_sync(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){
|
||||
wiphy_err(wiphy, "Failed to set custom regdomain\n");
|
||||
}
|
||||
if (regulatory_set_wiphy_regd_sync(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){
|
||||
wiphy_err(wiphy, "Failed to set custom regdomain\n");
|
||||
}
|
||||
#else
|
||||
if (regulatory_set_wiphy_regd_sync_rtnl(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){
|
||||
wiphy_err(wiphy, "Failed to set custom regdomain\n");
|
||||
}
|
||||
if (regulatory_set_wiphy_regd_sync_rtnl(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){
|
||||
wiphy_err(wiphy, "Failed to set custom regdomain\n");
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
wiphy_err(wiphy,"\n"
|
||||
"*******************************************************\n"
|
||||
"** CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES **\n"
|
||||
"*******************************************************\n");
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
||||
else{
|
||||
wiphy_err(wiphy,"\n"
|
||||
"*******************************************************\n"
|
||||
"** CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES **\n"
|
||||
"*******************************************************\n");
|
||||
}
|
||||
rtnl_unlock();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,8 @@ struct ieee80211_regdomain *getRegdomainFromRwnxDB(struct wiphy *wiphy,
|
||||
|
||||
struct ieee80211_regdomain *getRegdomainFromRwnxDBIndex(struct wiphy *wiphy,
|
||||
int index);
|
||||
void rwnx_get_countrycode_channels(struct wiphy *wiphy,
|
||||
struct ieee80211_regdomain *regdomain);
|
||||
|
||||
|
||||
#endif /* _RWNX_MOD_PARAM_H_ */
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#ifdef CONFIG_USE_WIRELESS_EXT
|
||||
#include "aicwf_wext_linux.h"
|
||||
#endif
|
||||
#include "rwnx_msg_rx.h"
|
||||
|
||||
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)
|
||||
@@ -121,13 +123,13 @@ static inline int rwnx_rx_chan_switch_ind(struct rwnx_hw *rwnx_hw,
|
||||
if (!roc_elem->mgmt_roc) {
|
||||
/* Inform the host that we have switch on the indicated off-channel */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
|
||||
cfg80211_ready_on_channel(roc_elem->wdev->netdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_ready_on_channel(roc_elem->wdev->netdev, roc_elem->cookie,
|
||||
roc_elem->chan, NL80211_CHAN_HT20, roc_elem->duration, GFP_ATOMIC);
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||
cfg80211_ready_on_channel(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_ready_on_channel(roc_elem->wdev, roc_elem->cookie,
|
||||
roc_elem->chan, NL80211_CHAN_HT20, roc_elem->duration, GFP_ATOMIC);
|
||||
#else
|
||||
cfg80211_ready_on_channel(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_ready_on_channel(roc_elem->wdev, roc_elem->cookie,
|
||||
roc_elem->chan, roc_elem->duration, GFP_ATOMIC);
|
||||
#endif
|
||||
}
|
||||
@@ -243,13 +245,13 @@ static inline int rwnx_rx_remain_on_channel_exp_ind(struct rwnx_hw *rwnx_hw,
|
||||
/* Inform the host that off-channel period has expired */
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev->netdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev->netdev, roc_elem->cookie,
|
||||
roc_elem->chan, NL80211_CHAN_HT20, GFP_ATOMIC);
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev, roc_elem->cookie,
|
||||
roc_elem->chan, NL80211_CHAN_HT20, GFP_ATOMIC);
|
||||
#else
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev, roc_elem->cookie,
|
||||
roc_elem->chan, GFP_ATOMIC);
|
||||
#endif
|
||||
}
|
||||
@@ -789,13 +791,21 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USE_WIRELESS_EXT
|
||||
if(rwnx_hw->wext_scan){
|
||||
list_for_each_entry(scan_re_wext, &rwnx_hw->wext_scanre_list, scanu_re_list) {
|
||||
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__);
|
||||
goto putbss;
|
||||
}
|
||||
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) {
|
||||
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)) {
|
||||
AICWFDBG(LOGDEBUG, "%s: BSSID already exists, no need to add again\r\n", __func__);
|
||||
goto putbss;
|
||||
}
|
||||
}
|
||||
scan_re_wext = (struct scanu_result_wext *)vmalloc(sizeof(struct scanu_result_wext));
|
||||
scan_re_wext->ind = (struct scanu_result_ind *)vmalloc(sizeof(struct scanu_result_ind));
|
||||
scan_re_wext->payload = (u32_l *)vmalloc(sizeof(u32_l) * ind->length);
|
||||
@@ -811,11 +821,13 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw,
|
||||
INIT_LIST_HEAD(&scan_re_wext->scanu_re_list);
|
||||
list_add_tail(&scan_re_wext->scanu_re_list, &rwnx_hw->wext_scanre_list);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
#ifdef CONFIG_USE_WIRELESS_EXT
|
||||
putbss:
|
||||
#endif
|
||||
if (bss != NULL)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
|
||||
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;
|
||||
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{
|
||||
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,
|
||||
GFP_ATOMIC);
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
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){
|
||||
AICWFDBG(LOGINFO, "%s roaming fail to notify disconnect \r\n", __func__);
|
||||
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);
|
||||
}else{
|
||||
#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
|
||||
, GFP_ATOMIC);
|
||||
#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;
|
||||
}
|
||||
@@ -1263,7 +1279,7 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
|
||||
|
||||
//msleep(200);
|
||||
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;
|
||||
@@ -1577,6 +1593,68 @@ static inline int rwnx_rx_dbg_error_ind(struct rwnx_hw *rwnx_hw,
|
||||
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
|
||||
|
||||
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_APM_STALOSS_IND)] = rwnx_apm_staloss_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)] = {
|
||||
@@ -1669,12 +1749,14 @@ void rwnx_rx_handle_print(struct rwnx_hw *rwnx_hw, u8 *msg, u32 len)
|
||||
u8 *data_end = NULL;
|
||||
(void)data_end;
|
||||
|
||||
msg[len-1] = '\0';
|
||||
|
||||
if (!rwnx_hw || !rwnx_hw->fwlog_en) {
|
||||
pr_err("FWLOG-OVFL: %s", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("FWLOG: %s", msg);
|
||||
AICWFDBG(LOGFW, "%s", msg);
|
||||
|
||||
#ifdef CONFIG_RWNX_DEBUGFS
|
||||
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);
|
||||
cmd->used = 0;
|
||||
cmd->flags = 0;
|
||||
AICWFDBG(LOGTRACE, "%s cmd_array[%d]:%p \r\n", __func__, cmd->array_id, cmd);
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#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){
|
||||
rf_calib_req->cal_cfg_24g = 0x0f8f;
|
||||
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;
|
||||
@@ -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){
|
||||
rf_calib_req->cal_cfg_24g = 0x0f8f;
|
||||
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;
|
||||
@@ -1494,21 +1529,36 @@ 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)
|
||||
{
|
||||
struct mm_get_sta_info_req *get_info_req;
|
||||
struct mm_get_sta_info_compat_req *get_info_compat_req;
|
||||
int error;
|
||||
|
||||
/* Build the MM_GET_STA_INFO_REQ message */
|
||||
get_info_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID,
|
||||
sizeof(struct mm_get_sta_info_req));
|
||||
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;
|
||||
}
|
||||
|
||||
if (!get_info_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 */
|
||||
get_info_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID,
|
||||
sizeof(struct mm_get_sta_info_req));
|
||||
|
||||
if (!get_info_req) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
get_info_req->sta_idx = sta_idx;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
get_info_req->sta_idx = sta_idx;
|
||||
|
||||
/* 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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CUSTOMIZED_FREQ_REQ:
|
||||
/* 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));
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
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.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
|
||||
@@ -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);
|
||||
|
||||
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 ||
|
||||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
|
||||
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){
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
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);
|
||||
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++;
|
||||
else
|
||||
rwnx_vif->ap.aic_index = 0;
|
||||
@@ -3406,10 +3546,15 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par
|
||||
req->flags |= STA_MFP_CAPA;
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
||||
if (link_sta_params->opmode_notif_used) {
|
||||
req->opmode = link_sta_params->opmode_notif_used;
|
||||
req->flags |= STA_OPMOD_NOTIF;
|
||||
}
|
||||
#if LINUX_VERSION_CODE < HIGH_KERNEL_VERSION
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
req->aid = cpu_to_le16(params->aid);
|
||||
@@ -4704,7 +4849,13 @@ int rwnx_send_dbg_trigger_req(struct rwnx_hw *rwnx_hw, char *msg)
|
||||
return -ENOMEM;
|
||||
|
||||
/* 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 */
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
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);
|
||||
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
|
||||
#ifdef CONFIG_WOWLAN
|
||||
#ifndef ANDROID_PLATFORM
|
||||
int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -5124,3 +5262,4 @@ int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw)
|
||||
return ret;
|
||||
}
|
||||
#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);
|
||||
#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_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_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_ofst2x_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_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_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_v2_req(struct rwnx_hw *rwnx_hw);
|
||||
#ifdef CONFIG_WOWLAN
|
||||
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);
|
||||
@@ -196,15 +199,14 @@ int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw);
|
||||
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||
int rwnx_send_txpwr_per_sta_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta);
|
||||
#endif
|
||||
|
||||
int rwnx_send_get_temp_req(struct rwnx_hw *rwnx_hw, s8_l *temp);
|
||||
|
||||
//#ifdef CONFIG_USB_BT
|
||||
int rwnx_send_reboot(struct rwnx_hw *rwnx_hw);
|
||||
//#endif // CONFIG_USB_BT
|
||||
|
||||
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);
|
||||
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_set_pwm_tbl(struct rwnx_hw *rwnx_hw);
|
||||
struct rwnx_cmd *rwnx_cmd_malloc(void);
|
||||
void rwnx_cmd_free(struct rwnx_cmd *cmd);
|
||||
int rwnx_init_cmd_array(void);
|
||||
void rwnx_free_cmd_array(void);
|
||||
|
||||
#endif /* _RWNX_MSG_TX_H_ */
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "rwnx_defs.h"
|
||||
#include "rwnx_dini.h"
|
||||
#include "rwnx_v7.h"
|
||||
#include "rwnx_pci.h"
|
||||
|
||||
#define PCI_VENDOR_ID_DINIGROUP 0x17DF
|
||||
#define PCI_DEVICE_ID_DINIGROUP_DNV6_F2PCIE 0x1907
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "aicwf_compat_8800dc.h"
|
||||
#include "aicwf_compat_8800d80.h"
|
||||
#include "aicwf_compat_8800d80x2.h"
|
||||
#include "aicwf_compat_8800d80n.h"
|
||||
#include "aicwf_compat_8800dln.h"
|
||||
#ifdef CONFIG_USE_FW_REQUEST
|
||||
#include <linux/firmware.h>
|
||||
#endif
|
||||
@@ -190,6 +192,15 @@ userconfig_info_t userconfig_info = {
|
||||
.pwrofst2x_tbl_6g_ant0 = { 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 = {
|
||||
.enable = 0,
|
||||
.xtal_cap = 24,
|
||||
@@ -248,6 +259,7 @@ reg_table reg_tables[] = {
|
||||
{.ccode = "CL", .region = REGIONS_ETSI},
|
||||
{.ccode = "CO", .region = REGIONS_FCC},
|
||||
{.ccode = "CR", .region = REGIONS_FCC},
|
||||
{.ccode = "CU", .region = REGIONS_FCC},
|
||||
{.ccode = "CX", .region = REGIONS_FCC},
|
||||
{.ccode = "CY", .region = REGIONS_ETSI},
|
||||
{.ccode = "CZ", .region = REGIONS_ETSI},
|
||||
@@ -272,7 +284,7 @@ reg_table reg_tables[] = {
|
||||
{.ccode = "GL", .region = REGIONS_ETSI},
|
||||
{.ccode = "GP", .region = REGIONS_ETSI},
|
||||
{.ccode = "GR", .region = REGIONS_ETSI},
|
||||
{.ccode = "GT", .region = REGIONS_FCC},
|
||||
{.ccode = "GT", .region = REGIONS_DEFAULT},
|
||||
{.ccode = "GU", .region = REGIONS_FCC},
|
||||
{.ccode = "GY", .region = REGIONS_DEFAULT},
|
||||
{.ccode = "HK", .region = REGIONS_ETSI},
|
||||
@@ -285,7 +297,7 @@ reg_table reg_tables[] = {
|
||||
{.ccode = "IL", .region = REGIONS_ETSI},
|
||||
{.ccode = "IN", .region = REGIONS_ETSI},
|
||||
{.ccode = "IQ", .region = REGIONS_ETSI},
|
||||
{.ccode = "IR", .region = REGIONS_JP},
|
||||
{.ccode = "IR", .region = REGIONS_ETSI},
|
||||
{.ccode = "IS", .region = REGIONS_ETSI},
|
||||
{.ccode = "IT", .region = REGIONS_ETSI},
|
||||
{.ccode = "JM", .region = REGIONS_FCC},
|
||||
@@ -295,7 +307,7 @@ reg_table reg_tables[] = {
|
||||
{.ccode = "KH", .region = REGIONS_ETSI},
|
||||
{.ccode = "KN", .region = REGIONS_ETSI},
|
||||
{.ccode = "KP", .region = REGIONS_JP},
|
||||
{.ccode = "KR", .region = REGIONS_ETSI},
|
||||
{.ccode = "KR", .region = REGIONS_KCC},
|
||||
{.ccode = "KW", .region = REGIONS_ETSI},
|
||||
{.ccode = "KY", .region = REGIONS_FCC},
|
||||
{.ccode = "KZ", .region = REGIONS_DEFAULT},
|
||||
@@ -339,7 +351,7 @@ reg_table reg_tables[] = {
|
||||
{.ccode = "PF", .region = REGIONS_ETSI},
|
||||
{.ccode = "PG", .region = REGIONS_FCC},
|
||||
{.ccode = "PH", .region = REGIONS_FCC},
|
||||
{.ccode = "PK", .region = REGIONS_ETSI},
|
||||
{.ccode = "PK", .region = REGIONS_DEFAULT},
|
||||
{.ccode = "PL", .region = REGIONS_ETSI},
|
||||
{.ccode = "PM", .region = REGIONS_ETSI},
|
||||
{.ccode = "PR", .region = REGIONS_FCC},
|
||||
@@ -361,7 +373,7 @@ reg_table reg_tables[] = {
|
||||
{.ccode = "SN", .region = REGIONS_FCC},
|
||||
{.ccode = "SR", .region = REGIONS_ETSI},
|
||||
{.ccode = "SV", .region = REGIONS_FCC},
|
||||
{.ccode = "SY", .region = REGIONS_DEFAULT},
|
||||
{.ccode = "SY", .region = REGIONS_ETSI},
|
||||
{.ccode = "TC", .region = REGIONS_FCC},
|
||||
{.ccode = "TD", .region = REGIONS_ETSI},
|
||||
{.ccode = "TG", .region = REGIONS_ETSI},
|
||||
@@ -372,6 +384,7 @@ reg_table reg_tables[] = {
|
||||
{.ccode = "TR", .region = REGIONS_ETSI},
|
||||
{.ccode = "TT", .region = REGIONS_FCC},
|
||||
{.ccode = "TW", .region = REGIONS_FCC},
|
||||
{.ccode = "TZ", .region = REGIONS_ETSI},
|
||||
{.ccode = "UA", .region = REGIONS_ETSI},
|
||||
{.ccode = "UG", .region = REGIONS_FCC},
|
||||
{.ccode = "UY", .region = REGIONS_FCC},
|
||||
@@ -382,10 +395,13 @@ reg_table reg_tables[] = {
|
||||
{.ccode = "VN", .region = REGIONS_JP},
|
||||
{.ccode = "VU", .region = REGIONS_FCC},
|
||||
{.ccode = "WF", .region = REGIONS_ETSI},
|
||||
{.ccode = "WS", .region = REGIONS_ETSI},
|
||||
{.ccode = "YE", .region = REGIONS_DEFAULT},
|
||||
{.ccode = "YT", .region = REGIONS_ETSI},
|
||||
{.ccode = "ZA", .region = REGIONS_ETSI},
|
||||
{.ccode = "ZM", .region = REGIONS_ETSI},
|
||||
{.ccode = "FO", .region = REGIONS_ETSI},
|
||||
{.ccode = "FK", .region = REGIONS_ETSI},
|
||||
{.ccode = "ZW", .region = REGIONS_ETSI},
|
||||
};
|
||||
|
||||
@@ -417,6 +433,8 @@ u8 get_region_index(char * name)
|
||||
return REGIONS_ETSI;
|
||||
else if (strncmp(name, "JP", 2) == 0)
|
||||
return REGIONS_JP;
|
||||
else if (strncmp(name, "KCC", 3) == 0)
|
||||
return REGIONS_KCC;
|
||||
else if (strncmp(name, "UNSET", 5) == 0)
|
||||
return REGIONS_DEFAULT;
|
||||
|
||||
@@ -424,6 +442,7 @@ u8 get_region_index(char * name)
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef CONFIG_POWER_LIMIT
|
||||
#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_5G_BW_NUM 3
|
||||
#define MAX_REGION_NUM 5
|
||||
#define MAX_REGION_NUM 6
|
||||
|
||||
|
||||
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 */
|
||||
buffer = vmalloc(size);
|
||||
buffer = vmalloc(size + 1);
|
||||
if (!buffer) {
|
||||
*fw_buf = NULL;
|
||||
__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);
|
||||
#endif
|
||||
|
||||
*((char*)buffer + size) = 0;
|
||||
if (size != rdlen) {
|
||||
AICWFDBG(LOGERROR, "%s: %s file rdlen invalid %d\n", __func__, name, (int)rdlen);
|
||||
*fw_buf = NULL;
|
||||
@@ -836,6 +856,69 @@ int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
|
||||
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
|
||||
@@ -1586,7 +1669,8 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
|
||||
if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC ||
|
||||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){
|
||||
#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
|
||||
AICWFDBG(LOGINFO, "testmode=%d\n", testmode);
|
||||
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
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
#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]);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -2311,6 +2451,23 @@ void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x
|
||||
}
|
||||
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)
|
||||
{
|
||||
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_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)
|
||||
{
|
||||
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_TAB_DEFINE 1
|
||||
@@ -3465,11 +3717,21 @@ static int rwnx_plat_userconfig_load(struct rwnx_hw *rwnx_hw) {
|
||||
#ifdef CONFIG_POWER_LIMIT
|
||||
rwnx_plat_powerlimit_load_8800dcdw(rwnx_hw, PRODUCT_ID_AIC8800DW);
|
||||
#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){
|
||||
rwnx_plat_userconfig_load_8800d80(rwnx_hw);
|
||||
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 ||
|
||||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
|
||||
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;
|
||||
|
||||
@@ -71,10 +71,12 @@ typedef struct
|
||||
txpwr_lvl_conf_v3_t txpwr_lvl_v3;
|
||||
txpwr_lvl_conf_v4_t txpwr_lvl_v4;
|
||||
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_ofst_conf_t txpwr_ofst;
|
||||
txpwr_ofst2x_conf_t txpwr_ofst2x;
|
||||
txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2;
|
||||
txpwr_ofst2x_conf_v3_t txpwr_ofst2x_v3;
|
||||
xtal_cap_conf_t xtal_cap;
|
||||
} userconfig_info_t;
|
||||
|
||||
@@ -85,6 +87,7 @@ typedef enum {
|
||||
REGIONS_FCC,
|
||||
REGIONS_ETSI,
|
||||
REGIONS_JP,
|
||||
REGIONS_KCC,
|
||||
REGIONS_DEFAULT,
|
||||
} 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_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_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_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_v3_in_fdrv(txpwr_ofst2x_conf_v3_t *txpwr_ofst2x_v3);
|
||||
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 rwnx_plat_userconfig_parsing(char *buffer, int size);
|
||||
|
||||
@@ -169,7 +175,7 @@ u8 get_region_index(char * name);
|
||||
|
||||
#ifdef CONFIG_POWER_LIMIT
|
||||
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_chnum(uint8_t chnum, uint8_t r_idx, uint8_t bw);
|
||||
#endif
|
||||
@@ -182,5 +188,17 @@ static inline unsigned int rwnx_platform_get_irq(struct rwnx_plat *rwnx_plat)
|
||||
{
|
||||
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_ */
|
||||
|
||||
@@ -182,28 +182,27 @@ static const struct radar_types fcc_radar_types = {
|
||||
};
|
||||
|
||||
#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[] = {
|
||||
JP_PATTERN(0, 0, 8, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(1, 2, 8, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(2, 0, 8, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(3, 0, 8, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(4, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(5, 6, 20, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(6, 10, 28, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(7, 50, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG),
|
||||
JP_PATTERN(8, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(0, 0, 4, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(1, 0, 4, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(2, 0, 4, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(3, 0, 6, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(4, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(5, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(6, 48, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG),
|
||||
JP_PATTERN(7, 0, 4, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
|
||||
};
|
||||
|
||||
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(1, 2, 6, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(2, 0, 8, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(3, 2, 2, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(4, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(5, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(6, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(7, 50, 104, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG),
|
||||
JP_PATTERN(8, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(0, 0, 4, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(1, 0, 4, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(2, 0, 4, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(3, 0, 6, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(4, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(5, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT),
|
||||
JP_PATTERN(6, 48, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG),
|
||||
JP_PATTERN(7, 0, 4, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
|
||||
};
|
||||
|
||||
static const struct radar_types jp_radar_types = {
|
||||
@@ -219,33 +218,6 @@ static const struct radar_types *dfs_domains[] = {
|
||||
&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
|
||||
* @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;
|
||||
const struct radar_detector_specs *rs = pde->rs;
|
||||
|
||||
if(radar->status != RWNX_RADAR_CAC_BUSY) {
|
||||
return NULL;
|
||||
}
|
||||
//if(radar->status != RWNX_RADAR_CAC_BUSY) {
|
||||
// return NULL;
|
||||
//}
|
||||
|
||||
if (list_empty(&pde->sequences)) {
|
||||
/* 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->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
|
||||
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)
|
||||
&ctxt->chan_def,
|
||||
#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);
|
||||
#else
|
||||
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");
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -1621,7 +1617,7 @@ void rwnx_radar_cancel_cac(struct rwnx_radar *radar)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
||||
&ctxt->chan_def,
|
||||
#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);
|
||||
#else
|
||||
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);
|
||||
|
||||
return size_needed;
|
||||
}
|
||||
return size_needed;
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
@@ -32,6 +32,34 @@ enum rwnx_radar_detector {
|
||||
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
|
||||
#include <linux/workqueue.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);
|
||||
int rwnx_radar_dump_radar_detected(char *buf, size_t len,
|
||||
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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (ieee80211_is_probe_req(mgmt->frame_control)) {
|
||||
if (!rwnx_vif->ap.start)
|
||||
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);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1308,7 +1310,7 @@ static void rwnx_rx_add_rtap_hdr(struct rwnx_hw* rwnx_hw,
|
||||
|
||||
// Check for HE frames
|
||||
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 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)
|
||||
@@ -1364,8 +1366,18 @@ static void rwnx_rx_add_rtap_hdr(struct rwnx_hw* rwnx_hw,
|
||||
while ((pos - (u8 *)rtap) & 1)
|
||||
pos++;
|
||||
rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_HE);
|
||||
memcpy(pos, &he, sizeof(he));
|
||||
pos += sizeof(he);
|
||||
put_unaligned_le16(le16_to_cpu(he.data1), pos);
|
||||
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
|
||||
@@ -1833,8 +1845,7 @@ bool reord_rxframes_process(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *pr
|
||||
return bPktInBuf;
|
||||
}
|
||||
|
||||
void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv,
|
||||
struct reord_ctrl *preorder_ctrl)
|
||||
void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *preorder_ctrl)
|
||||
{
|
||||
struct list_head *phead, *plist;
|
||||
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 rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif;
|
||||
struct ethhdr *eh = (struct ethhdr *)(skb->data);
|
||||
u8 *da = eh->h_dest;
|
||||
u8 is_mcast = ((*da) & 0x01)? 1 : 0;
|
||||
|
||||
#if 0
|
||||
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;
|
||||
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);
|
||||
|
||||
if((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
|
||||
@@ -2039,9 +2048,9 @@ int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv,
|
||||
} else {
|
||||
if(timer_pending(&preorder_ctrl->reord_timer)) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
|
||||
ret = timer_delete(&preorder_ctrl->reord_timer);
|
||||
ret = timer_delete(&preorder_ctrl->reord_timer);
|
||||
#else
|
||||
ret = del_timer(&preorder_ctrl->reord_timer);
|
||||
ret = del_timer(&preorder_ctrl->reord_timer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -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(((skb->data[0] & 0x0C) == 0) && (skb->data[1] & 0x40) == 0x40){ //protect management frame
|
||||
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);
|
||||
skb_pull(skb,8);
|
||||
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;
|
||||
bool resend = false, forward = true;
|
||||
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);
|
||||
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)
|
||||
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 */
|
||||
if (status & RX_STAT_DELETE) {
|
||||
/* 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 {
|
||||
#ifdef CONFIG_RWNX_MON_DATA
|
||||
skb_monitor = skb_copy_expand(skb, rtap_len, 0, GFP_ATOMIC);
|
||||
skb_monitor->data += (msdu_offset + 2); //sdio/usb word allign
|
||||
if (skb_monitor) {
|
||||
skb_monitor->data += (msdu_offset + 2); //sdio/usb word allign
|
||||
|
||||
//Save frame length
|
||||
frm_len = le32_to_cpu(hw_rxhdr->hwvect.len);
|
||||
//Save frame length
|
||||
frm_len = le32_to_cpu(hw_rxhdr->hwvect.len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
skb_reset_tail_pointer(skb);
|
||||
skb->len = 0;
|
||||
if (!skb_monitor) {
|
||||
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_monitor->len = 0;
|
||||
skb_put(skb_monitor, frm_len);
|
||||
@@ -2375,7 +2410,7 @@ check_len_update:
|
||||
hdr = (struct ieee80211_hdr *)(skb->data + msdu_offset);
|
||||
rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx);
|
||||
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);
|
||||
#else
|
||||
cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC);
|
||||
@@ -2389,8 +2424,26 @@ check_len_update:
|
||||
rwnx_rx_vector_convert(rwnx_hw,
|
||||
&hw_rxhdr->hwvect.rx_vect1,
|
||||
&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
|
||||
#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];
|
||||
seq_num = ((skb->data[22] & 0xf0) >> 4) | (skb->data[23] << 4);
|
||||
frag_num = (skb->data[22] & 0x0f);
|
||||
@@ -2398,28 +2451,86 @@ check_len_update:
|
||||
|
||||
if ((skb->data[0] & 0x0f) == 0x08) {
|
||||
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;
|
||||
#endif
|
||||
is_qos = 1;
|
||||
#ifdef CONFIG_SUPPORT_4ADDR
|
||||
if (b_4addr) {
|
||||
if (skb->data[30] & 0x80)
|
||||
is_amsdu = 1;
|
||||
} else {
|
||||
if (skb->data[24] & 0x80)
|
||||
is_amsdu = 1;
|
||||
}
|
||||
#else
|
||||
if (skb->data[24] & 0x80)
|
||||
is_amsdu = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(skb->data[1] & 0x80)// htc
|
||||
hdr_len += 4;
|
||||
|
||||
if((skb->data[1] & 0x3) == 0x1) {// to ds
|
||||
memcpy(ra, &skb->data[16], MAC_ADDR_LEN);//destination addr
|
||||
memcpy(ta, &skb->data[10], MAC_ADDR_LEN);//source addr
|
||||
} else if((skb->data[1] & 0x3) == 0x2) { //from ds
|
||||
memcpy(ta, &skb->data[16], MAC_ADDR_LEN);//destination addr
|
||||
memcpy(ra, &skb->data[4], MAC_ADDR_LEN);//BSSID
|
||||
}
|
||||
#ifdef CONFIG_SUPPORT_4ADDR
|
||||
if (b_4addr) {
|
||||
if ((skb->data[1] & 0x3) != 0x3) {
|
||||
printk("aicwf: 4addr DS error, to_from ds:%d\n", skb->data[1] & 0x3);
|
||||
print_hex_dump(KERN_ERR,"rx_4addr ",DUMP_PREFIX_NONE, 16, 1, skb->data, skb->len, false);
|
||||
}
|
||||
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);
|
||||
|
||||
switch (hw_rxhdr->hwvect.decr_status) {
|
||||
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
|
||||
//skb_pull(&skb->data[skb->len-8], 8); //ccmp_mic_len
|
||||
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);
|
||||
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)
|
||||
hw_rxhdr->flags_is_amsdu = 1;
|
||||
else
|
||||
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)
|
||||
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 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,
|
||||
sta->mac_addr, -1, GFP_ATOMIC);
|
||||
#else
|
||||
@@ -2675,7 +2803,7 @@ check_len_update:
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||
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
|
||||
#ifdef CONFIG_BAND_STEERING
|
||||
(&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 */
|
||||
};
|
||||
|
||||
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_rxdataind(void *pthis, void *hostid);
|
||||
u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *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
|
||||
int aicwf_process_msg_rxframes(struct aicwf_rx_priv *rx_priv);
|
||||
#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);
|
||||
void reord_timeout_worker(struct work_struct *work);
|
||||
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)
|
||||
void reord_timeout_handler (ulong data);
|
||||
#else
|
||||
void reord_timeout_handler (struct timer_list *t);
|
||||
#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
|
||||
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) {
|
||||
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));
|
||||
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.dialog_token = dialog_token;
|
||||
mgmt->u.action.u.tdls_discover_resp.capability =
|
||||
cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code));
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@@ -766,9 +775,9 @@ rwnx_tdls_send_mgmt_packet_data(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_v
|
||||
|
||||
params.len = skb->len;
|
||||
params.buf = skb->data;
|
||||
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, ¶ms, false, &cookie);
|
||||
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, ¶ms, false, &cookie, false);
|
||||
#else
|
||||
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, NULL, false, 0, skb->data, skb->len, false, false, &cookie);
|
||||
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, NULL, false, 0, skb->data, skb->len, false, false, &cookie, false);
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1325,6 +1325,7 @@ int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg)
|
||||
sw_txhdr->rwnx_sta = sta;
|
||||
sw_txhdr->rwnx_vif = rwnx_vif;
|
||||
sw_txhdr->skb = skb;
|
||||
sw_txhdr->cookie = (unsigned long)skb;
|
||||
sw_txhdr->headroom = headroom;
|
||||
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
|
||||
|
||||
@@ -1541,6 +1542,7 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
sw_txhdr->rwnx_sta = sta;
|
||||
sw_txhdr->rwnx_vif = rwnx_vif;
|
||||
sw_txhdr->skb = skb;
|
||||
sw_txhdr->cookie = (unsigned long)skb;
|
||||
sw_txhdr->headroom = headroom;
|
||||
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
|
||||
|
||||
@@ -1630,7 +1632,12 @@ free:
|
||||
* @params: Mgmt frame parameters
|
||||
* @offchan: Indicate whether the frame must be send via the offchan TXQ.
|
||||
* (is is redundant with params->offchan ?)
|
||||
* @cookie: updated with a unique value to identify the frame with upper layer
|
||||
* @cookie: on return, the value cfg80211_mgmt_tx_status() will report for
|
||||
* this frame: invented here (the skb pointer) unless
|
||||
* @use_given_cookie is set, in which case *@cookie is kept.
|
||||
* @use_given_cookie: *@cookie already holds the cookie cfg80211 assigned
|
||||
* (7.3+, the direct .mgmt_tx path only); honour it instead of
|
||||
* inventing one. Every other caller passes false.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1638,7 +1645,7 @@ free:
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
||||
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
struct cfg80211_mgmt_tx_params *params, bool offchan,
|
||||
u64 *cookie)
|
||||
u64 *cookie, bool use_given_cookie)
|
||||
#else
|
||||
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
struct ieee80211_channel *channel, bool offchan,
|
||||
@@ -1649,7 +1656,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
|
||||
bool dont_wait_for_ack,
|
||||
#endif
|
||||
u64 *cookie)
|
||||
u64 *cookie, bool use_given_cookie)
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||
{
|
||||
struct rwnx_hw *rwnx_hw = vif->rwnx_hw;
|
||||
@@ -1703,7 +1710,18 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*cookie = (unsigned long)skb;
|
||||
/*
|
||||
* use_given_cookie is true only for the direct cfg80211 .mgmt_tx call
|
||||
* path on 7.3+, where *cookie already holds the value cfg80211
|
||||
* pre-assigned and must be echoed back via cfg80211_mgmt_tx_status()
|
||||
* later -- see rwnx_cfg80211_mgmt_tx(). TDLS's internal reuse of this
|
||||
* function (use_given_cookie == false) never goes through that cfg80211
|
||||
* op, so it still gets an invented, locally-unique cookie exactly as
|
||||
* before this fix, and on every kernel older than 7.3 every caller
|
||||
* passes use_given_cookie == false, also leaving this unchanged.
|
||||
*/
|
||||
if (!use_given_cookie)
|
||||
*cookie = (unsigned long)skb;
|
||||
|
||||
/*
|
||||
* Move skb->data pointer in order to reserve room for rwnx_txhdr
|
||||
@@ -1773,6 +1791,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
sw_txhdr->rwnx_sta = sta;
|
||||
sw_txhdr->rwnx_vif = vif;
|
||||
sw_txhdr->skb = skb;
|
||||
sw_txhdr->cookie = *cookie;
|
||||
sw_txhdr->headroom = headroom;
|
||||
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
|
||||
#ifdef CONFIG_RWNX_AMSDUS_TX
|
||||
@@ -1833,7 +1852,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BAND_STEERING
|
||||
#if 0//def CONFIG_BAND_STEERING
|
||||
void rwnx_probersp_work(struct work_struct *work)
|
||||
{
|
||||
struct ap_probe_rsp *rsp = container_of(work, struct ap_probe_rsp, rsp_work);
|
||||
@@ -1841,7 +1860,6 @@ void rwnx_probersp_work(struct work_struct *work)
|
||||
struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw;
|
||||
struct sk_buff *skb = NULL;
|
||||
struct rwnx_bcn *bcn = &rwnx_vif->ap.bcn;
|
||||
unsigned int len = bcn->len;
|
||||
u8_l *buf;
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
bool robust;
|
||||
@@ -1852,13 +1870,13 @@ void rwnx_probersp_work(struct work_struct *work)
|
||||
struct rwnx_sw_txhdr *sw_txhdr;
|
||||
struct txdesc_api *desc;
|
||||
headroom = sizeof(struct rwnx_txhdr);
|
||||
frame_len = len;
|
||||
frame_len = bcn->len;
|
||||
|
||||
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);
|
||||
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__);
|
||||
goto free_use;
|
||||
}
|
||||
@@ -1925,6 +1943,7 @@ void rwnx_probersp_work(struct work_struct *work)
|
||||
sw_txhdr->rwnx_sta = sta;
|
||||
sw_txhdr->rwnx_vif = rwnx_vif;
|
||||
sw_txhdr->skb = skb;
|
||||
sw_txhdr->cookie = (unsigned long)skb;
|
||||
sw_txhdr->headroom = headroom;
|
||||
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
|
||||
#ifdef CONFIG_RWNX_AMSDUS_TX
|
||||
@@ -1992,7 +2011,7 @@ free_use:
|
||||
|
||||
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_iterator iterator; // net/cfg80211.h
|
||||
u8_l *rtap_buf = (u8_l *)skb->data;
|
||||
@@ -2013,10 +2032,30 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
|
||||
bool offchan = false;
|
||||
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;
|
||||
|
||||
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);
|
||||
//rwnx_data_dump((char*)__func__, skb->data, skb->len);
|
||||
if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) ||
|
||||
@@ -2024,23 +2063,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)){
|
||||
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;
|
||||
pframe = rtap_buf + rtap_len;
|
||||
|
||||
@@ -2276,6 +2298,15 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
|
||||
sw_txhdr->rwnx_sta = sta;
|
||||
sw_txhdr->rwnx_vif = vif;
|
||||
sw_txhdr->skb = skb_mgmt;
|
||||
/*
|
||||
* Injected frames are flagged TXU_CNTRL_MGMT below and complete through
|
||||
* the same path as management frames, which reports sw_txhdr->cookie to
|
||||
* cfg80211_mgmt_tx_status(). There is no cfg80211-assigned cookie for an
|
||||
* injected frame, so this is the skb-derived value that path reported
|
||||
* before the field existed. Not gated on 7.3: this path runs on every
|
||||
* kernel with CONFIG_RWNX_MON_XMIT.
|
||||
*/
|
||||
sw_txhdr->cookie = (unsigned long)skb_mgmt;
|
||||
sw_txhdr->headroom = headroom;
|
||||
sw_txhdr->map_len = skb_mgmt->len - offsetof(struct rwnx_txhdr, hw_hdr);
|
||||
sw_txhdr->raw_frame = 1;
|
||||
@@ -2347,7 +2378,8 @@ int rwnx_txdatacfm(void *pthis, void *host_id)
|
||||
/* Check status in the header. If status is null, it means that the buffer
|
||||
* was not transmitted and we have to return immediately */
|
||||
if (rwnx_txst.value == 0) {
|
||||
return -1;
|
||||
//return -1;
|
||||
rwnx_txst.tx_done = 1;
|
||||
}
|
||||
|
||||
#ifdef AICWF_USB_SUPPORT
|
||||
@@ -2386,7 +2418,7 @@ int rwnx_txdatacfm(void *pthis, void *host_id)
|
||||
#endif
|
||||
/* Confirm transmission to CFG80211 */
|
||||
cfg80211_mgmt_tx_status(&sw_txhdr->rwnx_vif->wdev,
|
||||
(unsigned long)skb,
|
||||
sw_txhdr->cookie,
|
||||
(skb->data + sw_txhdr->headroom),
|
||||
sw_txhdr->frame_len,
|
||||
rwnx_txst.acknowledged,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "ipc_shared.h"
|
||||
#include "rwnx_txq.h"
|
||||
#include "hal_desc.h"
|
||||
#include "aicwf_tcp_ack.h"
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||
#define IEEE80211_NUM_TIDS 16
|
||||
@@ -129,6 +130,17 @@ struct rwnx_sw_txhdr {
|
||||
#endif
|
||||
u32 need_cfm;
|
||||
struct sk_buff *skb;
|
||||
/*
|
||||
* The cookie cfg80211_mgmt_tx_status() reports for this frame. sw_txhdr
|
||||
* comes from a kmem_cache and is never zeroed, so every allocation site
|
||||
* sets this: (unsigned long)skb, which is what the completion path
|
||||
* reported before the field existed, except in rwnx_start_mgmt_xmit(),
|
||||
* which stores the cfg80211-assigned cookie it was handed on 7.3+ (see
|
||||
* use_given_cookie there). Only frames flagged TXU_CNTRL_MGMT are ever
|
||||
* reported, but the field is initialised unconditionally so that filter
|
||||
* is not what keeps it safe.
|
||||
*/
|
||||
u64 cookie;
|
||||
|
||||
size_t map_len;
|
||||
dma_addr_t dma_addr;
|
||||
@@ -157,7 +169,7 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
||||
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
struct cfg80211_mgmt_tx_params *params, bool offchan,
|
||||
u64 *cookie);
|
||||
u64 *cookie, bool use_given_cookie);
|
||||
#else
|
||||
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
struct ieee80211_channel *channel, bool offchan,
|
||||
@@ -168,10 +180,11 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
|
||||
bool dont_wait_for_ack,
|
||||
#endif
|
||||
u64 *cookie);
|
||||
u64 *cookie, bool use_given_cookie);
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||
#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
|
||||
int rwnx_txdatacfm(void *pthis, void *host_id);
|
||||
|
||||
@@ -197,6 +210,8 @@ void rwnx_tx_push(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr, int flags);
|
||||
#ifdef CONFIG_BAND_STEERING
|
||||
void rwnx_probersp_work(struct work_struct *work);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FILTER_TCP_ACK
|
||||
int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg);
|
||||
#endif
|
||||
|
||||
#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_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq);
|
||||
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_ */
|
||||
|
||||
@@ -131,6 +131,7 @@ struct rwnx_ipc_rxbuf_elems {
|
||||
struct sk_buff *skb[RWNX_RXBUFF_MAX];
|
||||
int idx;
|
||||
};
|
||||
int rwnx_init_aic(struct rwnx_hw *rwnx_hw);
|
||||
|
||||
#endif /* CONFIG_RWNX_FULLMAC */
|
||||
#endif /* _RWNX_IPC_UTILS_H_ */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#define RWNX_VERS_REV "1a4b0054d2M (master)"
|
||||
#define RWNX_VERS_MOD "6.4.3.0"
|
||||
#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 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
|
||||
|
||||
@@ -7,14 +7,16 @@ CONFIG_M2D_OTA_AUTO_SUPPORT = n
|
||||
CONFIG_LINK_DET_5G = y
|
||||
CONFIG_FOR_IPCAM = n
|
||||
CONFIG_USB_SUSPEND_REBOOT_TIME = n
|
||||
CONFIG_SUPPORT_USB_SUSP = 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
|
||||
CONFIG_USE_FW_REQUEST ?= n
|
||||
CONFIG_PREALLOC_RX_SKB ?= n
|
||||
CONFIG_PREALLOC_TXQ ?= y
|
||||
CONFIG_BAND_STEERING = n
|
||||
CONFIG_PRBREQ_REPORT = n
|
||||
|
||||
# Platform support list
|
||||
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_SUPPORT_USB_SUSP) += -DCONFIG_SUPPORT_USB_SUSP
|
||||
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_PRBREQ_REPORT) += -DCONFIG_PRBREQ_REPORT
|
||||
ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN
|
||||
|
||||
obj-$(CONFIG_AIC_LOADFW_SUPPORT) := $(MODULE_NAME).o
|
||||
$(MODULE_NAME)-y := aic_bluetooth_main.o \
|
||||
@@ -67,7 +73,7 @@ ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
|
||||
#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-
|
||||
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-
|
||||
#KDIR := /home/yaya/E/Rockchip/3399/rk3399-android-10/kernel
|
||||
#ARCH ?= arm64
|
||||
@@ -91,12 +97,13 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
||||
ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU
|
||||
KVER := $(or $(KVER), $(kernelver), $(KERNELRELEASE), $(shell uname -r))
|
||||
KVER ?= $(shell uname -r)
|
||||
KDIR ?= /lib/modules/$(KVER)/build
|
||||
PWD ?= $(shell pwd)
|
||||
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/)
|
||||
CROSS_COMPILE ?=
|
||||
PWD := $(shell pwd)
|
||||
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/)
|
||||
ARCH ?= $(SUBARCH)
|
||||
CROSS_COMPILE :=
|
||||
endif
|
||||
|
||||
|
||||
|
||||
@@ -44,21 +44,30 @@ typedef struct {
|
||||
#define USER_TX_USE_ANA_F_FLAG (0x01U << 2)
|
||||
#define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3)
|
||||
#define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4)
|
||||
#define USER_LOFT_CALIB_DISABLE_FLAG (0x01U << 6)
|
||||
#define USER_CAPA_CALIB_DISABLE_FLAG (0x01U << 7)
|
||||
#define USER_PWR_CALIB_DISABLE_FLAG (0x01U << 8)
|
||||
#define USER_IPA_CALIB_DISABLE_FLAG (0x01U << 13)
|
||||
|
||||
#define CFG_PWROFST_COVER_CALIB 1
|
||||
#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 USER_EXT_FLAGS_DEFAULT_D80 (USER_PWROFST_COVER_CALIB_FLAG)
|
||||
|
||||
#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)
|
||||
#define CFG_USER_PWROFST_COVER_CALIB_EN (1)
|
||||
#if (defined(CONFIG_POWER_LIMIT))
|
||||
#define CFG_USER_CHAN_MAX_TXPWR_EN (1)
|
||||
#else
|
||||
#define CFG_USER_CHAN_MAX_TXPWR_EN (0)
|
||||
#endif
|
||||
#define CFG_USER_TX_USE_ANA_F_EN (0)
|
||||
#if (defined(CONFIG_PRBREQ_REPORT))
|
||||
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (1)
|
||||
#else
|
||||
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (0)
|
||||
#endif
|
||||
#define CFG_USER_HE_MU_EDCA_UPDATE_DISABLE (0)
|
||||
#define CFG_USER_LOFT_CALIB_DISABLE_DISABLE (0)
|
||||
#define CFG_USER_CAPA_CALIB_DISABLE_DISABLE (0)
|
||||
#define CFG_USER_PWR_CALIB_DISABLE_DISABLE (0)
|
||||
#define CFG_USER_IPA_CALIB_DISABLE_DISABLE (0)
|
||||
|
||||
u32 patch_tbl_d80[][2] =
|
||||
{
|
||||
@@ -73,25 +82,47 @@ u32 patch_tbl_d80[][2] =
|
||||
{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
|
||||
{0x0188,
|
||||
(USER_EXT_FLAGS_DEFAULT_D80 |
|
||||
#if CFG_USER_CHAN_MAX_TXPWR_EN
|
||||
USER_CHAN_MAX_TXPWR_EN_FLAG |
|
||||
#endif
|
||||
#if CFG_USER_TX_USE_ANA_F_EN
|
||||
USER_TX_USE_ANA_F_FLAG |
|
||||
#endif
|
||||
#if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE
|
||||
USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG |
|
||||
#endif
|
||||
#if CFG_USER_HE_MU_EDCA_UPDATE_DISABLE
|
||||
USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG |
|
||||
#endif
|
||||
#if CFG_USER_LOFT_CALIB_DISABLE_DISABLE
|
||||
USER_LOFT_CALIB_DISABLE_FLAG |
|
||||
#endif
|
||||
#if CFG_USER_CAPA_CALIB_DISABLE_DISABLE
|
||||
USER_CAPA_CALIB_DISABLE_FLAG |
|
||||
#endif
|
||||
#if CFG_USER_PWR_CALIB_DISABLE_DISABLE
|
||||
USER_PWR_CALIB_DISABLE_FLAG |
|
||||
#endif
|
||||
#if CFG_USER_IPA_CALIB_DISABLE_DISABLE
|
||||
USER_IPA_CALIB_DISABLE_FLAG |
|
||||
#endif
|
||||
0) & ~(
|
||||
#if !CFG_USER_PWROFST_COVER_CALIB_EN
|
||||
USER_PWROFST_COVER_CALIB_FLAG |
|
||||
#endif
|
||||
0)
|
||||
}, // user_ext_flags
|
||||
|
||||
#ifdef CONFIG_RADAR_OR_IR_DETECT
|
||||
{0x0019c,0x00000B00},
|
||||
{0x0019c,0x00000900},
|
||||
#endif
|
||||
#ifdef CONFIG_WOWLAN
|
||||
{0x019c,0x01000000},
|
||||
#ifdef ANDROID_PLATFORM
|
||||
{0x01A0, 0x01000001},
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -303,6 +334,7 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){
|
||||
int syscfg_num;
|
||||
int ret, cnt;
|
||||
const u32 mem_addr = 0x40500000;
|
||||
const u32 cache_mem_addr = 0x40100020;
|
||||
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm);
|
||||
if (ret) {
|
||||
@@ -314,6 +346,19 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){
|
||||
}
|
||||
chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16);
|
||||
printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id);
|
||||
if (chip_mcu_id) {
|
||||
ret = rwnx_send_dbg_mem_read_req(usb_dev, cache_mem_addr, &rd_mem_addr_cfm);
|
||||
if (ret) {
|
||||
printk("%x rd fail: %d\n", 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;
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
syscfg_num = sizeof(syscfg_tbl_8800d80) / sizeof(u32) / 2;
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
@@ -337,7 +382,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;
|
||||
uint32_t ext_patch_nb = patch_info->ext_patch_nb;
|
||||
@@ -354,7 +399,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);
|
||||
memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name));
|
||||
sprintf(ext_patch_file_name,"%s%d.bin",
|
||||
FW_PATCH_BASE_NAME_8800D80_U02_EXT,
|
||||
filename,
|
||||
id);
|
||||
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);
|
||||
@@ -386,7 +431,6 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
||||
|
||||
int i = 0;
|
||||
|
||||
#if 0
|
||||
if (chip_id == CHIP_REV_U01) {
|
||||
head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80);
|
||||
} else {
|
||||
@@ -414,11 +458,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);
|
||||
#endif
|
||||
|
||||
if(testmode == FW_NORMAL_MODE){
|
||||
|
||||
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)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -426,14 +469,13 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
||||
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;
|
||||
}
|
||||
|
||||
if (aicbt_patch_table_load(usb_dev, head)) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
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))
|
||||
@@ -456,7 +498,6 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
||||
return -1;
|
||||
}
|
||||
}else {
|
||||
#if 0
|
||||
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -472,7 +513,6 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80, FW_BASE_NAME_8800D80)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -482,7 +522,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
||||
}
|
||||
}else if(testmode == FW_TEST_MODE){
|
||||
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)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -491,7 +531,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -508,7 +548,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
|
||||
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)) {
|
||||
AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__);
|
||||
return -1;
|
||||
|
||||
@@ -41,21 +41,32 @@ typedef struct {
|
||||
|
||||
#define USER_PWROFST_COVER_CALIB_FLAG (0x01U << 0)
|
||||
#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_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 CFG_USER_CHAN_MAX_TXPWR_EN 1
|
||||
#define USER_EXT_FLAGS_DEFAULT_D80X2 \
|
||||
(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
|
||||
#define CFG_USER_CHAN_MAX_TXPWR_EN 0
|
||||
#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
|
||||
#if (defined(CONFIG_PRBREQ_REPORT))
|
||||
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (1)
|
||||
#else
|
||||
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 0
|
||||
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (0)
|
||||
#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] =
|
||||
{
|
||||
@@ -71,29 +82,35 @@ u32 patch_tbl_d80x2[][2] =
|
||||
{0x0228, 0x50000a00},//ss aggr
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#ifdef USE_5G
|
||||
{0x00b4, 0xf3010001},
|
||||
#else
|
||||
{0x00b4, 0xf3010000},
|
||||
#endif
|
||||
#ifdef CONFIG_PLATFORM_HI
|
||||
{0x0170, 0x00000001},//rx aggr counter
|
||||
#else
|
||||
{0x0170, 0x0000000A},//rx aggr counter
|
||||
#endif
|
||||
#ifdef CONFIG_FLASH_CALRES
|
||||
{0x0234, 0x0000004F}, // cal_res_stored_in_flash_flags
|
||||
#endif
|
||||
|
||||
{0x01f0, 0x00000001
|
||||
#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
|
||||
{0x01f0,
|
||||
(USER_EXT_FLAGS_DEFAULT_D80X2 |
|
||||
#if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE
|
||||
USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG |
|
||||
#endif
|
||||
#if CFG_USER_HE_MU_EDCA_UPDATE_DISABLE
|
||||
USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG |
|
||||
#endif
|
||||
#if CFG_USER_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
|
||||
};
|
||||
|
||||
@@ -297,53 +314,84 @@ int rwnx_plat_userconfig_load_8800d80x2(struct aic_usb_dev *usb_dev){
|
||||
}
|
||||
#endif
|
||||
int system_config_8800d80x2(struct aic_usb_dev *usb_dev){
|
||||
int syscfg_num;
|
||||
int ret, cnt;
|
||||
const u32 mem_addr = 0x40500000;
|
||||
const u32 mem_addr2 = 0x40500004;
|
||||
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm);
|
||||
if (ret) {
|
||||
printk("%x rd fail: %d\n", mem_addr, ret);
|
||||
return ret;
|
||||
}
|
||||
chip_id = rd_mem_addr_cfm.memdata >> 16;
|
||||
int syscfg_num;
|
||||
int ret, cnt;
|
||||
const u32 mem_addr = 0x40500000;
|
||||
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;
|
||||
|
||||
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr2, &rd_mem_addr_cfm);
|
||||
if (ret) {
|
||||
printk("%x rd fail: %d\n", mem_addr2, ret);
|
||||
return ret;
|
||||
}
|
||||
if (((rd_mem_addr_cfm.memdata >> 17) & 0x01UL) == 0x00UL) {
|
||||
chip_mcu_id = 1;
|
||||
}
|
||||
/* 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);
|
||||
}
|
||||
|
||||
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;
|
||||
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]);
|
||||
if (ret) {
|
||||
printk("%x write fail: %d\n", syscfg_tbl_8800d80x2[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
syscfg_num = sizeof(syscfg_tbl_masked_8800d80x2) / sizeof(u32) / 3;
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_mask_write_req(usb_dev,
|
||||
syscfg_tbl_masked_8800d80x2[cnt][0], syscfg_tbl_masked_8800d80x2[cnt][1], syscfg_tbl_masked_8800d80x2[cnt][2]);
|
||||
if (ret) {
|
||||
printk("%x mask write fail: %d\n", syscfg_tbl_masked_8800d80x2[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm);
|
||||
if (ret) {
|
||||
printk("%x rd fail: %d\n", mem_addr, ret);
|
||||
return ret;
|
||||
}
|
||||
chip_id = rd_mem_addr_cfm.memdata >> 16;
|
||||
|
||||
return 0;
|
||||
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr2, &rd_mem_addr_cfm);
|
||||
if (ret) {
|
||||
printk("%x rd fail: %d\n", mem_addr2, ret);
|
||||
return ret;
|
||||
}
|
||||
if (((rd_mem_addr_cfm.memdata >> 17) & 0x01UL) == 0x00UL) {
|
||||
chip_mcu_id = 1;
|
||||
}
|
||||
|
||||
printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id);
|
||||
|
||||
syscfg_num = sizeof(syscfg_tbl_8800d80x2) / sizeof(u32) / 2;
|
||||
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]);
|
||||
if (ret) {
|
||||
printk("%x write fail: %d\n", syscfg_tbl_8800d80x2[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
syscfg_num = sizeof(syscfg_tbl_masked_8800d80x2) / sizeof(u32) / 3;
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_mask_write_req(usb_dev,
|
||||
syscfg_tbl_masked_8800d80x2[cnt][0], syscfg_tbl_masked_8800d80x2[cnt][1], syscfg_tbl_masked_8800d80x2[cnt][2]);
|
||||
if (ret) {
|
||||
printk("%x mask write fail: %d\n", syscfg_tbl_masked_8800d80x2[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
uint32_t id = 0;
|
||||
uint32_t addr = 0;
|
||||
|
||||
uint32_t mem_w_add = 0;
|
||||
uint32_t mem_w_data = 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++){
|
||||
id = *(patch_info->ext_patch_param + (index * 2));
|
||||
addr = *(patch_info->ext_patch_param + (index * 2) + 1);
|
||||
memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name));
|
||||
sprintf(ext_patch_file_name,"%s%d.bin",
|
||||
FW_PATCH_BASE_NAME_8800D80X2_U03_EXT,
|
||||
filename,
|
||||
id);
|
||||
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);
|
||||
@@ -393,6 +451,10 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
||||
|
||||
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) {
|
||||
head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80X2_U03);
|
||||
} else {
|
||||
@@ -480,7 +542,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -556,23 +618,14 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
||||
mdelay(100);
|
||||
#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)) {
|
||||
AICWFDBG(LOGERROR,"%s wifi fw 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)) {
|
||||
AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, HOST_START_APP_AUTO)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, HOST_START_APP_AUTO)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
#ifdef CONFIG_USB_BT
|
||||
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80X2_U05)) {
|
||||
return -1;
|
||||
@@ -582,7 +635,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
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);
|
||||
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);
|
||||
|
||||
int ret;
|
||||
ret = rwnx_send_dbg_mem_write_req(usb_dev, 0x40500048, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80);
|
||||
if (ret) {
|
||||
printk("%x write fail\n", ret);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#define USB_DEVICE_ID_AIC_8800D80X2 0x8D90
|
||||
#define USB_DEVICE_ID_AIC_8800D81X2 0x8D91
|
||||
#define USB_DEVICE_ID_AIC_8800D89X2 0x8D99
|
||||
#define USB_DEVICE_ID_AIC_8800D40X2 0x8D92
|
||||
|
||||
#ifdef CONFIG_FOR_IPCAM
|
||||
#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_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 FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt"
|
||||
|
||||
#define RAM_FMAC_FW_ADDR_8800D80X2 0x120000
|
||||
#define RAM_FMAC_RF_FW_ADDR_8800D80X2 0x120000
|
||||
#define RAM_FMAC_FW_ADDR_8800D80X2 0x128000
|
||||
#define RAM_FMAC_RF_FW_ADDR_8800D80X2 0x128000
|
||||
|
||||
#define FW_RAM_ADID_BASE_ADDR_8800D80X2_U03 0x003018f8
|
||||
#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_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);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#define DATA_BUF_MAX 2048
|
||||
#define TXPKT_BLOCKSIZE 512
|
||||
#define MAX_AGGR_TXPKT_LEN (1536*32)
|
||||
#define CMD_TX_TIMEOUT 2000
|
||||
#define CMD_TX_TIMEOUT 5000
|
||||
#define TX_ALIGNMENT 4
|
||||
|
||||
#define RX_HWHRD_LEN 60 //58->60 word allined
|
||||
|
||||
@@ -20,20 +20,6 @@ extern int flash_erase_len;
|
||||
int flash_write_size = 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 = {
|
||||
.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 = {
|
||||
.enable = 1,
|
||||
@@ -72,13 +47,6 @@ txpwr_ofst_conf_t userconfig_txpwr_ofst = {
|
||||
.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 = {
|
||||
.enable = 0,
|
||||
@@ -757,7 +725,7 @@ int rwnx_plat_flash_bin_upload_android(struct aic_usb_dev *usbdev, u32 fw_addr,
|
||||
int err=0;
|
||||
const u32 mem_addr = fw_addr;
|
||||
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||
u32 crc = ~0UL;
|
||||
u32 crc = (u32)~0UL;
|
||||
|
||||
/* load aic firmware */
|
||||
size = aic_load_firmware(&dst, filename, dev);
|
||||
@@ -1285,6 +1253,149 @@ static struct aicbt_info_t aicbt_info[] = {
|
||||
},//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)
|
||||
{
|
||||
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 + 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 uart_baud[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_baud);
|
||||
printk("%s bt uart_flowctrl[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_flowctrl);
|
||||
printk("%s bt lpm_enable[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].lpm_enable);
|
||||
printk("%s bt tx_pwr[%d]:%d \r\n", __func__, usbdev->chipid, 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 btport[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].btport);
|
||||
printk("%s bt uart_baud[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_baud);
|
||||
printk("%s bt uart_flowctrl[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_flowctrl);
|
||||
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) {
|
||||
@@ -1326,7 +1438,8 @@ int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table
|
||||
data += 2;
|
||||
}
|
||||
if (p->type == AICBT_PT_PWRON)
|
||||
udelay(500);
|
||||
mdelay(100);
|
||||
// udelay(500);
|
||||
}
|
||||
aicbt_patch_table_free(head);
|
||||
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)
|
||||
{
|
||||
uint8_t *patch_info_array = (uint8_t*)patch_info;
|
||||
int base_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;
|
||||
memcpy_len = patch_info->info_len;
|
||||
}
|
||||
head_t->len = patch_info->info_len;
|
||||
AICWFDBG(LOGDEBUG, "%s memcpy_len:%d \r\n", __func__, memcpy_len);
|
||||
|
||||
if (patch_info->info_len == 0)
|
||||
return 0;
|
||||
|
||||
memcpy(((patch_info_array) + sizeof(patch_info->info_len)),
|
||||
head_t->data,
|
||||
memcpy_len * sizeof(uint32_t) * 2);
|
||||
if (memcpy_len >= 1) {
|
||||
patch_info->adid_addrinf = head_t->data[0];
|
||||
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__,
|
||||
((struct aicbt_patch_info_t *)patch_info_array)->adid_addrinf,
|
||||
((struct aicbt_patch_info_t *)patch_info_array)->addr_adid);
|
||||
patch_info->adid_addrinf,
|
||||
patch_info->addr_adid);
|
||||
|
||||
if (patch_info->ext_patch_nb > 0){
|
||||
int index = 0;
|
||||
|
||||
@@ -9,6 +9,53 @@ struct aicbt_patch_table {
|
||||
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);
|
||||
|
||||
@@ -30,6 +77,9 @@ int8_t rwnx_atoi(char *value);
|
||||
uint32_t rwnx_atoli(char *value);
|
||||
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);
|
||||
#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_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;
|
||||
u8 *buffer = bus->cmd_buf;
|
||||
u16 index = 0;
|
||||
int ret = 0;
|
||||
|
||||
memset(buffer, 0, CMD_BUF_MAX);
|
||||
buffer[0] = (len+4) & 0x00ff;
|
||||
@@ -262,10 +261,7 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len)
|
||||
index += 2;
|
||||
memcpy(&buffer[index], (u8 *)msg->param, msg->param_len);
|
||||
|
||||
ret = aicwf_bus_txmsg(bus, buffer, len + 8);
|
||||
if (ret == -EIO) {
|
||||
ret = aicwf_bus_txmsg(bus, buffer, len + 8);
|
||||
}
|
||||
aicwf_bus_txmsg(bus, buffer, len + 8);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
kfree(cmd);
|
||||
rwnx_msg_free(msg, msg_params);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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 */
|
||||
mem_write_req = rwnx_msg_zalloc(DBG_MEM_WRITE_REQ, TASK_DBG, DRV_TASK_ID,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <linux/slab.h>
|
||||
#include "aicwf_debug.h"
|
||||
#include "aicwf_txq_prealloc.h"
|
||||
|
||||
struct prealloc_txq{
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -985,7 +985,7 @@ u32 patch_tbl[][2] ={
|
||||
#ifdef CONFIG_USB_SUSPEND_REBOOT_TIME
|
||||
{0x0110, 0x03e80001}//reboot time when usb suspend,0001 enables reboot on suspend, default 0x3e8 = 1000ms reboot
|
||||
#else
|
||||
#ifdef CONFIG_SUPPORT_USB_SUSP
|
||||
#ifdef CONFIG_WOWLAN
|
||||
//USB SUSP keep working 0x0100:enable 0x0000:disable
|
||||
{0x0110, 0x00000100}
|
||||
#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;
|
||||
AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__);
|
||||
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{
|
||||
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_8800D81X2)},
|
||||
{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_AIC8800D81X2,
|
||||
PRODUCT_ID_AIC8800D89X2,
|
||||
PRODUCT_ID_AIC8800D40X2,
|
||||
};
|
||||
|
||||
|
||||
#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_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3)
|
||||
#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_busrx_thread(void *data);
|
||||
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_H_ */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#define RWNX_VERS_REV "1a4b0054d2M (master)"
|
||||
#define RWNX_VERS_MOD "6.4.3.0"
|
||||
#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