Author SHA1 Message Date
Shen Mintao cbc12c7bdb test: add btusb ZLP quirk for issue 63 2026-07-17 21:00:18 +08:00
Shen Mintao 8006daf6c7 fix: refresh Bazzite package for bluetooth branch
Pin the package to the current code commit, ship both maintained modules and all firmware variants, remove obsolete Bluetooth configuration, and document kernel-specific rebuilds.
2026-07-14 17:39:29 +08:00
Shen Mintao 6b8cb98e96 fix: clean up legacy aic_btusb configuration
Sanitize obsolete modprobe and udev rules during upgrades, unload the removed module when possible, and expand Bluetooth diagnostics for stale configuration. Continues the cleanup for #44 and #53.
2026-07-14 17:30:03 +08:00
Shen Mintao 7dc7569312 fix: improve dependency installation diagnostics
Install mode-switch dependencies, support a69c:572f, avoid redundant generic headers when a usable kernel build tree exists, and discover DKMS logs dynamically. Addresses installer portions of #28, #55, #65, #66, and #68.
2026-07-14 17:23:53 +08:00
Shen Mintao 0ed5afba03 fix: retry DKMS install when existing modules block install 2026-06-25 19:55:34 +08:00
Shen Mintao df8a44bf88 fix: handle Volumio and early firmware loading 2026-06-25 19:48:08 +08:00
Shen Mintao 18d4be4228 fix: write radiotap HE fields without struct copy 2026-06-25 19:38:40 +08:00
Shen Mintao 0c9e2f1bca fix: avoid fortify warning in patch info unpack 2026-06-25 19:32:42 +08:00
Shen Mintao 35c077823c fix: support newer kernel cfg80211 APIs 2026-06-25 19:26:59 +08:00
Shen MintaoandClaude Opus 4.7 7d7d9547b8 clean up stale aic_btusb references on bluetooth branch (#53)
This branch already switched to standard btusb (commit 86aa95f), but
several pieces still pointed back at the removed aic_btusb module:

- drivers/aic8800/aic_btusb/ source tree (no longer in build)
- modprobe/aic8800-bt.conf installed to /etc/modprobe.d/, which
  softdep'd btusb to a nonexistent aic_btusb and aliased AIC BT
  interfaces to it. This caused btusb to load without firmware
  having been uploaded, producing HCI_Reset timeout -110 on hci0.
- install.sh still copied that conf into /etc/modprobe.d/
- diagnose_bt.sh still told users to modprobe aic_btusb

diagnose_bt.sh rewritten to flag the residual /etc/modprobe.d/aic8800-bt.conf
on already-installed systems and to advise the correct flow
(aic_load_fw uploads BT firmware, btusb takes over).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:00:10 +08:00
Nurmukhamed Artykaly f40bda47c3 fixed README.md after requests of telegram users. 2026-05-20 13:38:56 +08:00
Nurmukhamed Artykaly f1f825850b fixed error after trying build. 2026-05-20 13:38:56 +08:00
Nurmukhamed Artykaly 7779c8a285 fixed after comment on github. 2026-05-20 13:38:56 +08:00
Nurmukhamed Artykaly 6510278218 refactored, added bluetooth branch. 2026-05-20 13:38:56 +08:00
Nurmukhamed Artykaly bfe239c9af fixed github raw url. 2026-05-20 13:38:56 +08:00
Nurmukhamed Artykaly 43878adc39 small fix. 2026-05-20 13:38:56 +08:00
Nurmukhamed Artykaly 58dff473e8 added Bazzite SRPM instructions. 2026-05-20 13:38:56 +08:00
Vladislav Tatyanin 16b5d4af33 fix: map riscv64 to riscv for kernel ARCH 2026-05-20 13:38:43 +08:00
Shen MintaoandClaude Sonnet 4.5 d8a8048929 Add support for TP-Link/Mercury branded AIC8800D80 USB WiFi adapters
Added USB VID/PID for TP-Link vendor (0x2357) and Mercury product (0x014b)
to support WiFi adapters that re-enumerate with these IDs after firmware
loading. The device is recognized as AIC8800D81 chip with RX aggregation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-20 13:38:23 +08:00
toor11 13cccb953c Add USB ID 368b:8d84 (AIC 8800D80 variant)
Device 368b:8d84 is an AIC 8800D80 variant not included in the USB
device table. Add it as AIC8800M80_CUS0 alongside the other M80 CUS
variants; it maps to PRODUCT_ID_AIC8800D81 like its siblings.

Tested on kernel 6.19.8-arch1 with a physical dongle (Bus 001 Device
005: ID 368b:8d84 AICSemi AIC 8800D80).
2026-05-20 13:37:53 +08:00
Shen MintaoandClaude Opus 4.6 52e968e765 fix: add -b bluetooth to git clone command in INSTALL_SCRIPT.md
Closes #48

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 17:01:02 +08:00
Shen Mintao ebab65c042 更新aic_btusb Makefile 2026-03-24 10:47:23 +08:00
Shen Mintao 3e0c941337 更新Makefile配置 2026-03-24 10:40:21 +08:00
Shen Mintao 3aa0191c7e Merge branch 'bluetooth' of https://github.com/shenmintao/aic8800d80 into bluetooth
# Conflicts:
#	drivers/aic8800/Makefile
2026-03-23 22:21:02 +08:00
Shen Mintao 089be7c4ff Merge main into bluetooth: apply KDIR fix and remove aic_btusb
- Apply PR #34 KDIR fix to dkms.conf for correct kernel header usage
- Remove remaining aic_btusb references from Makefile (standard btusb is used)
2026-03-23 22:17:53 +08:00
Shen MintaoandClaude Sonnet 4.5 41b5208909 feat: auto-load btusb driver in install.sh
Add automatic loading of btusb (standard Linux Bluetooth driver) after
WiFi module installation. This enables Bluetooth functionality without
requiring manual intervention.

The aic_load_fw module uploads Bluetooth firmware including ext0 patches,
then btusb driver handles the actual Bluetooth interface.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-11 10:48:42 +08:00
Shen MintaoandClaude Sonnet 4.5 f2e73a92ab fix: add Linux 6.17+ compatibility for get_tx_power callback
Add radio_idx and changed parameters to rwnx_cfg80211_get_tx_power function
to match the updated cfg80211 API signature introduced in Linux 6.17+. This
fixes compilation errors on kernel 6.19 and later versions.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-11 10:33:27 +08:00
Shen MintaoandClaude Sonnet 4.5 6a2d56d055 fix: update install.sh to install all firmware variants
Changes:
- Install firmware for all chip variants (D80, D80N, D80X2, DC, DW, DLN)
- Automatically detect and copy all firmware directories from fw/
- Update verification to check all installed firmware
- Update uninstallation instructions to remove all firmware

This ensures support for all newly added devices:
- AIC8800D80N series
- AIC8800DLN series
- AIC8800D80X2 with extended firmware
- All other chip variants

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-11 10:14:10 +08:00
Shen MintaoandClaude Sonnet 4.5 165a346c4d feat: update to SDK v5.0 with comprehensive kernel and device support
Major updates:
- Add Linux kernel 6.12-6.19 compatibility support
- Add Linux 6.16 timer_container_of and wakelock API support
- Add Debian 6.1.0-26 backport support
- Fix Bluetooth firmware upload for chip_mcu_id == 1 (cache_mem_addr)
- Add USB device ID 368b:8d81 support
- Add AIC8800DW device support
- Add TP-Link Archer TX1U Nano support (USB_VENDOR_ID_TENDA_V2:0x0110)
- Add TENDA series device support (U2, U11, U11 PRO)
- Add AIC8800FC_CUS4/5/6 series support
- Add AIC8800M80_CUS7/8 series support
- Add UGREEN AIC8800D80 adapter support
- Fix CONFIG_USB_BT interface number check (allow 1 or 3 interfaces)
- Update firmware files for all chip variants

Device support:
- AIC8800D80/D81/DC/DW series
- AIC8800D80X2/D81X2/D89X2 series
- AIC8800D80N/D80LN/D80WN/DLN/DWN series
- TENDA U2/U11/U11 PRO/TX1U Nano adapters
- Multiple OEM variants (FC_CUS1-6, M80_CUS1-8)

Kernel compatibility:
- Linux 3.10 - 6.19+
- Debian 6.1.0-26 with backported APIs
- Ubuntu and other distributions

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-11 10:10:30 +08:00
Shen Mintao b0787d9989 fix: fix usb_modeswitch message content 2026-03-04 21:55:41 +08:00
Shen Mintao 86aa95ffcb refactor: remove aic_btusb module, use standard btusb driver for Bluetooth 2026-03-04 18:12:08 +08:00
Shen Mintao cf63c8e0ee docs: update README with full Bluetooth support documentation 2026-03-04 16:48:49 +08:00
MinQ f2d9cc9ff0 Merge pull request #35 from bnister/bluetooth
Bluetooth firmware upload fix
2026-03-04 16:37:27 +08:00
bnister f36a0afeb4 Bluetooth fw upload fix: chip_mcu_id == 1 needs cache_mem_addr |= 1 2026-03-04 04:49:04 +03:00
Shen Mintao b771774f40 fix: pass KDIR to DKMS make command for proper kernel build path 2026-02-28 14:37:30 +08:00
Shen Mintao 600cdf5ef4 feat: add Kconfig for aic_btusb module 2026-02-28 14:34:52 +08:00
Shen Mintao 8a5af5cfdb fix: export CONFIG_AIC8800_BTUSB_SUPPORT for aic_btusb module compilation 2026-02-28 14:32:37 +08:00
Shen Mintao 85a412e5b8 feat: add aic_btusb bluetooth module support to install.sh 2026-02-28 14:27:02 +08:00
Shen Mintao 4f288d90b2 fix: fix 2026-02-28 09:11:25 +08:00
Shen Mintao 8b90bd8f45 feat: 添加蓝牙支持及固件更新 2026-02-27 18:19:39 +08:00
Shen Mintao 96e1d9cd3d feat: 增加对Linux 6.13+内核的MODULE_IMPORT_NS支持 2026-02-27 18:17:43 +08:00
159 changed files with 6086 additions and 1641 deletions
+2
View File
@@ -0,0 +1,2 @@
tests/issue63-btusb-zlp/*.patch -whitespace
tests/issue63-btusb-zlp/*.sh text eol=lf
+1 -1
View File
@@ -16,7 +16,7 @@ This automated installation script (`install.sh`) simplifies the process of inst
```bash ```bash
# Clone the repository and download the script, make the script executable # Clone the repository and download the script, make the script executable
git clone https://github.com/shenmintao/aic8800d80.git && cd aic8800d80 && chmod +x install.sh git clone -b bluetooth https://github.com/shenmintao/aic8800d80.git && cd aic8800d80 && chmod +x install.sh
# Run the installation # Run the installation
sudo ./install.sh sudo ./install.sh
+54 -1
View File
@@ -5,7 +5,7 @@ Added support for devices with Vendor ID 368B (tested).
Tested on Linux kernel 6.16 with Ubuntu 25.04 and 6.1.0.27 with Debian 12. Tested on Linux kernel 6.16 with Ubuntu 25.04 and 6.1.0.27 with Debian 12.
> **Bluetooth Support**: The [`bluetooth`](https://github.com/shenmintao/aic8800d80/tree/bluetooth) branch fully supports Bluetooth. This main branch only provides Wi-Fi functionality. Please switch to the `bluetooth` branch if you need Bluetooth support. This branch (`bluetooth`) fully supports both **Wi-Fi** and **Bluetooth**.
### Disclaimer ### Disclaimer
I did not develop this software, The code is sourced from the Tenda U11 driver. I only made some modifications to the code to adapt it to newer kernel versions. Apart from compilation issues, I am unable to address other problems. I did not develop this software, The code is sourced from the Tenda U11 driver. I only made some modifications to the code to adapt it to newer kernel versions. Apart from compilation issues, I am unable to address other problems.
@@ -98,3 +98,56 @@ If the device is still not active, check the kernel logs for any errors related
sudo dmesg sudo dmesg
``` ```
### Bluetooth Support
The `aic_load_fw` module loads the Bluetooth firmware during initialization. After the firmware is correctly uploaded, the standard Linux `btusb` driver handles the Bluetooth interface — no custom `aic_btusb` module is needed (see [PR #35](https://github.com/shenmintao/aic8800d80/pull/35) for details).
#### Verify Bluetooth is Working
After loading the driver and plugging in the USB device, check if the Bluetooth HCI device is registered:
```bash
hciconfig -a
```
You should see an HCI device (e.g., `hci0`) listed. If the device is down, bring it up:
```bash
sudo hciconfig hci0 up
```
You can also use `bluetoothctl` to scan and connect to Bluetooth devices:
```bash
bluetoothctl
# Inside bluetoothctl:
power on
scan on
```
#### Bluetooth Troubleshooting
If Bluetooth is not working, run the diagnostic script:
```bash
chmod +x diagnose_bt.sh
sudo ./diagnose_bt.sh
```
Common issues and solutions:
1. **Firmware not found**: Ensure the firmware files are correctly copied to `/lib/firmware/aic8800D80/`. Key Bluetooth firmware files include:
- `fw_patch_8800d80_u02.bin`
- `fw_patch_table_8800d80_u02.bin`
- `fw_adid_8800d80_u02.bin`
2. **Check kernel logs** for Bluetooth-related errors:
```bash
sudo dmesg | grep -iE "aicbt|bluetooth|hci|fw_patch"
```
3. **RF-Kill blocking Bluetooth**:
```bash
rfkill list bluetooth
sudo rfkill unblock bluetooth
```
+20
View File
@@ -1,3 +1,4 @@
# AIC8800 USB Mass Storage mode switch rules
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5723", SYMLINK+="tendaudisk", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5723", SYMLINK+="tendaudisk", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5724", SYMLINK+="ugreenax900", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5724", SYMLINK+="ugreenax900", RUN+="/usr/bin/eject /dev/%k"
@@ -6,3 +7,22 @@ KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5726", SYMLINK+="ten
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5727", SYMLINK+="tendaudiskv4", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5727", SYMLINK+="tendaudiskv4", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572a", SYMLINK+="tendaudiskv5", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572a", SYMLINK+="tendaudiskv5", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572c", SYMLINK+="cudydiskv2", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572c", SYMLINK+="cudydiskv2", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572f", SYMLINK+="aicudisk572f", RUN+="/usr/bin/eject /dev/%k"
# AIC8800D80 "Pandora" clone adapter - automatic mode switch & driver binding
# Triggers usb_modeswitch when the device is plugged in as 1111:1111
# --- Mode Switch ---
ACTION=="add", ATTRS{idVendor}=="1111", ATTRS{idProduct}=="1111", RUN+="/bin/sh -c 'if [ -x /usr/sbin/usb_modeswitch ]; then exec /usr/sbin/usb_modeswitch -c /etc/usb_modeswitch.d/1111:1111; elif [ -x /usr/bin/usb_modeswitch ]; then exec /usr/bin/usb_modeswitch -c /etc/usb_modeswitch.d/1111:1111; fi'"
# --- WiFi Driver Binding ---
# After mode switch, the device re-enumerates as a69c:8d81 (Radxa fw) or a69c:8d83 (Brostrend fw).
# If aic8800_fdrv doesn't auto-bind to the WiFi interface, add the VID:PID dynamically:
ACTION=="add", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="8d81", RUN+="/bin/sh -c 'echo a69c 8d81 > /sys/bus/usb/drivers/aic8800_fdrv/new_id 2>/dev/null || true'"
ACTION=="add", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="8d83", RUN+="/bin/sh -c 'echo a69c 8d83 > /sys/bus/usb/drivers/aic8800_fdrv/new_id 2>/dev/null || true'"
ACTION=="add", ATTRS{idVendor}=="368b", ATTRS{idProduct}=="8d81", RUN+="/bin/sh -c 'echo 368b 8d81 > /sys/bus/usb/drivers/aic8800_fdrv/new_id 2>/dev/null || true'"
# Unblock rfkill for Bluetooth
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="8d81", RUN+="/bin/sh -c 'rfkill unblock bluetooth 2>/dev/null || true'"
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="8d83", RUN+="/bin/sh -c 'rfkill unblock bluetooth 2>/dev/null || true'"
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="368b", ATTRS{idProduct}=="8d81", RUN+="/bin/sh -c 'rfkill unblock bluetooth 2>/dev/null || true'"
+64
View File
@@ -0,0 +1,64 @@
# 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/bluetooth/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. Bluetooth
is handled by the standard `btusb` kernel module after firmware initialization.
This RPM is built for the kernel reported by `uname -r`. Rebuild and reinstall
it after a Bazzite kernel upgrade.
+78
View File
@@ -0,0 +1,78 @@
%global commit 6b8cb98e969b04236f8726f7591393a040171735
%global shortcommit %(echo %{commit} | cut -c1-7)
%{!?kver:%global kver %(uname -r)}
Name: aic8800d80
Version: %{shortcommit}
Release: 1%{?dist}
Summary: AIC8800D80 USB Wi-Fi and Bluetooth 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: /usr/sbin/usb_modeswitch
Requires: /usr/sbin/rfkill
Requires(post): /usr/sbin/depmod
Requires(postun): /usr/sbin/depmod
%description
Out-of-tree AIC8800D80 USB driver with Wi-Fi support, Bluetooth firmware
loading, udev mode-switch rules, and all firmware variants shipped by the
upstream repository. Bluetooth interfaces are handled by the standard Linux
btusb driver after aic_load_fw initializes the device.
%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 \
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/udev/rules.d/90-aic8800-mode-switch.rules
%config(noreplace) /etc/usb_modeswitch.d/1111:1111
/usr/lib/firmware/aic8800*
%changelog
* Tue Jul 14 2026 Shen Mintao <shenmintao@gmail.com> - 6b8cb98-1
- Build the current bluetooth branch without the removed aic_btusb module.
- Package all firmware variants and current mode-switch rules.
- Remove the obsolete custom Bluetooth module integration.
+142
View File
@@ -0,0 +1,142 @@
#!/bin/bash
#
# AIC8800D80 Bluetooth Diagnostic Script
# 用于诊断蓝牙问题
#
# 本分支 (bluetooth) 使用内核标准 btusb 驱动接管蓝牙,
# aic_load_fw 负责把蓝牙固件上传到芯片。
# 不应该再安装/加载 aic_btusb。
#
echo "=== AIC8800D80 蓝牙诊断 ==="
echo ""
# 1. 检查 USB 设备
echo "1. USB 设备状态:"
echo " 当前 AIC 设备:"
lsusb | grep -iE "a69c|368b|1111" || echo " 未找到 AIC 设备"
echo ""
# 2. 检查 USB 接口数量
echo "2. USB 接口详情:"
for dev in /sys/bus/usb/devices/*; do
if [ -f "$dev/idVendor" ] && [ -f "$dev/idProduct" ]; then
vid=$(cat "$dev/idVendor" 2>/dev/null)
pid=$(cat "$dev/idProduct" 2>/dev/null)
if [[ "$vid" == "a69c" || "$vid" == "368b" ]]; then
echo " 设备: $vid:$pid"
if [ -d "$dev" ]; then
for intf in "$dev"/*:*; do
if [ -d "$intf" ]; then
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 " 接口: $class/$subclass/$protocol -> 驱动: ${driver:-未绑定}"
fi
done
fi
fi
fi
done
echo ""
# 3. 检查已加载的模块
echo "3. 已加载的相关模块 (期望: aic_load_fw + btusb):"
lsmod | grep -E "aic_load_fw|aicwf|aic_btusb|btusb|bluetooth" || echo " 未找到相关模块"
echo ""
# 4. 检查 HCI 设备
echo "4. HCI 设备:"
hciconfig -a 2>/dev/null || echo " 无法获取 HCI 信息 (可能需要 root 权限)"
echo ""
# 5. 检查蓝牙固件加载日志
echo "5. 蓝牙固件加载日志 (最近 50 行):"
dmesg | grep -iE "fw_patch|fw_adid|aicbt|bluetooth|btusb|hci" | tail -50
echo ""
# 6. 检查 rfkill 状态
echo "6. RF-Kill 状态:"
rfkill list bluetooth 2>/dev/null || echo " 无法获取 rfkill 信息"
echo ""
# 7. 检查残留的旧 aic_btusb 配置 (issue #53)
echo "7. 残留旧配置检查:"
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 || 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 || true
)
for legacy_file in "${legacy_modprobe_files[@]}"; do
echo " ⚠️ 发现旧 modprobe 指令: $legacy_file"
legacy_refs_found=true
done
for legacy_file in "${legacy_udev_files[@]}"; do
echo " ⚠️ 发现旧 udev 绑定规则: $legacy_file"
legacy_refs_found=true
done
if lsmod | awk '{print $1}' | grep -qx 'aic_btusb'; then
echo " ⚠️ 旧 aic_btusb 模块当前仍已加载"
legacy_refs_found=true
fi
if modinfo -n aic_btusb >/dev/null 2>&1; then
echo " ⚠️ 系统中仍存在 aic_btusb 模块: $(modinfo -n aic_btusb 2>/dev/null)"
legacy_refs_found=true
fi
if [ "$legacy_refs_found" = true ]; then
echo " 这些残留会尝试加载已删除的模块, 并干扰标准 btusb 的自动加载/绑定顺序。"
echo " 修复: 拉取最新 bluetooth 分支后重新运行 sudo ./install.sh"
if command -v update-initramfs >/dev/null 2>&1; then
echo " 然后执行: sudo update-initramfs -u"
elif command -v dracut >/dev/null 2>&1; then
echo " 然后执行: sudo dracut -f"
elif command -v mkinitcpio >/dev/null 2>&1; then
echo " 然后执行: sudo mkinitcpio -P"
fi
else
echo " 未发现活动的 aic_btusb 配置、规则或模块 (正常)"
fi
echo ""
# 8. 建议
echo "=== 诊断建议 ==="
echo ""
# 检查 aic_load_fw 是否加载 (它负责上传 WiFi + BT 固件)
if ! lsmod | grep -q "^aic_load_fw"; then
echo "⚠️ aic_load_fw 未加载"
echo " 该模块负责把蓝牙固件上传到芯片, 必须先于 btusb 工作"
echo " 解决方案: sudo modprobe aic_load_fw"
echo ""
fi
# 检查 HCI_Reset 超时 (典型症状: 固件未上传却让 btusb 接管)
if dmesg | grep -iE "hci0:.*command (0x|tx) timed out|hci0.*opcode.*0x0c03" | tail -5 | grep -q .; then
echo "⚠️ 检测到 HCI 命令超时 (HCI_Reset/-110)"
echo " 常见原因:"
echo " a) 旧 aic_btusb 配置或 udev 规则残留 (见第 7 项)"
echo " b) aic_load_fw 没有先把蓝牙固件 patch 上传到芯片"
echo " c) usb_modeswitch 没把 1111:1111 切换到真实 VID:PID"
echo " 排查: 看上面第 5 项日志, 应能看到 fw_patch_table_8800d80 / fw_adid 字样"
echo " 临时缓解: 拔插一次设备 (软件复位/飞行模式切换通常无法救活)"
echo ""
fi
# btusb 是否已接管 BT 接口 (这是正常预期)
if lsmod | grep -q "^btusb"; then
echo "✅ btusb 已加载 (正常, 本分支由 btusb 接管蓝牙)"
fi
echo "=== 诊断完成 ==="
+79 -19
View File
@@ -17,6 +17,29 @@ YELLOW='\033[1;33m'
BLUE='\033[0;34m' BLUE='\033[0;34m'
NC='\033[0m' NC='\033[0m'
DRV_NAME="aic8800"
DRV_VERSION="1.0.0"
INSTALL_LOG="/tmp/aic8800d80_install.log"
read_dkms_conf_value() {
local key="$1"
local file="$2"
grep -E "^[[:space:]]*${key}[[:space:]]*=" "$file" 2>/dev/null \
| head -1 \
| cut -d= -f2- \
| tr -d "\"'[:space:]"
}
if [ -f "./dkms.conf" ]; then
detected_name="$(read_dkms_conf_value PACKAGE_NAME ./dkms.conf)"
detected_version="$(read_dkms_conf_value PACKAGE_VERSION ./dkms.conf)"
[ -n "$detected_name" ] && DRV_NAME="$detected_name"
[ -n "$detected_version" ] && DRV_VERSION="$detected_version"
fi
mapfile -t DKMS_SOURCE_DIRS < <(find /usr/src -maxdepth 1 -type d -name "${DRV_NAME}-*" -print 2>/dev/null | sort)
print_section() { print_section() {
echo "" echo ""
echo -e "${BLUE}━━━ $1 ━━━${NC}" echo -e "${BLUE}━━━ $1 ━━━${NC}"
@@ -58,46 +81,73 @@ fi
print_section "2. Checking DKMS directory" print_section "2. Checking DKMS directory"
if [ -d "/usr/src/aic8800-1.0.0" ]; then echo "Detected package: ${DRV_NAME}/${DRV_VERSION}"
echo -e "${GREEN}✓${NC} /usr/src/aic8800-1.0.0 directory exists" if [ "${#DKMS_SOURCE_DIRS[@]}" -gt 0 ]; then
for source_dir in "${DKMS_SOURCE_DIRS[@]}"; do
echo -e "${GREEN}✓${NC} $source_dir directory exists"
echo "" echo ""
echo "Content:" echo "Content:"
ls -la /usr/src/aic8800-1.0.0/ ls -la "$source_dir/"
echo "" echo ""
echo "Checking drivers/aic8800 inside DKMS:" echo "Checking drivers/aic8800 inside DKMS:"
if [ -d "/usr/src/aic8800-1.0.0/drivers/aic8800" ]; then if [ -d "$source_dir/drivers/aic8800" ]; then
echo -e "${GREEN}✓${NC} drivers/aic8800 copied to DKMS" echo -e "${GREEN}✓${NC} drivers/aic8800 copied to DKMS"
ls -la /usr/src/aic8800-1.0.0/drivers/aic8800/ ls -la "$source_dir/drivers/aic8800/"
else else
echo -e "${RED}✗${NC} drivers/aic8800 NOT copied correctly!" echo -e "${RED}✗${NC} drivers/aic8800 NOT copied correctly!"
fi fi
echo ""
done
else else
echo -e "${RED}✗${NC} /usr/src/aic8800-1.0.0 directory NOT FOUND" echo -e "${RED}✗${NC} No /usr/src/${DRV_NAME}-* directory found"
fi fi
print_section "3. Checking DKMS build logs" print_section "3. Checking DKMS build logs"
if [ -f "/var/lib/dkms/aic8800/1.0.0/build/make.log" ]; then mapfile -t BUILD_LOGS < <(find "/var/lib/dkms/${DRV_NAME}" -type f -name make.log -print 2>/dev/null | sort)
echo -e "${GREEN}✓${NC} Build log found"
if [ "${#BUILD_LOGS[@]}" -gt 0 ]; then
for build_log in "${BUILD_LOGS[@]}"; do
echo -e "${GREEN}✓${NC} Build log found: $build_log"
echo "" echo ""
echo "Last 50 lines of make.log:" echo "Last 50 lines of make.log:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
tail -50 /var/lib/dkms/aic8800/1.0.0/build/make.log tail -50 "$build_log"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
done
else
echo -e "${RED}✗${NC} No make.log found under /var/lib/dkms/${DRV_NAME}/"
echo "The module may not have reached the build step yet, or this DKMS version stores logs elsewhere."
fi
if [ -f "$INSTALL_LOG" ]; then
echo ""
echo -e "${GREEN}✓${NC} Installer log found: $INSTALL_LOG"
echo "Last 50 lines of installer log:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
tail -50 "$INSTALL_LOG"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
else else
echo -e "${RED}✗${NC} Build log not found in /var/lib/dkms/aic8800/1.0.0/build/make.log" echo -e "${YELLOW}!${NC} Installer log not found: $INSTALL_LOG"
fi fi
print_section "4. Checking dkms.conf" print_section "4. Checking dkms.conf"
if [ -f "/usr/src/aic8800-1.0.0/dkms.conf" ]; then if [ "${#DKMS_SOURCE_DIRS[@]}" -gt 0 ]; then
echo -e "${GREEN}✓${NC} dkms.conf found" for source_dir in "${DKMS_SOURCE_DIRS[@]}"; do
if [ -f "$source_dir/dkms.conf" ]; then
echo -e "${GREEN}✓${NC} dkms.conf found: $source_dir/dkms.conf"
echo "" echo ""
echo "dkms.conf content:" cat "$source_dir/dkms.conf"
cat /usr/src/aic8800-1.0.0/dkms.conf echo ""
else
echo -e "${RED}✗${NC} dkms.conf NOT FOUND in $source_dir"
fi
done
else else
echo -e "${RED}✗${NC} dkms.conf NOT FOUND!" echo -e "${RED}✗${NC} No DKMS source directory available to inspect"
fi fi
if [ -f "./dkms.conf" ]; then if [ -f "./dkms.conf" ]; then
@@ -120,13 +170,23 @@ print_section "6. System information"
echo "Kernel: $(uname -r)" echo "Kernel: $(uname -r)"
echo "Architecture: $(uname -m)" echo "Architecture: $(uname -m)"
echo "" echo ""
echo "GCC version:" echo "Compiler version:"
gcc --version | head -1 if command -v gcc >/dev/null 2>&1; then
gcc --version | head -1
elif command -v clang >/dev/null 2>&1; then
clang --version | head -1
else
echo "No gcc or clang found"
fi
echo "" echo ""
echo "Installed kernel headers:" echo "Installed kernel headers:"
ls -d /lib/modules/$(uname -r)/build 2>/dev/null && echo "✓ Headers found" || echo "✗ Headers NOT found" ls -d "/lib/modules/$(uname -r)/build" 2>/dev/null && echo "✓ Headers found" || echo "✗ Headers NOT found"
print_section "7. DKMS status" print_section "7. DKMS status"
echo "DKMS modules registered:" echo "DKMS modules registered:"
dkms status if command -v dkms >/dev/null 2>&1; then
dkms status
else
echo -e "${RED}✗${NC} dkms command not found"
fi
+2 -2
View File
@@ -1,7 +1,7 @@
PACKAGE_NAME="aic8800" PACKAGE_NAME="aic8800"
PACKAGE_VERSION="1.0.0" PACKAGE_VERSION="1.0.0"
MAKE="KVER=${kernelver} 'make' -C drivers/aic8800" MAKE="KVER=${kernelver} KDIR=/lib/modules/${kernelver}/build 'make' -C drivers/aic8800"
CLEAN="KVER=${kernelver} 'make' -C drivers/aic8800 clean" CLEAN="KVER=${kernelver} KDIR=/lib/modules/${kernelver}/build 'make' -C drivers/aic8800 clean"
# Main module (aic8800_fdrv) # Main module (aic8800_fdrv)
BUILT_MODULE_NAME[0]="aic8800_fdrv" BUILT_MODULE_NAME[0]="aic8800_fdrv"
+16 -3
View File
@@ -8,6 +8,7 @@ obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/
export CONFIG_USE_FW_REQUEST = n export CONFIG_USE_FW_REQUEST = n
export CONFIG_PREALLOC_RX_SKB = y export CONFIG_PREALLOC_RX_SKB = y
export CONFIG_PREALLOC_TXQ = y export CONFIG_PREALLOC_TXQ = y
export CONFIG_WOWLAN = n
################################### ###################################
########## platform support list ########## ########## platform support list ##########
@@ -47,10 +48,10 @@ endif
ifeq ($(CONFIG_PLATFORM_UBUNTU), y) ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
KVER ?= $(shell uname -r) KVER ?= $(shell uname -r)
KDIR = /lib/modules/$(KVER)/build KDIR ?= /lib/modules/$(KVER)/build
PWD = $(shell pwd) PWD = $(shell pwd)
MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800 MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/ -e s/loongarch64/loongarch/ -e s/loong64/loongarch/) SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/ -e s/loongarch64/loongarch/ -e s/loong64/loongarch/ -e s/riscv64/riscv/)
ARCH ?= $(SUBARCH) ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= CROSS_COMPILE ?=
endif endif
@@ -59,9 +60,21 @@ endif
MAKEFLAGS +=-j$(shell nproc) MAKEFLAGS +=-j$(shell nproc)
KERNEL_AUTOCONF := $(KDIR)/include/config/auto.conf
KERNEL_CONFIG := $(KDIR)/.config
KERNEL_CC_IS_CLANG := $(shell if [ -r "$(KERNEL_AUTOCONF)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_AUTOCONF)"; then echo y; elif [ -r "$(KERNEL_CONFIG)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_CONFIG)"; then echo y; fi)
ifeq ($(KERNEL_CC_IS_CLANG),y)
LLVM ?= 1
endif
ifneq ($(LLVM),)
KBUILD_EXTRA_ARGS += LLVM=$(LLVM)
endif
all: modules all: modules
modules: modules:
make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) $(KBUILD_EXTRA_ARGS) modules
install: install:
mkdir -p $(MODDESTDIR) mkdir -p $(MODDESTDIR)
+16 -5
View File
@@ -82,7 +82,7 @@ CONFIG_BR_SUPPORT = n
CONFIG_USB_MSG_OUT_EP = y CONFIG_USB_MSG_OUT_EP = y
CONFIG_USB_MSG_IN_EP = y CONFIG_USB_MSG_IN_EP = y
CONFIG_USB_RX_REASSEMBLE = n CONFIG_USB_RX_REASSEMBLE = n
CONFIG_WOWLAN = n CONFIG_WOWLAN ?= n
#DCDW support tx aggr, D80 support both #DCDW support tx aggr, D80 support both
CONFIG_USB_RX_AGGR = n CONFIG_USB_RX_AGGR = n
@@ -93,7 +93,7 @@ CONFIG_GPIO_WAKEUP = n
CONFIG_CREATE_TRACE_POINTS = n CONFIG_CREATE_TRACE_POINTS = n
CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y
CONFIG_USE_USB_ZERO_PACKET = y CONFIG_USE_USB_ZERO_PACKET = y
CONFIG_DEBUG_FS = n CONFIG_DEBUG_FS ?= n
CONFIG_STA_SCAN_WHEN_P2P_WORKING = y CONFIG_STA_SCAN_WHEN_P2P_WORKING = y
CONFIG_SET_VENDOR_EXTENSION_IE = n CONFIG_SET_VENDOR_EXTENSION_IE = n
CONFIG_VENDOR_GPIO = n CONFIG_VENDOR_GPIO = n
@@ -114,6 +114,7 @@ CONFIG_LOFT_CALIB = n
CONFIG_GKI = n CONFIG_GKI = n
CONFIG_SCHED_SCAN = n CONFIG_SCHED_SCAN = n
CONFIG_TEMP_COMP = n CONFIG_TEMP_COMP = n
CONFIG_TEMP_CONTROL = n
CONFIG_POWER_LIMIT = n CONFIG_POWER_LIMIT = n
CONFIG_EXT_FEM_8800DCDW = n CONFIG_EXT_FEM_8800DCDW = n
# CONFIG_MCC = n for sta and p2p concurrent in same channel. # CONFIG_MCC = n for sta and p2p concurrent in same channel.
@@ -122,6 +123,8 @@ CONFIG_LOAD_BT_PATCH_IN_FDRV = n
CONFIG_DYNAMIC_PWR = n CONFIG_DYNAMIC_PWR = n
CONFIG_DYNAMIC_PERPWR = n CONFIG_DYNAMIC_PERPWR = n
CONFIG_BAND_STEERING = n CONFIG_BAND_STEERING = n
CONFIG_PRBREQ_REPORT = n
CONFIG_SUPPORT_4ADDR = n
#support D80X2 can write rf result to file #support D80X2 can write rf result to file
CONFIG_WRITE_FILE_D80X2 = n CONFIG_WRITE_FILE_D80X2 = n
@@ -189,7 +192,9 @@ $(MODULE_NAME)-y := \
aic_priv_cmd.o \ aic_priv_cmd.o \
aicwf_compat_8800dc.o \ aicwf_compat_8800dc.o \
aicwf_compat_8800d80.o \ aicwf_compat_8800d80.o \
aicwf_compat_8800d80x2.o aicwf_compat_8800d80x2.o \
aicwf_compat_8800d80n.o \
aicwf_compat_8800dln.o
$(MODULE_NAME)-$(CONFIG_BAND_STEERING) += aicwf_manager.o \ $(MODULE_NAME)-$(CONFIG_BAND_STEERING) += aicwf_manager.o \
aicwf_steering.o aicwf_steering.o
@@ -263,6 +268,8 @@ ccflags-$(CONFIG_LOAD_BT_PATCH_IN_FDRV) += -DCONFIG_LOAD_BT_PATCH_IN_FDRV
ccflags-$(CONFIG_DYNAMIC_PWR) += -DCONFIG_DYNAMIC_PWR ccflags-$(CONFIG_DYNAMIC_PWR) += -DCONFIG_DYNAMIC_PWR
ccflags-$(CONFIG_DYNAMIC_PERPWR) += -DCONFIG_DYNAMIC_PERPWR ccflags-$(CONFIG_DYNAMIC_PERPWR) += -DCONFIG_DYNAMIC_PERPWR
ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING
ccflags-$(CONFIG_PRBREQ_REPORT) += -DCONFIG_PRBREQ_REPORT
ccflags-$(CONFIG_SUPPORT_4ADDR) += -DCONFIG_SUPPORT_4ADDR
ccflags-$(CONFIG_WRITE_FILE_D80X2) += -DRF_WRITE_FILE ccflags-$(CONFIG_WRITE_FILE_D80X2) += -DRF_WRITE_FILE
ifeq ($(CONFIG_SDIO_SUPPORT), y) ifeq ($(CONFIG_SDIO_SUPPORT), y)
@@ -338,9 +345,11 @@ ccflags-$(CONFIG_GKI) += -DCONFIG_GKI
ccflags-$(CONFIG_SCHED_SCAN) += -DCONFIG_SCHED_SCAN ccflags-$(CONFIG_SCHED_SCAN) += -DCONFIG_SCHED_SCAN
ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK
ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP
ccflags-$(CONFIG_TEMP_CONTROL) += -DCONFIG_TEMP_CONTROL
ccflags-$(CONFIG_POWER_LIMIT) += -DCONFIG_POWER_LIMIT ccflags-$(CONFIG_POWER_LIMIT) += -DCONFIG_POWER_LIMIT
ccflags-$(CONFIG_EXT_FEM_8800DCDW) += -DCONFIG_EXT_FEM_8800DCDW ccflags-$(CONFIG_EXT_FEM_8800DCDW) += -DCONFIG_EXT_FEM_8800DCDW
ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN
MAKEFLAGS +=-j$(shell nproc)
# Platform support list # Platform support list
CONFIG_PLATFORM_ROCKCHIP ?= n CONFIG_PLATFORM_ROCKCHIP ?= n
@@ -380,11 +389,13 @@ KDIR ?= /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt
endif endif
ifeq ($(CONFIG_PLATFORM_UBUNTU), y) ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
KVER := $(or $(KVER), $(kernelver), $(KERNELRELEASE), $(shell uname -r)) KVER ?= $(shell uname -r)
KDIR ?= /lib/modules/$(KVER)/build KDIR ?= /lib/modules/$(KVER)/build
#KDIR ?= ~/D/Workspace/CyberQuantum/Linux/linux-4.15/
PWD ?= $(shell pwd) PWD ?= $(shell pwd)
MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800 MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/) SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= CROSS_COMPILE ?=
endif endif
+59 -19
View File
@@ -1,23 +1,30 @@
/****************************************************************************** /******************************************************************************
* *
* Copyright(c) 2007 - 2017 Realtek Corporation. * Copyright (C) 2019-2021 Aicsemi Corporation
* *
* This program is free software; you can redistribute it and/or modify it * Licensed under the Apache License, Version 2.0 (the "License");
* under the terms of version 2 of the GNU General Public License as * you may not use this file except in compliance with the License.
* published by the Free Software Foundation. * You may obtain a copy of the License at:
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * http://www.apache.org/licenses/LICENSE-2.0
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* *
*****************************************************************************/ * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#define _AIC_BR_EXT_C_ #define _AIC_BR_EXT_C_
#include <linux/version.h>
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <net/ip.h> #include <net/ip.h>
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
#include <net/ipx.h> #include <net/ipx.h>
#endif
#include <linux/atalk.h> #include <linux/atalk.h>
#include <linux/udp.h> #include <linux/udp.h>
#include <linux/if_pppox.h> #include <linux/if_pppox.h>
@@ -54,6 +61,7 @@
#define MAGIC_CODE_LEN 2 #define MAGIC_CODE_LEN 2
#define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */ #define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */
/*----------------------------------------------------------------- /*-----------------------------------------------------------------
How database records network address: How database records network address:
0 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9 10
@@ -503,7 +511,6 @@ static void __nat25_db_network_insert(struct rwnx_vif *vif,
spin_unlock_bh(&vif->br_ext_lock); spin_unlock_bh(&vif->br_ext_lock);
} }
static void __nat25_db_print(struct rwnx_vif *vif) static void __nat25_db_print(struct rwnx_vif *vif)
{ {
spin_lock_bh(&vif->br_ext_lock); spin_lock_bh(&vif->br_ext_lock);
@@ -746,6 +753,22 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN)); protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN));
#if 0
printk("nat25_db_handle: DA=%02x%02x%02x%02x%02x%02x SA=%02x%02x%02x%02x%02x%02x\n",
skb->data[0],
skb->data[1],
skb->data[2],
skb->data[3],
skb->data[4],
skb->data[5],
skb->data[6],
skb->data[7],
skb->data[8],
skb->data[9],
skb->data[10],
skb->data[11]);
#endif
/*---------------------------------------------------*/ /*---------------------------------------------------*/
/* Handle IP frame */ /* Handle IP frame */
/*---------------------------------------------------*/ /*---------------------------------------------------*/
@@ -849,7 +872,6 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
case NAT25_LOOKUP: { case NAT25_LOOKUP: {
printk("NAT25: Lookup ARP\n"); printk("NAT25: Lookup ARP\n");
arp_ptr += arp->ar_hln; arp_ptr += arp->ar_hln;
sender = (unsigned int *)arp_ptr; sender = (unsigned int *)arp_ptr;
arp_ptr += (arp->ar_hln + arp->ar_pln); arp_ptr += (arp->ar_hln + arp->ar_pln);
@@ -874,23 +896,34 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
/*---------------------------------------------------*/ /*---------------------------------------------------*/
/* Handle IPX and Apple Talk frame */ /* Handle IPX and Apple Talk frame */
/*---------------------------------------------------*/ /*---------------------------------------------------*/
else if ((protocol == __constant_htons(ETH_P_IPX)) || else if (
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
(protocol == __constant_htons(ETH_P_IPX)) ||
#endif
(protocol == __constant_htons(ETH_P_ATALK)) || (protocol == __constant_htons(ETH_P_ATALK)) ||
(protocol == __constant_htons(ETH_P_AARP))) { (protocol == __constant_htons(ETH_P_AARP))) {
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
unsigned char ipx_header[2] = {0xFF, 0xFF}; unsigned char ipx_header[2] = {0xFF, 0xFF};
struct ipxhdr *ipx = NULL; struct ipxhdr *ipx = NULL;
#endif
struct elapaarp *ea = NULL; struct elapaarp *ea = NULL;
struct ddpehdr *ddp = NULL; struct ddpehdr *ddp = NULL;
unsigned char *framePtr = skb->data + ETH_HLEN; unsigned char *framePtr = skb->data + ETH_HLEN;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
if (protocol == __constant_htons(ETH_P_IPX)) { if (protocol == __constant_htons(ETH_P_IPX)) {
printk("NAT25: Protocol=IPX (Ethernet II)\n"); printk("NAT25: Protocol=IPX (Ethernet II)\n");
ipx = (struct ipxhdr *)framePtr; ipx = (struct ipxhdr *)framePtr;
} else { /* if(protocol <= __constant_htons(ETH_FRAME_LEN)) */ } else
#endif
{ /* if(protocol <= __constant_htons(ETH_FRAME_LEN)) */
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
if (!memcmp(ipx_header, framePtr, 2)) { if (!memcmp(ipx_header, framePtr, 2)) {
printk("NAT25: Protocol=IPX (Ethernet 802.3)\n"); printk("NAT25: Protocol=IPX (Ethernet 802.3)\n");
ipx = (struct ipxhdr *)framePtr; ipx = (struct ipxhdr *)framePtr;
} else { } else
#endif
{
unsigned char ipx_8022_type = 0xE0; unsigned char ipx_8022_type = 0xE0;
unsigned char snap_8022_type = 0xAA; unsigned char snap_8022_type = 0xAA;
@@ -900,13 +933,15 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; /* Apple Talk DDP SNAP ID */ unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; /* Apple Talk DDP SNAP ID */
framePtr += 3; /* eliminate the 802.2 header */ framePtr += 3; /* eliminate the 802.2 header */
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
if (!memcmp(ipx_snap_id, framePtr, 5)) { if (!memcmp(ipx_snap_id, framePtr, 5)) {
framePtr += 5; /* eliminate the SNAP header */ framePtr += 5; /* eliminate the SNAP header */
printk("NAT25: Protocol=IPX (Ethernet SNAP)\n"); printk("NAT25: Protocol=IPX (Ethernet SNAP)\n");
ipx = (struct ipxhdr *)framePtr; ipx = (struct ipxhdr *)framePtr;
} else if (!memcmp(aarp_snap_id, framePtr, 5)) { } else
#endif
if (!memcmp(aarp_snap_id, framePtr, 5)) {
framePtr += 5; /* eliminate the SNAP header */ framePtr += 5; /* eliminate the SNAP header */
ea = (struct elapaarp *)framePtr; ea = (struct elapaarp *)framePtr;
@@ -919,7 +954,9 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
framePtr[1], framePtr[2], framePtr[3], framePtr[4]); framePtr[1], framePtr[2], framePtr[3], framePtr[4]);
return -1; return -1;
} }
} else if (*framePtr == ipx_8022_type) { }
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
else if (*framePtr == ipx_8022_type) {
framePtr += 3; /* eliminate the 802.2 header */ framePtr += 3; /* eliminate the 802.2 header */
if (!memcmp(ipx_header, framePtr, 2)) { if (!memcmp(ipx_header, framePtr, 2)) {
@@ -928,9 +965,11 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
} else } else
return -1; return -1;
} }
#endif
} }
} }
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
/* IPX */ /* IPX */
if (ipx != NULL) { if (ipx != NULL) {
switch (method) { switch (method) {
@@ -997,10 +1036,11 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method)
default: default:
return -1; return -1;
} }
} }else
#endif
/* AARP */ /* AARP */
else if (ea != NULL) { if (ea != NULL) {
/* Sanity check fields. */ /* Sanity check fields. */
if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) { if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) {
printk("NAT25: Appletalk AARP Sanity check fail!\n"); printk("NAT25: Appletalk AARP Sanity check fail!\n");
+13 -9
View File
@@ -1,17 +1,21 @@
/****************************************************************************** /******************************************************************************
* *
* Copyright(c) 2007 - 2017 Realtek Corporation. * Copyright (C) 2019-2021 Aicsemi Corporation
* *
* This program is free software; you can redistribute it and/or modify it * Licensed under the Apache License, Version 2.0 (the "License");
* under the terms of version 2 of the GNU General Public License as * you may not use this file except in compliance with the License.
* published by the Free Software Foundation. * You may obtain a copy of the License at:
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * http://www.apache.org/licenses/LICENSE-2.0
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* *
*****************************************************************************/ * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _AIC_BR_EXT_H_ #ifndef _AIC_BR_EXT_H_
#define _AIC_BR_EXT_H_ #define _AIC_BR_EXT_H_
+143 -20
View File
@@ -11,8 +11,6 @@
*/ */
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/vmalloc.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include "rwnx_defs.h" #include "rwnx_defs.h"
#include "rwnx_msg_tx.h" #include "rwnx_msg_tx.h"
@@ -90,6 +88,7 @@ enum {
EXEC_FLASH_OPER, EXEC_FLASH_OPER,
RDWR_PWRADD2X, RDWR_PWRADD2X,
RDWR_EFUSE_PWRADD2X, RDWR_EFUSE_PWRADD2X,
GET_RSSI=0x52,
CHECK_FLASH=0x108, CHECK_FLASH=0x108,
}; };
@@ -342,7 +341,7 @@ static int aic_priv_cmd_set_tx (struct rwnx_hw *rwnx_hw, int argc, char *argv[],
AICWFDBG(LOGINFO, "txparam:%d,%d,%d,%d,%d,%d\n", settx_param.chan, settx_param.bw, AICWFDBG(LOGINFO, "txparam:%d,%d,%d,%d,%d,%d\n", settx_param.chan, settx_param.bw,
settx_param.mode, settx_param.rate, settx_param.length, settx_param.tx_intv_us); settx_param.mode, settx_param.rate, settx_param.length, settx_param.tx_intv_us);
#ifdef CONFIG_POWER_LIMIT #ifdef CONFIG_POWER_LIMIT
r_idx = get_ccode_region(country_code); r_idx = get_ccode_region(rwnx_hw->wiphy->regd->alpha2);
txpwr_loss = &txpwr_loss_tmp; txpwr_loss = &txpwr_loss_tmp;
get_userconfig_txpwr_loss(txpwr_loss); get_userconfig_txpwr_loss(txpwr_loss);
if (txpwr_loss->loss_enable_2g4 == 1) if (txpwr_loss->loss_enable_2g4 == 1)
@@ -797,7 +796,10 @@ static int aic_priv_cmd_rdwr_pwrlvl (struct rwnx_hw *rwnx_hw, int argc, char *ar
AICWFDBG(LOGERROR, "wrong func: %x\n", func); AICWFDBG(LOGERROR, "wrong func: %x\n", func);
return -EINVAL; return -EINVAL;
} }
if((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)){ if((dev->chipid == PRODUCT_ID_AIC8800D81)||
(dev->chipid == PRODUCT_ID_AIC8800D81X2) ||
(dev->chipid == PRODUCT_ID_AIC8800D89X2) ||
(dev->chipid == PRODUCT_ID_AIC8800D80N)) {
memcpy(command, &cfm.rftest_result[0], 6 * 12); memcpy(command, &cfm.rftest_result[0], 6 * 12);
return (6 * 12); return (6 * 12);
} else { } else {
@@ -823,16 +825,19 @@ static int aic_priv_cmd_rdwr_pwrofst (struct rwnx_hw *rwnx_hw, int argc, char *a
if (func == 0) { // read cur if (func == 0) { // read cur
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, 0, NULL, &cfm); rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, 0, NULL, &cfm);
} else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1 } else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1
if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2))) { if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) ||
(dev->chipid == PRODUCT_ID_AIC8800D81X2) ||
(dev->chipid == PRODUCT_ID_AIC8800D89X2) ||
(dev->chipid == PRODUCT_ID_AIC8800D80N))) {
u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16); u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16);
u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16); u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16);
s8_l pwrofst = (u8_l)command_strtoul(argv[4], NULL, 10); s8_l pwrofst = (s8_l)command_strtoul(argv[4], NULL, 10);
u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst}; u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst};
AICWFDBG(LOGINFO, "set pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst); AICWFDBG(LOGINFO, "set pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst);
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm); rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm);
} else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC))) { } else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DLN))) {
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10);
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
AICWFDBG(LOGINFO, "set pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst); AICWFDBG(LOGINFO, "set pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst);
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm); rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm);
@@ -843,9 +848,9 @@ static int aic_priv_cmd_rdwr_pwrofst (struct rwnx_hw *rwnx_hw, int argc, char *a
AICWFDBG(LOGERROR, "wrong func: %x\n", func); AICWFDBG(LOGERROR, "wrong func: %x\n", func);
return -EINVAL; return -EINVAL;
} }
if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW)) { // 3 = 3 (2.4g) if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DLN)) { // 3 = 3 (2.4g)
res_len = 3; res_len = 3;
} else if (dev->chipid == PRODUCT_ID_AIC8800D81) { // 3 * 2 (2.4g) + 3 * 6 (5g) } else if ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D80N)) { // 3 * 2 (2.4g) + 3 * 6 (5g)
res_len = 3 * 3 + 3 * 6; res_len = 3 * 3 + 3 * 6;
} else if ((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // ant0/1 } else if ((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // ant0/1
res_len = ( 3 * 3 + 3 * 6 ) * 2; res_len = ( 3 * 3 + 3 * 6 ) * 2;
@@ -868,7 +873,7 @@ static int aic_priv_cmd_rdwr_pwrofstfine (struct rwnx_hw *rwnx_hw, int argc, cha
} else if (func <= 2) { // write 2.4g/5g pwr ofst } else if (func <= 2) { // write 2.4g/5g pwr ofst
if (argc > 3) { if (argc > 3) {
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10);
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst); AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst);
rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFSTFINE, sizeof(buf), buf, &cfm); rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFSTFINE, sizeof(buf), buf, &cfm);
@@ -930,16 +935,17 @@ static int aic_priv_cmd_rdwr_efuse_pwrofst (struct rwnx_hw *rwnx_hw, int argc, c
if (func == 0) { // read cur if (func == 0) { // read cur
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, 0, NULL, &cfm); rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, 0, NULL, &cfm);
} else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1 } else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1
if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2))) { if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)
|| (dev->chipid == PRODUCT_ID_AIC8800D80N))) {
u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16); u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16);
u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16); u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16);
s8_l pwrofst = (u8_l)command_strtoul(argv[4], NULL, 10); s8_l pwrofst = (s8_l)command_strtoul(argv[4], NULL, 10);
u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst}; u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst};
AICWFDBG(LOGINFO, "set efuse pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst); AICWFDBG(LOGINFO, "set efuse pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst);
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm); rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm);
} else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC))) { } else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DLN))) {
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10);
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
AICWFDBG(LOGINFO, "set efuse pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst); AICWFDBG(LOGINFO, "set efuse pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst);
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm); rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm);
@@ -951,9 +957,9 @@ static int aic_priv_cmd_rdwr_efuse_pwrofst (struct rwnx_hw *rwnx_hw, int argc, c
AICWFDBG(LOGERROR, "wrong func: %x\n", func); AICWFDBG(LOGERROR, "wrong func: %x\n", func);
return -EINVAL; return -EINVAL;
} }
if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW)) { // 6 = 3 (2.4g) * 2 if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DLN)) { // 6 = 3 (2.4g) * 2
res_len = 3 * 2; res_len = 3 * 2;
} else if (dev->chipid == PRODUCT_ID_AIC8800D81) { // 3 * 2 (2.4g) + 3 * 6 (5g) } else if ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D80N)) { // 3 * 2 (2.4g) + 3 * 6 (5g)
res_len = (3 * 3 + 3 * 6) * 2; res_len = (3 * 3 + 3 * 6) * 2;
} else if((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // 3 * 2 (2.4g) *2 + 3 * 6 (5g) *2 } else if((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // 3 * 2 (2.4g) *2 + 3 * 6 (5g) *2
res_len = (3 * 3 + 3 * 6) * 2 * 2; res_len = (3 * 3 + 3 * 6) * 2 * 2;
@@ -976,7 +982,7 @@ static int aic_priv_cmd_rdwr_efuse_pwrofstfine (struct rwnx_hw *rwnx_hw, int arg
} else if (func <= 2) { // write 2.4g/5g pwr ofst } else if (func <= 2) { // write 2.4g/5g pwr ofst
if (argc > 3) { if (argc > 3) {
u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16);
s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10);
u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; u8_l buf[3] = {func, chgrp, (u8_l)pwrofst};
AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst); AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst);
rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFSTFINE, sizeof(buf), buf, &cfm); rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFSTFINE, sizeof(buf), buf, &cfm);
@@ -1273,6 +1279,49 @@ static int aic_priv_cmd_set_pll_test (struct rwnx_hw *rwnx_hw, int argc, char *a
return 0; return 0;
} }
static int aic_priv_cmd_get_txpwr(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
{
s8_l power=0;
power = get_txpwr_max(power);
memcpy(command, &power, 1);
return 1;
}
static int aic_priv_cmd_set_txpwr_loss(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
{
s8_l func;
#ifdef AICWF_SDIO_SUPPORT
struct aic_sdio_dev *dev = g_rwnx_plat->sdiodev;
#endif
#ifdef AICWF_USB_SUPPORT
struct aic_usb_dev *dev = g_rwnx_plat->usbdev;
#endif
if (argc > 1) {
func = (s8_l)command_strtoul(argv[1], NULL, 10);
AICWFDBG(LOGINFO, "set txpwr loss: %d\n", func);
if (dev->chipid == PRODUCT_ID_AIC8800D81 ||
dev->chipid == PRODUCT_ID_AIC8800D80N){
set_txpwr_loss_ofst(func);
rwnx_send_txpwr_lvl_v3_req(dev->rwnx_hw);
}else if(dev->chipid == PRODUCT_ID_AIC8800D81X2 ||
dev->chipid == PRODUCT_ID_AIC8800D89X2){
set_txpwr_loss_ofst(func);
rwnx_send_txpwr_lvl_v4_req(dev->rwnx_hw);
}else if(dev->chipid == PRODUCT_ID_AIC8800DC ||
dev->chipid == PRODUCT_ID_AIC8800DW){
set_txpwr_loss_ofst(func);
rwnx_send_txpwr_lvl_req(dev->rwnx_hw);
}else{
AICWFDBG(LOGINFO, "error:don't support 8800D");
}
} else {
AICWFDBG(LOGERROR, "wrong args\n");
return -EINVAL;
}
return 0;
}
static int aic_priv_cmd_set_ant_mode (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) static int aic_priv_cmd_set_ant_mode (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
{ {
u8_l func = 0; u8_l func = 0;
@@ -1340,6 +1389,12 @@ static int aic_priv_cmd_country_set(struct rwnx_hw *rwnx_hw, int argc,
return -1; return -1;
} }
if (!rwnx_hw->mod_params->custregd) {
AICWFDBG(LOGERROR, "%s: invalid custregd\n", __func__);
return -1;
}
AICWFDBG(LOGINFO, "cmd country_set: %s\n", argv[1]); AICWFDBG(LOGINFO, "cmd country_set: %s\n", argv[1]);
regdomain = getRegdomainFromRwnxDB(rwnx_hw->wiphy, argv[1]); regdomain = getRegdomainFromRwnxDB(rwnx_hw->wiphy, argv[1]);
@@ -1474,6 +1529,58 @@ static int aic_priv_cmd_check_flash(struct rwnx_hw *rwnx_hw, int argc, char *arg
return 8; return 8;
} }
static int aic_priv_cmd_get_rssi(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
{
rwnx_send_rftest_req(rwnx_hw, GET_RSSI, 0, NULL, &cfm);
memcpy(command, &cfm.rftest_result[0], 1);
AICWFDBG(LOGINFO, "get_rssi: %d\n", (char)cfm.rftest_result[0]);
return 1;
}
#ifdef CONFIG_DYNAMIC_PERPWR
static int aic_priv_cmd_set_sta_thd(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
{
int i;
s8_l val;
if (argc < 3) {
AICWFDBG(LOGERROR, "%s: Invalid parameters (argc=%d)\n", __func__, argc);
return -EINVAL;
}
AICWFDBG(LOGDEBUG, "cmd set_sta_thd: %s, %s\n", argv[1], argv[2]);
val = (s8_l)command_strtoul(argv[2], NULL, 10);
struct {
const char *name;
s8_l *target;
size_t name_len;
} thd_map[] = {
{ "rssi_thd_0", &rwnx_hw->pwrth.rssi_thd_0, 10 },
{ "rssi_thd_1", &rwnx_hw->pwrth.rssi_thd_1, 10 },
{ "rssi_thd_2", &rwnx_hw->pwrth.rssi_thd_2, 10 },
{ "pwr_loss_lvl_0", &rwnx_hw->pwrth.pwr_loss_lvl_0, 14 },
{ "pwr_loss_lvl_1", &rwnx_hw->pwrth.pwr_loss_lvl_1, 14 },
{ "pwr_loss_lvl_2", &rwnx_hw->pwrth.pwr_loss_lvl_2, 14 },
{ "pwr_loss_lvl_3", &rwnx_hw->pwrth.pwr_loss_lvl_3, 14 },
};
for (i = 0; i < ARRAY_SIZE(thd_map); i++) {
if (strncmp(argv[1], thd_map[i].name, thd_map[i].name_len) == 0) {
*thd_map[i].target = val;
AICWFDBG(LOGINFO, "%s: %s = %d\n", __func__, thd_map[i].name, val);
return 0;
}
}
AICWFDBG(LOGERROR, "%s: Unknown parameter '%s'\n", __func__, argv[1]);
return -EINVAL;
}
#endif
static int aic_priv_cmd_help (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) static int aic_priv_cmd_help (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command)
{ {
print_help(argc > 0 ? argv[0] : NULL); print_help(argc > 0 ? argv[0] : NULL);
@@ -1575,6 +1682,10 @@ static const struct aic_priv_cmd aic_priv_commands[] = {
"= off usb configure before usb disconnect" }, "= off usb configure before usb disconnect" },
{ "set_pll_test", aic_priv_cmd_set_pll_test, { "set_pll_test", aic_priv_cmd_set_pll_test,
"<func> <freq> <tx_pwr> = use pll test to measure saturation power" }, "<func> <freq> <tx_pwr> = use pll test to measure saturation power" },
{ "get_txpwr", aic_priv_cmd_get_txpwr,
"= get userconfig max txpwr" },
{ "set_txpwr_loss",aic_priv_cmd_set_txpwr_loss,
"<val> = txpwr will change ,val can be negative" },
{ "set_ant", aic_priv_cmd_set_ant_mode, { "set_ant", aic_priv_cmd_set_ant_mode,
"<val> = 0/ant0, 1/ant1, 2/both" }, "<val> = 0/ant0, 1/ant1, 2/both" },
{ "rdwr_bt_efuse_pwrofst", aic_priv_cmd_rdwr_bt_efuse_pwrofst, { "rdwr_bt_efuse_pwrofst", aic_priv_cmd_rdwr_bt_efuse_pwrofst,
@@ -1589,6 +1700,11 @@ static const struct aic_priv_cmd aic_priv_commands[] = {
"a value is added for both 2.4G and 5G to achieve overall power adjustment of the band, write to efuse"}, "a value is added for both 2.4G and 5G to achieve overall power adjustment of the band, write to efuse"},
{"check_flash", aic_priv_cmd_check_flash, {"check_flash", aic_priv_cmd_check_flash,
"check bin crc in flash" }, "check bin crc in flash" },
{"get_rssi", aic_priv_cmd_get_rssi, "get rssi"},
#ifdef CONFIG_DYNAMIC_PERPWR
{"set_sta_thd", aic_priv_cmd_set_sta_thd,
"set per_sta power threshold, (set_sta_thd rssi_thd_0 value; set_sta_thd pwr_loss_lvl_0 value)"},
#endif
//Reserve for new aic_priv_cmd. //Reserve for new aic_priv_cmd.
{ "help", aic_priv_cmd_help, { "help", aic_priv_cmd_help,
@@ -1794,7 +1910,7 @@ int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val)
} }
memset(&cs_info, 0, sizeof(struct aicwf_cs_info)); memset(&cs_info, 0, sizeof(struct aicwf_cs_info));
memcpy(cs_info.countrycode, country_code, 4); memcpy(cs_info.countrycode, vif->rwnx_hw->wiphy->regd->alpha2, 2);
if((sta == NULL) && (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_AP)) { if((sta == NULL) && (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_AP)) {
sta = &vif->rwnx_hw->sta_table[vif->ap.bcmc_index]; sta = &vif->rwnx_hw->sta_table[vif->ap.bcmc_index];
@@ -1940,6 +2056,11 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
strncasecmp(command, "country_set", strlen("country_set"))) { strncasecmp(command, "country_set", strlen("country_set"))) {
skip = strlen(CMD_SET_COUNTRY) + 1; skip = strlen(CMD_SET_COUNTRY) + 1;
country = command + skip; country = command + skip;
if (!vif->rwnx_hw->mod_params->custregd) {
AICWFDBG(LOGERROR, "%s: invalid custregd\n", __func__);
ret = -EINVAL;
goto exit;
}
if (!country || strlen(country) < RWNX_COUNTRY_CODE_LEN) { if (!country || strlen(country) < RWNX_COUNTRY_CODE_LEN) {
AICWFDBG(LOGERROR, "%s: invalid country code\n", __func__); AICWFDBG(LOGERROR, "%s: invalid country code\n", __func__);
ret = -EINVAL; ret = -EINVAL;
@@ -1991,9 +2112,11 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
if(g_rwnx_plat && g_rwnx_plat->usbdev->rwnx_hw){ if(g_rwnx_plat && g_rwnx_plat->usbdev->rwnx_hw){
if (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW || if (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW ||
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DC) || (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DC) ||
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DLN) ||
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81) || (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81) ||
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81X2) || (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81X2) ||
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D89X2)){ (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) ||
(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D80N)){
set_testmode(!testmode); set_testmode(!testmode);
rwnx_send_reboot(g_rwnx_plat->usbdev->rwnx_hw); rwnx_send_reboot(g_rwnx_plat->usbdev->rwnx_hw);
} }
@@ -59,6 +59,14 @@ typedef struct _compat_android_wifi_priv_cmd {
int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd); int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd);
int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val); int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val);
unsigned int command_strtoul(const char *cp, char **endp, unsigned int base);
int str_starts(const char *str, const char *start);
int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter);
#else
void set_mon_chan(struct rwnx_vif *vif, char *parameter);
#endif
#endif /* _AIC_PRIV_CMD_H_ */ #endif /* _AIC_PRIV_CMD_H_ */
@@ -323,6 +323,13 @@ static int aicwf_vendor_subcmd_set_country_code(struct wiphy *wiphy, struct wire
const struct nlattr *iter; const struct nlattr *iter;
struct ieee80211_regdomain *regdomain; struct ieee80211_regdomain *regdomain;
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
if (!rwnx_hw->mod_params->custregd) {
AICWFDBG(LOGERROR, "%s: invalid custregd\n", __func__);
return -EINVAL;
}
nla_for_each_attr(iter, data, len, rem) { nla_for_each_attr(iter, data, len, rem) {
type = nla_type(iter); type = nla_type(iter);
switch (type) { switch (type) {
@@ -2,6 +2,7 @@
#define _AIC_VENDOR_H #define _AIC_VENDOR_H
#include <linux/types.h> #include <linux/types.h>
#include "rwnx_defs.h"
#define GOOGLE_OUI 0x001A11 #define GOOGLE_OUI 0x001A11
#define BRCM_OUI 0x001018 #define BRCM_OUI 0x001018
@@ -342,5 +343,10 @@ typedef struct wl_mkeep_alive_pkt {
u8 data[1]; u8 data[1];
} wl_mkeep_alive_pkt_t; } wl_mkeep_alive_pkt_t;
int aic_dev_start_mkeep_alive(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
u8 mkeep_alive_id, u8 *ip_pkt, u16 ip_pkt_len, u8 *src_mac, u8 *dst_mac, u32 period_msec);
int aic_dev_stop_mkeep_alive(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, u8 mkeep_alive_id);
int aicwf_vendor_init(struct wiphy *wiphy);
#endif /* _AIC_VENDOR_H */ #endif /* _AIC_VENDOR_H */
@@ -1,11 +1,9 @@
#include "rwnx_main.h" #include "rwnx_main.h"
#include "rwnx_msg_tx.h" #include "rwnx_msg_tx.h"
#include "reg_access.h" #include "reg_access.h"
#include "aicwf_compat_8800d80.h"
#define FW_USERCONFIG_NAME_8800D80 "aic_userconfig_8800d80.txt" #define FW_USERCONFIG_NAME_8800D80 "aic_userconfig_8800d80.txt"
#define FW_USERCONFIG_NAME_8800D80_U11 "aic_userconfig_8800d80_u11.txt"
#define FW_USERCONFIG_NAME_8800D80_U11_PRO "aic_userconfig_8800d80_u11_pro.txt"
#define FW_USERCONFIG_NAME_8800D80_U11_CUS "aic_userconfig_8800d80_u11_cus.txt"
#define FW_POWERLIMIT_NAME_8800D80 "aic_powerlimit_8800d80.txt" #define FW_POWERLIMIT_NAME_8800D80 "aic_powerlimit_8800d80.txt"
extern char aic_fw_path[200]; extern char aic_fw_path[200];
@@ -40,20 +38,6 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){
int size; int size;
u32 *dst=NULL; u32 *dst=NULL;
char *filename = FW_USERCONFIG_NAME_8800D80; char *filename = FW_USERCONFIG_NAME_8800D80;
if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS1
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS4
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS7) {
filename = FW_USERCONFIG_NAME_8800D80_U11;
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11_PRO
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS3
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS5
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS6
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS8) {
filename = FW_USERCONFIG_NAME_8800D80_U11_PRO;
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS2) {
filename = FW_USERCONFIG_NAME_8800D80_U11_CUS;
}
#ifndef ANDROID_PLATFORM #ifndef ANDROID_PLATFORM
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80"); sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80");
@@ -102,7 +86,7 @@ int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw)
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
/* parsing the file */ /* parsing the file */
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code); rwnx_plat_powerlimit_parsing((char *)dst, size);
rwnx_release_firmware_common(&dst); rwnx_release_firmware_common(&dst);
@@ -111,3 +95,37 @@ int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw)
} }
#endif #endif
int system_config_8800d80(struct rwnx_hw *rwnx_hw)
{
int ret;
const u32 mem_addr = 0x40500000;
const u32 read_mem_addr = 0x40241014;
struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
if (ret) {
AICWFDBG(LOGINFO, "%x rd fail: %d\n", mem_addr, ret);
return ret;
}
if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL) {
chip_mcu_id = 1;
}
chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16);
AICWFDBG(LOGINFO, "chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id);
if (testmode == 1 && (IS_CHIP_ID_H()))
{
struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, read_mem_addr, &rd_mem_addr_cfm);
AICWFDBG(LOGINFO, "%s 0x%08x=0x%08x\n", __func__, read_mem_addr, rd_mem_addr_cfm.memdata);
if (ret) {
AICWFDBG(LOGERROR, "%x rd fail: %d\n", read_mem_addr, ret);
return ret;
} else {
if (rd_mem_addr_cfm.memdata != 1) {
AICWFDBG(LOGERROR, "check fail: %x\n", rd_mem_addr_cfm.memdata);
return -1;
}
}
}
return 0;
}
@@ -5,5 +5,5 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw);
int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw); int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw);
#endif #endif
int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm); int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
int system_config_8800d80(struct rwnx_hw *rwnx_hw);
@@ -0,0 +1,560 @@
#include "rwnx_main.h"
#include "rwnx_msg_tx.h"
#include "reg_access.h"
#include "rwnx_platform.h"
#include "aicwf_compat_8800d80n.h"
#define FW_USERCONFIG_NAME_8800D80N "aic_userconfig_8800d80n.txt"
#define FW_POWERLIMIT_NAME_8800D80N "aic_powerlimit_8800d80n.txt"
#define RWNX_MAC_FW_RF_BASE_NAME_8800D80N "lmacfw_rf_8800d80n.bin"
#define RWNX_MAC_FW_INITVAR_NAME_8800D80N "fmacfw_initvar_8800d80n.bin"
#define RWNX_MAC_FW_GAINTBL_NAME_8800D80N "fmacfw_gaintbl_8800d80n.bin"
#define RWNX_MAC_FW_CINIT_NAME_8800D80N_U02 "fmacfw_cinit_8800d80n_u02.bin"
#define RWNX_MAC_FW_CALIB_NAME_8800D80N_U02 "fmacfw_calib_8800d80n_u02.bin"
#define RWNX_MAC_PATCH_NAME_8800D80N_U02 "fmacfw_patch_8800d80n_u02.bin"
#define RWNX_MAC_PATCHTBL_NAME_8800D80N_U02 "fmacfw_patch_tbl_8800d80n_u02.bin"
#define RAM_LMAC_FW_RF_ADDR_8800D80N 0x00132C00
#define ROM_FMAC_CINIT_ADDR_8800D80N_U02 0x00133000
#define ROM_FMAC_CALIB_ADDR_8800D80N_U02 0x00138000
#define ROM_FMAC_PATCH_ADDR_8800D80N_U02 0x00188000
#define CHIP_INFO_FLAG_CINIT_BEGIN (0x01U << 12)
#define CHIP_INFO_FLAG_CINIT_DONE (0x01U << 13)
#define PATCH_VAR_FLAG_CALIB_BEGIN (0x01U << 0)
#define PATCH_VAR_FLAG_CALIB_DONE (0x01U << 1)
#define WF_RXGAIN_TBL_IDX_MAX 20
#define WF_RXGAIN_TBL_SIZE 256
#define WF_TXGAIN_TBL_IDX_MAX 21
#define WF_TXGAIN_TBL_SIZE 128
extern char aic_fw_path[200];
int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
char *filename);
int rwnx_plat_bin_fw_upload_2_with_version(struct rwnx_hw *rwnx_hw, u32 fw_addr,
char *filename, char *version_str, int version_size);
int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw,
u32** buffer, const char *filename);
void rwnx_plat_userconfig_parsing(char *buffer, int size);
void rwnx_release_firmware_common(u32** buffer);
extern int get_adap_test(void);
typedef u32 (*array2_tbl_t)[2];
typedef u32 (*array3_tbl_t)[3];
u32 syscfg_tbl_masked_8800d80n[][3] = {
// {Address, mask, value}
#if DEF_PATCH_METHOD_VER_1 // moved to cinit.bin
// anareg1, u01 only
{0x4050201C, (0x7 << 0), (0x7 << 0)},
// pmic_pmu_init
{0x70001024, ((0x1F << 0) | (0x1 << 14) | (0x1 << 15)),
((0x08 << 0) | (0x1 << 14) | (0x1 << 15))},
{0x70001044, (0xF << 20), (0x4 << 20)},
{0x70001084, ((0xF << 23) | (0x1 << 27) | (0x1 << 31)),
((0x4 << 23) | (0x0 << 27) | (0x1 << 31))},
{0x70002118, (0x3 << 0), (0x0 << 0)},
{0x7000211C, (0x3 << 2), (0x0 << 2)},
{0x700021D8, (0x3 << 4), (0x0 << 4)},
{0x700021D0, ((0x1 << 5) | (0x1 << 6)),
((0x1 << 5) | (0x1 << 6))},
#if defined(CONFIG_VRF_DCDC_MODE)
{0x70001000, (0x1 << 0), (0x1 << 0)},
#else
{0x70001000, (0x1 << 0), (0x0 << 0)},
#endif
// cm_rf_init
{0x4050500C, ((0x7 << 27) | (0x3 << 30)),
((0x3 << 27) | (0x3 << 30))},
{0x40505008, ((0x3 << 11) | (0xF << 15)),
((0x1 << 11) | (0x4 << 15))},
#endif
{0x00000000, 0x00000000, 0x00000000}, // last one
};
u32 patch_tbl_wifisetting_8800d80n[][2] =
{
//{0x00b8, 0x00009d08 | (0x01U << 13)}, // debug_mask, bit13: CALIB_BIT
};
//adap test
u32 adaptivity_patch_tbl_8800d80n[][2] = {
};
u32 patch_tbl_rf_func_8800d80n[][2] =
{
};
extern int testmode;
extern u8 chip_id;
extern u8 chip_mcu_id;
void system_config_8800d80n(struct rwnx_hw *rwnx_hw)
{
int syscfg_num;
array3_tbl_t p_syscfg_msk_tbl;
int ret, cnt;
const u32 mem_addr = 0x40500000;
struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
if (ret) {
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
return;
}
chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16);
//printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL) {
chip_mcu_id = 1;
}
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm);
if (ret) {
AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret);
return;
}
chip_sub_id = (u8)(rd_mem_addr_cfm.memdata);
//printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
AICWFDBG(LOGINFO, "chip_id=%x, chip_sub_id=%x\n", chip_id, chip_sub_id);
syscfg_num = sizeof(syscfg_tbl_masked_8800d80n) / sizeof(u32) / 3;
p_syscfg_msk_tbl = syscfg_tbl_masked_8800d80n;
for (cnt = 0; cnt < syscfg_num; cnt++) {
if (p_syscfg_msk_tbl[cnt][0] == 0x00000000) {
break;
}
ret = rwnx_send_dbg_mem_mask_write_req(rwnx_hw,
p_syscfg_msk_tbl[cnt][0], p_syscfg_msk_tbl[cnt][1], p_syscfg_msk_tbl[cnt][2]);
if (ret) {
AICWFDBG(LOGERROR, "%x mask write fail: %d\n", p_syscfg_msk_tbl[cnt][0], ret);
return;
}
}
}
int aicwf_plat_patch_load_8800d80n(struct rwnx_hw *rwnx_hw)
{
int ret = 0;
char patch_ver_str[128];
//wifi patch
ret = rwnx_plat_bin_fw_upload_2_with_version(rwnx_hw,
ROM_FMAC_PATCH_ADDR_8800D80N_U02, RWNX_MAC_PATCH_NAME_8800D80N_U02, patch_ver_str, sizeof(patch_ver_str));
if (ret) {
AICWFDBG(LOGERROR, "load patch bin fail: %d\n", ret);
return ret;
}
AICWFDBG(LOGINFO, "PatchVer: %s", patch_ver_str);
return ret;
}
int aicwf_plat_patch_table_load_8800d80n(struct rwnx_hw *rwnx_hw)
{
int err = 0;
unsigned int i, size;
u32 *dst = NULL;
char *filename = RWNX_MAC_PATCHTBL_NAME_8800D80N_U02;
/* Copy the file on the Embedded side */
AICWFDBG(LOGINFO, "### Upload %s \n", filename);
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
if (!dst) {
AICWFDBG(LOGERROR, "No such file or directory\n");
return -1;
}
if (size <= 0) {
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
dst = NULL;
err = -1;
}
AICWFDBG(LOGINFO, "tbl size = %d \n", size);
if (!err) {
for (i = 0; i < (size / 4); i += 2) {
if ((dst[i] == 0x0) || (dst[i] == 0xFFFFFFFF)) {
break; // end of tbl
}
AICWFDBG(LOGERROR, "patch_tbl: %x %x\n", dst[i], dst[i+1]);
err = rwnx_send_dbg_mem_write_req(rwnx_hw, dst[i], dst[i+1]);
}
if (err) {
AICWFDBG(LOGERROR, "tbl bin upload fail: %x, err:%d\r\n", dst[i], err);
}
}
if (dst) {
rwnx_release_firmware_common(&dst);
}
return err;
}
void aicwf_patch_config_8800d80n(struct rwnx_hw *rwnx_hw)
{
#ifdef CONFIG_ROM_PATCH_EN
int ret = 0;
int cnt = 0;
//adap test
int adap_test = 0;
int adap_patch_num = 0;
adap_test = get_adap_test();
//adap test
if (testmode == 0) {
const u32 cfg_base = 0x10170;
struct dbg_mem_read_cfm cfm;
//int i;
u32 wifisetting_cfg_addr;
u32 agc_cfg_addr;
u32 txgain_cfg_24g_addr, txgain_cfg_5g_addr;
u32 jump_tbl_addr = 0;
u32 patch_tbl_wifisetting_num = sizeof(patch_tbl_wifisetting_8800d80n)/sizeof(u32)/2;
//u32 jump_tbl_size = 0;
//u32 patch_tbl_func_num = 0;
//array2_tbl_t jump_tbl_base = NULL;
//array2_tbl_t patch_tbl_func_base = NULL;
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm))) {
AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", cfg_base, ret);
}
wifisetting_cfg_addr = cfm.memdata;
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 4, &cfm))) {
AICWFDBG(LOGERROR, "jump_tbl base[0x%x] rd fail: %d\n", cfg_base + 4, ret);
}
jump_tbl_addr = cfm.memdata;
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x10, &cfm))) {
AICWFDBG(LOGERROR, "agc_cfg base[0x%x] rd fail: %d\n", cfg_base + 0xc, ret);
}
agc_cfg_addr = cfm.memdata;
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) {
AICWFDBG(LOGERROR, "txgain_cfg_24g base[0x%x] rd fail: %d\n", cfg_base + 0x10, ret);
}
txgain_cfg_24g_addr = cfm.memdata;
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x18, &cfm))) {
AICWFDBG(LOGERROR, "txgain_cfg_5g base[0x%x] rd fail: %d\n", cfg_base + 0x10, ret);
}
txgain_cfg_5g_addr = cfm.memdata;
AICWFDBG(LOGINFO, "wifisetting_cfg_addr=%x, jump_tbl_addr=%x, agc_cfg_addr=%x, txgain_cfg_24g_addr=%x, txgain_cfg_5g_addr=%x\n",
wifisetting_cfg_addr, jump_tbl_addr, agc_cfg_addr, txgain_cfg_24g_addr, txgain_cfg_5g_addr);
for (cnt = 0; cnt < patch_tbl_wifisetting_num; cnt++) {
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + patch_tbl_wifisetting_8800d80n[cnt][0], patch_tbl_wifisetting_8800d80n[cnt][1]))) {
AICWFDBG(LOGERROR, "wifisetting %x write fail\n", patch_tbl_wifisetting_8800d80n[cnt][0]);
}
}
//adap test
if (adap_test) {
adap_patch_num = sizeof(adaptivity_patch_tbl_8800d80n)/sizeof(u32)/2;
for(cnt = 0; cnt < adap_patch_num; cnt++)
{
if((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + adaptivity_patch_tbl_8800d80n[cnt][0], adaptivity_patch_tbl_8800d80n[cnt][1]))) {
AICWFDBG(LOGERROR, "%x write fail\n", wifisetting_cfg_addr + adaptivity_patch_tbl_8800d80n[cnt][0]);
}
}
}
//adap test
#if DEF_PATCH_METHOD_VER_1
ret = aicwf_plat_initvar_load_8800d80n(rwnx_hw, txgain_cfg_24g_addr);
if (ret) {
AICWFDBG(LOGERROR, "initvar load fail: %d\n", ret);
return;
}
#endif
}
else {
u32 patch_tbl_rf_func_num = sizeof(patch_tbl_rf_func_8800d80n)/sizeof(u32)/2;
for (cnt = 0; cnt < patch_tbl_rf_func_num; cnt++) {
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_rf_func_8800d80n[cnt][0], patch_tbl_rf_func_8800d80n[cnt][1]))) {
AICWFDBG(LOGERROR, "patch_tbl_rf_func %x write fail\n", patch_tbl_rf_func_8800d80n[cnt][0]);
}
}
}
#endif
}
int aicwf_plat_rftest_load_8800d80n(struct rwnx_hw *rwnx_hw)
{
int ret = 0;
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, RAM_LMAC_FW_RF_ADDR_8800D80N, RWNX_MAC_FW_RF_BASE_NAME_8800D80N);
if (ret) {
AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret);
return ret;
}
return ret;
}
int aicwf_plat_rftest_exec_8800d80n(struct rwnx_hw *rwnx_hw)
{
int ret = 0;
uint32_t fw_addr, boot_type;
uint32_t rst_hdlr_addr = RAM_LMAC_FW_RF_ADDR_8800D80N + 0x04;
uint32_t rst_hdlr_val;
struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, rst_hdlr_addr, &rd_mem_addr_cfm);
if (ret) {
AICWFDBG(LOGERROR, "%x rd fail: %d\n", rst_hdlr_addr, ret);
return ret;
}
rst_hdlr_val = rd_mem_addr_cfm.memdata;
if ((rst_hdlr_val & ~0x03FF) == RAM_LMAC_FW_RF_ADDR_8800D80N) {
AICWFDBG(LOGINFO, "rftest loaded, hdlr=%x\n", rst_hdlr_val);
}
/* fw start */
fw_addr = RAM_LMAC_FW_RF_ADDR_8800D80N;
boot_type = HOST_START_APP_AUTO;
AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type);
ret = rwnx_send_dbg_start_app_req(rwnx_hw, fw_addr, boot_type);
if (ret) {
AICWFDBG(LOGERROR, "start app fail: %d\n", ret);
return ret;
}
return ret;
}
#if DEF_PATCH_METHOD_VER_1
int aicwf_plat_initvar_load_8800d80n(struct rwnx_hw *rwnx_hw, u32 var_base_addr)
{
int ret = 0;
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, var_base_addr, RWNX_MAC_FW_INITVAR_NAME_8800D80N);
if (ret) {
AICWFDBG(LOGERROR, "load initvar bin fail: %d\n", ret);
return ret;
}
return ret;
}
int aicwf_plat_gain_table_load_8800d80n(struct rwnx_hw *rwnx_hw)
{
int size, desired_size, idx, ret;
u32 *dst=NULL;
u8_l *tbl_base;
char *filename = RWNX_MAC_FW_GAINTBL_NAME_8800D80N;
AICWFDBG(LOGINFO, "gaintbl file path:%s\n", filename);
/* load file */
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
desired_size = WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE + WF_TXGAIN_TBL_IDX_MAX * WF_TXGAIN_TBL_SIZE;
if ((size <= 0) || (size != desired_size)) {
AICWFDBG(LOGERROR, "wrong size of firmware file, desired=%d, size=%d\n", desired_size, size);
if (dst) {
rwnx_release_firmware_common(&dst);
dst = NULL;
}
return 0;
}
/* Copy the file on the Embedded side */
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
/* RX gain */
tbl_base = (u8_l *)dst;
for (idx = 0; idx < WF_RXGAIN_TBL_IDX_MAX; idx++) {
u16_l ofst = idx * 16;
u8_l *tbl_ptr = tbl_base + idx * WF_RXGAIN_TBL_SIZE;
ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 0, tbl_ptr, WF_RXGAIN_TBL_SIZE);
if (ret) {
AICWFDBG(LOGERROR, "rx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst);
break;
}
}
/* TX gain */
tbl_base = (u8_l *)dst + WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE;
for (idx = 0; idx < WF_TXGAIN_TBL_IDX_MAX; idx++) {
u16_l ofst = idx * 16;
u8_l *tbl_ptr = tbl_base + idx * WF_TXGAIN_TBL_SIZE;
ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 2, tbl_ptr, WF_TXGAIN_TBL_SIZE);
if (ret) {
AICWFDBG(LOGERROR, "tx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst);
break;
}
}
rwnx_release_firmware_common(&dst);
AICWFDBG(LOGINFO, "gaintbl download complete\n\n");
return 0;
}
#endif
#if DEF_PATCH_METHOD_VER_2
int aicwf_plat_cinit_exec_8800d80n(struct rwnx_hw *rwnx_hw)
{
int ret = 0;
uint32_t fw_addr, boot_type;
uint32_t mem_addr = 0x40500184;
uint32_t mem_val;
struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
if (ret) {
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
return ret;
}
mem_val = rd_mem_addr_cfm.memdata;
if (mem_val & CHIP_INFO_FLAG_CINIT_BEGIN) {
// wait done
while (!(mem_val & CHIP_INFO_FLAG_CINIT_DONE)) {
AICWFDBG(LOGINFO, "cinit rd chipinfo=%x\n", mem_val);
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
if (ret) {
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
return ret;
}
mem_val = rd_mem_addr_cfm.memdata;
}
AICWFDBG(LOGINFO, "cinit executed, chipinfo=%x\n", mem_val);
return ret;
}
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_CINIT_ADDR_8800D80N_U02, RWNX_MAC_FW_CINIT_NAME_8800D80N_U02);
if (ret) {
AICWFDBG(LOGERROR, "load cinit bin fail: %d\n", ret);
return ret;
}
/* fw start */
fw_addr = ROM_FMAC_CINIT_ADDR_8800D80N_U02 + 0x0009;
boot_type = HOST_START_APP_FNCALL;
AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type);
ret = rwnx_send_dbg_start_app_req(rwnx_hw, fw_addr, boot_type);
if (ret) {
AICWFDBG(LOGERROR, "start app fail: %d\n", ret);
return ret;
}
return ret;
}
int aicwf_plat_calib_exec_8800d80n(struct rwnx_hw *rwnx_hw)
{
int ret = 0;
uint32_t fw_addr, boot_type;
uint32_t patch_var_flags_addr = ROM_FMAC_PATCH_ADDR_8800D80N_U02 + 0x08;
uint32_t patch_var_flags_val;
struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, patch_var_flags_addr, &rd_mem_addr_cfm);
if (ret) {
AICWFDBG(LOGERROR, "%x rd fail: %d\n", patch_var_flags_addr, ret);
return ret;
}
patch_var_flags_val = rd_mem_addr_cfm.memdata;
if (patch_var_flags_val & (PATCH_VAR_FLAG_CALIB_BEGIN | PATCH_VAR_FLAG_CALIB_DONE)) {
AICWFDBG(LOGINFO, "calib executed, var_flags=%x\n", patch_var_flags_val);
return ret;
}
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_CALIB_ADDR_8800D80N_U02, RWNX_MAC_FW_CALIB_NAME_8800D80N_U02);
if (ret) {
AICWFDBG(LOGERROR, "load calib bin fail: %d\n", ret);
return ret;
}
/* fw start */
fw_addr = ROM_FMAC_CALIB_ADDR_8800D80N_U02 + 0x0009;
boot_type = HOST_START_APP_FNCALL;
AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type);
ret = rwnx_send_dbg_start_app_req(rwnx_hw, fw_addr, boot_type);
if (ret) {
AICWFDBG(LOGERROR, "start app fail: %d\n", ret);
return ret;
}
return ret;
}
#endif
int aicwf_set_rf_config_8800d80n(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm)
{
int ret = 0;
if ((ret = rwnx_send_txpwr_lvl_v3_req(rwnx_hw))) {
return -1;
}
if ((ret = rwnx_send_txpwr_lvl_adj_req(rwnx_hw))) {
return -1;
}
if ((ret = rwnx_send_txpwr_ofst2x_req(rwnx_hw))) {
return -1;
}
#if DEF_PATCH_METHOD_VER_1
if (testmode == FW_NORMAL_MODE) {
aicwf_plat_gain_table_load_8800d80n(rwnx_hw);
}
#endif
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
return -1;
}
return 0 ;
}
int rwnx_plat_userconfig_load_8800d80n(struct rwnx_hw *rwnx_hw){
int size;
u32 *dst=NULL;
char *filename = FW_USERCONFIG_NAME_8800D80N;
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
/* load file */
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
if (size <= 0) {
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
dst = NULL;
return 0;
}
/* Copy the file on the Embedded side */
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
rwnx_plat_userconfig_parsing((char *)dst, size);
rwnx_release_firmware_common(&dst);
AICWFDBG(LOGINFO, "userconfig download complete\n\n");
return 0;
}
#ifdef CONFIG_POWER_LIMIT
extern char country_code[];
int rwnx_plat_powerlimit_load_8800d80n(struct rwnx_hw *rwnx_hw)
{
int size;
u32 *dst=NULL;
char *filename = FW_POWERLIMIT_NAME_8800D80N;
AICWFDBG(LOGINFO, "powerlimit file path:%s \r\n", filename);
/* load file */
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
if (size <= 0) {
AICWFDBG(LOGERROR, "wrong size of cfg file\n");
dst = NULL;
return 0;
}
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
/* parsing the file */
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code);
rwnx_release_firmware_common(&dst);
AICWFDBG(LOGINFO, "powerlimit download complete\n\n");
return 0;
}
#endif
@@ -0,0 +1,32 @@
#include <linux/types.h>
#define DEF_PATCH_METHOD_VER_1 0 // deprecated
#define DEF_PATCH_METHOD_VER_2 1 // in used
void system_config_8800d80n(struct rwnx_hw *rwnx_hw);
int aicwf_plat_patch_load_8800d80n(struct rwnx_hw *rwnx_hw);
int aicwf_plat_patch_table_load_8800d80n(struct rwnx_hw *rwnx_hw);
void aicwf_patch_config_8800d80n(struct rwnx_hw *rwnx_hw);
int aicwf_plat_rftest_load_8800d80n(struct rwnx_hw *rwnx_hw);
int aicwf_plat_rftest_exec_8800d80n(struct rwnx_hw *rwnx_hw);
#if DEF_PATCH_METHOD_VER_1
int aicwf_plat_initvar_load_8800d80n(struct rwnx_hw *rwnx_hw, u32 var_base_addr);
int aicwf_plat_gain_table_load_8800d80n(struct rwnx_hw *rwnx_hw);
#endif
#if DEF_PATCH_METHOD_VER_2
int aicwf_plat_cinit_exec_8800d80n(struct rwnx_hw *rwnx_hw);
int aicwf_plat_calib_exec_8800d80n(struct rwnx_hw *rwnx_hw);
#endif
int rwnx_plat_userconfig_load_8800d80n(struct rwnx_hw *rwnx_hw);
#ifdef CONFIG_POWER_LIMIT
int rwnx_plat_powerlimit_load_8800d80n(struct rwnx_hw *rwnx_hw);
#endif
int aicwf_set_rf_config_8800d80n(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
@@ -1,6 +1,7 @@
#include "rwnx_main.h" #include "rwnx_main.h"
#include "rwnx_msg_tx.h" #include "rwnx_msg_tx.h"
#include "reg_access.h" #include "reg_access.h"
#include "aicwf_compat_8800d80x2.h"
#define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt" #define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt"
#define FW_POWERLIMIT_NAME_8800D80X2 "aic_powerlimit_8800d80x2.txt" #define FW_POWERLIMIT_NAME_8800D80X2 "aic_powerlimit_8800d80x2.txt"
@@ -86,7 +87,7 @@ int rwnx_plat_powerlimit_load_8800d80x2(struct rwnx_hw *rwnx_hw)
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
/* parsing the file */ /* parsing the file */
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code); rwnx_plat_powerlimit_parsing((char *)dst, size);
rwnx_release_firmware_common(&dst); rwnx_release_firmware_common(&dst);
+266 -173
View File
@@ -45,8 +45,6 @@
#define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt" #define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt"
#define FW_POWERLIMIT_NAME_8800DC "aic_powerlimit_8800dc.txt" #define FW_POWERLIMIT_NAME_8800DC "aic_powerlimit_8800dc.txt"
#define FW_POWERLIMIT_NAME_8800DW "aic_powerlimit_8800dw.txt" #define FW_POWERLIMIT_NAME_8800DW "aic_powerlimit_8800dw.txt"
#define FW_USERCONFIG_NAME_8800DW_W311 "aic_userconfig_8800dw_w311.txt"
#define FW_USERCONFIG_NAME_8800DW_U2 "aic_userconfig_8800dw_u2.txt"
#ifdef CONFIG_LOAD_BT_PATCH_IN_FDRV #ifdef CONFIG_LOAD_BT_PATCH_IN_FDRV
enum aicbt_patch_table_type { enum aicbt_patch_table_type {
@@ -169,6 +167,7 @@ u32 syscfg_tbl_masked_8800dc[][3] = {
{0x700010A0, (0x1 << 11), (0x1 << 11)}, {0x700010A0, (0x1 << 11), (0x1 << 11)},
{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, {0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
{0x70001038, (0x1 << 8), (0x1 << 8)}, {0x70001038, (0x1 << 8), (0x1 << 8)},
{0x70001084, (0x3 << 13), (0x0 << 13)},
{0x70001094, (0x3 << 2), (0x0 << 2)}, {0x70001094, (0x3 << 2), (0x0 << 2)},
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
{0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)), {0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)),
@@ -186,6 +185,7 @@ u32 syscfg_tbl_masked_8800dc[][3] = {
{0x700010A0, (0x1 << 11), (0x1 << 11)}, {0x700010A0, (0x1 << 11), (0x1 << 11)},
{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, {0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
{0x70001038, (0x1 << 8), (0x1 << 8)}, {0x70001038, (0x1 << 8), (0x1 << 8)},
{0x70001084, (0x3 << 13), (0x0 << 13)},
{0x70001094, (0x3 << 2), (0x0 << 2)}, {0x70001094, (0x3 << 2), (0x0 << 2)},
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
{0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)), {0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)),
@@ -211,6 +211,7 @@ u32 syscfg_tbl_masked_8800dc_h[][3] = {
{0x700010A0, (0x1 << 11), (0x1 << 11)}, {0x700010A0, (0x1 << 11), (0x1 << 11)},
//{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, //{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
{0x70001038, (0x1 << 8), (0x1 << 8)}, {0x70001038, (0x1 << 8), (0x1 << 8)},
{0x70001084, (0x3 << 13), (0x0 << 13)},
{0x70001094, (0x3 << 2), (0x0 << 2)}, {0x70001094, (0x3 << 2), (0x0 << 2)},
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
#if defined(CONFIG_VRF_DCDC_MODE) #if defined(CONFIG_VRF_DCDC_MODE)
@@ -242,7 +243,6 @@ u32 syscfg_tbl_8800dc[][2] = {
u32 patch_tbl_wifisetting[][2] = u32 patch_tbl_wifisetting[][2] =
{ {
{0x0004, 0x00020010}, //wdt_reboot_type, wdt_period_sec
#if !defined(CONFIG_FPGA_VERIFICATION) #if !defined(CONFIG_FPGA_VERIFICATION)
{0x0090, 0x0013FC00}, //rx_ringbuf_start2 {0x0090, 0x0013FC00}, //rx_ringbuf_start2
#endif #endif
@@ -251,10 +251,9 @@ u32 patch_tbl_wifisetting[][2] =
{0x0120, 0x140A0100}, //usb agg tx params(total cnt, aggr cnt, out en, global out nak) {0x0120, 0x140A0100}, //usb agg tx params(total cnt, aggr cnt, out en, global out nak)
#endif //CONFIG_USB_TX_AGGR #endif //CONFIG_USB_TX_AGGR
{0x00b0, 0xAD180100}, {0x00b0, 0xAD180100},
#ifdef CONFIG_BAND_STEERING #ifdef CONFIG_PRBREQ_REPORT
{0x0138, 0x00010a00}, //apm probe resp offload en {0x0138, 0x00010a00}, //apm probe resp offload en
#endif #endif
{0x0084, 0x00000040},
}; };
u32 jump_tbl[][2] = u32 jump_tbl[][2] =
@@ -1872,104 +1871,104 @@ const uint32_t txgain_map_femkct[96] =
const uint32_t txgain_map_femkct_h[96] = const uint32_t txgain_map_femkct_h[96] =
{ {
//11b //11b
0x00ffd872,//15 0x00ffd86c,//15
0x00ffd880,//16 0x00ffd879,//16
0x00ffd972,//17 0x00ffd96c,//17
0x00ffd980,//18 0x00ffd979,//18
0x00ffd990,//19 0x00ffd988,//19
0x00ffda72,//20 0x00ffda6c,//20
0x00ffda80,//21 0x00ffda79,//21
0x00ffdb72,//22 0x00ffdb6c,//22
0x00ffdb80,//23 0x00ffdb79,//23
0x00ffdc72,//24 0x00ffdc6c,//24
0x00ffdc80,//25 0x00ffdc79,//25
0x00ffdd72,//26 0x00ffdd6c,//26
0x00ffdd80,//27 0x00ffdd79,//27
0x00ffde72,//28 0x00ffde6c,//28
0x00ffde80,//29 0x00ffde79,//29
0x00ffdf72,//30 0x00ffdf6c,//30
0x00ffd072,//-1 0x00ffd06c,//-1
0x00ffd072,//0 0x00ffd06c,//0
0x00ffd080,//1 0x00ffd079,//1
0x00ffd172,//2 0x00ffd16c,//2
0x00ffd180,//3 0x00ffd179,//3
0x00ffd272,//4 0x00ffd26c,//4
0x00ffd280,//5 0x00ffd279,//5
0x00ffd379,//6 0x00ffd372,//6
0x00ffd46d,//7 0x00ffd467,//7
0x00ffd479,//8 0x00ffd472,//8
0x00ffd572,//9 0x00ffd56c,//9
0x00ffd580,//10 0x00ffd579,//10
0x00ffd672,//11 0x00ffd66c,//11
0x00ffd680,//12 0x00ffd679,//12
0x00ffd772,//13 0x00ffd76c,//13
0x00ffd780,//14 0x00ffd779,//14
//high //high
0x00ffc880,//11 0x00ffc879,//11
0x00ffc972,//12 0x00ffc96c,//12
0x00ffc980,//13 0x00ffc979,//13
0x00ffca72,//14 0x00ffca6c,//14
0x00ffca80,//15 0x00ffca79,//15
0x00ffcb72,//16 0x00ffcb6c,//16
0x00ffcb80,//17 0x00ffcb79,//17
0x00ffcc72,//18 0x00ffcc6c,//18
0x00ffcc80,//19 0x00ffcc79,//19
0x00ffcc90,//20 0x00ffcc88,//20
0x00ffcd72,//21 0x00ffcd6c,//21
0x00ffcd80,//22 0x00ffcd79,//22
0x00ffce72,//23 0x00ffce6c,//23
0x00ffce80,//24 0x00ffce79,//24
0x00ffcf72,//25 0x00ffcf6c,//25
0x00ffcf80,//26 0x00ffcf79,//26
0x00ffc080,//-5 0x00ffc079,//-5
0x00ffc172,//-4 0x00ffc16c,//-4
0x00ffc180,//-3 0x00ffc179,//-3
0x00ffc272,//-2 0x00ffc26c,//-2
0x00ffc280,//-1 0x00ffc279,//-1
0x00ffc372,//0 0x00ffc36c,//0
0x00ffc380,//1 0x00ffc379,//1
0x00ffc472,//2 0x00ffc46c,//2
0x00ffc480,//3 0x00ffc479,//3
0x00ffc572,//4 0x00ffc56c,//4
0x00ffc580,//5 0x00ffc579,//5
0x00ffc672,//6 0x00ffc66c,//6
0x00ffc680,//7 0x00ffc679,//7
0x00ffc772,//8 0x00ffc76c,//8
0x00ffc780,//9 0x00ffc779,//9
0x00ffc872,//10 0x00ffc86c,//10
//low //low
0x00ffc880,//11 0x00ffc879,//11
0x00ffc972,//12 0x00ffc96c,//12
0x00ffc980,//13 0x00ffc979,//13
0x00ffca72,//14 0x00ffca6c,//14
0x00ffca80,//15 0x00ffca79,//15
0x00ffcb72,//16 0x00ffcb6c,//16
0x00ffcb80,//17 0x00ffcb79,//17
0x00ffcc72,//18 0x00ffcc6c,//18
0x00ffcc80,//19 0x00ffcc79,//19
0x00ffcc90,//20 0x00ffcc88,//20
0x00ffcd72,//21 0x00ffcd6c,//21
0x00ffcd80,//22 0x00ffcd79,//22
0x00ffce72,//23 0x00ffce6c,//23
0x00ffce80,//24 0x00ffce79,//24
0x00ffcf72,//25 0x00ffcf6c,//25
0x00ffcf80,//26 0x00ffcf79,//26
0x00ffc080,//-5 0x00ffc079,//-5
0x00ffc172,//-4 0x00ffc16c,//-4
0x00ffc180,//-3 0x00ffc179,//-3
0x00ffc272,//-2 0x00ffc26c,//-2
0x00ffc280,//-1 0x00ffc279,//-1
0x00ffc372,//0 0x00ffc36c,//0
0x00ffc380,//1 0x00ffc379,//1
0x00ffc472,//2 0x00ffc46c,//2
0x00ffc480,//3 0x00ffc479,//3
0x00ffc572,//4 0x00ffc56c,//4
0x00ffc580,//5 0x00ffc579,//5
0x00ffc672,//6 0x00ffc66c,//6
0x00ffc680,//7 0x00ffc679,//7
0x00ffc772,//8 0x00ffc76c,//8
0x00ffc780,//9 0x00ffc779,//9
0x00ffc872,//10 0x00ffc86c,//10
}; };
#endif #endif
@@ -2205,6 +2204,141 @@ uint32_t wifi_txgain_table_24g_1_8800dcdw_femkct[32] = {
}; };
#endif #endif
#ifdef CONFIG_5M10M
u32 wifi_rxgain_table_24g_dcdw_5m[64] = {
0x82f282d1,//index 0
0x9591a200,
0x80808419,
0x000000f0,
0x42f282d1,//index 1
0x95923400,
0x80808419,
0x000000f0,
0x22f282d1,//index 2
0x9592c600,
0x80808419,
0x000000f0,
0x02f282d1,//index 3
0x9591a200,
0x80808419,
0x000000f0,
0x06f282d1,//index 4
0x9591a200,
0x80808419,
0x000000f0,
0x0ef282d1,//index 5
0x9591a200,
0x80808419,
0x000000f0,
0x0ef282d3,//index 6
0x95923400,
0x80808419,
0x000000f0,
0x0ef282d7,//index 7
0x9595a200,
0x80808419,
0x000000f0,
0x02f282d2,//index 8
0x95951000,
0x80808419,
0x000000f0,
0x02f282f4,//index 9
0x95951000,
0x80808419,
0x000000f0,
0x02f282e6,//index 10
0x9595a200,
0x80808419,
0x000000f0,
0x02f282e6,//index 11
0x9599a200,
0x80808419,
0x000000f0,
0x02f282e6,//index 12
0x959da200,
0x80808419,
0x000000f0,
0x02f282e6,//index 13
0x959f5800,
0x80808419,
0x000000f0,
0x06f282e6,//index 14
0x959f5800,
0x80808419,
0x000000f0,
0x0ef282e6,//index 15
0x959f5800,
0x80808419,
0x000000f0
};
u32 wifi_rxgain_table_24g_dcdw_10m[64] = {
0x82f282d1,//index 0
0x9591a320,
0x80808419,
0x000000f0,
0x42f282d1,//index 1
0x95923520,
0x80808419,
0x000000f0,
0x22f282d1,//index 2
0x9592c720,
0x80808419,
0x000000f0,
0x02f282d1,//index 3
0x9591a320,
0x80808419,
0x000000f0,
0x06f282d1,//index 4
0x9591a320,
0x80808419,
0x000000f0,
0x0ef282d1,//index 5
0x9591a320,
0x80808419,
0x000000f0,
0x0ef282d3,//index 6
0x95923520,
0x80808419,
0x000000f0,
0x0ef282d7,//index 7
0x9595a320,
0x80808419,
0x000000f0,
0x02f282d2,//index 8
0x95951120,
0x80808419,
0x000000f0,
0x02f282f4,//index 9
0x95951120,
0x80808419,
0x000000f0,
0x02f282e6,//index 10
0x9595a320,
0x80808419,
0x000000f0,
0x02f282e6,//index 11
0x9599a320,
0x80808419,
0x000000f0,
0x02f282e6,//index 12
0x959da320,
0x80808419,
0x000000f0,
0x02f282e6,//index 13
0x959f5920,
0x80808419,
0x000000f0,
0x06f282e6,//index 14
0x959f5920,
0x80808419,
0x000000f0,
0x0ef282e6,//index 15
0x959f5920,
0x80808419,
0x000000f0
};
#endif
u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = { u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = {
0x82f282d1,//index 0 0x82f282d1,//index 0
0x9591a324, 0x9591a324,
@@ -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))) if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32, 0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256)))
return -1; return -1;
#ifdef CONFIG_5M10M
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 0, (u8_l *)wifi_rxgain_table_24g_dcdw_5m, 256)))
return -1;
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 48, 0, (u8_l *)wifi_rxgain_table_24g_dcdw_10m, 256)))
return -1;
#endif
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) { if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
return -1; return -1;
} }
@@ -3038,54 +3178,35 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out)
uint32_t misc_ram_addr; uint32_t misc_ram_addr;
uint32_t ram_base_addr, ram_word_cnt; uint32_t ram_base_addr, ram_word_cnt;
uint32_t bit_mask[4]; uint32_t bit_mask[4];
uint32_t dpd_info_read_addr = 0xfe004;
uint32_t boot_argc_read_addr = 0x1220f0;
uint32_t flash_size_mem_addr = 0x40038030;
uint8_t flash_size = 0;
int i; int i;
if (valid_out) { if (valid_out) {
*valid_out = 0; *valid_out = 0;
} }
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;
}
printk("boot argc %x\n", cfm.memdata);
if (cfm.memdata & 0x10) {
*valid_out = 1;
return ret;
}
if (chip_mcu_id) {
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, flash_size_mem_addr, &cfm);
if (ret) {
AICWFDBG(LOGERROR, "flash size[0x%x] rd fail: %d\n", flash_size_mem_addr, ret);
return ret;
}
flash_size = cfm.memdata & 0xff;
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) { if (testmode == FW_RFTEST_MODE) {
uint32_t vect1 = 0;
uint32_t vect2 = 0;
cfg_base = RAM_LMAC_FW_ADDR + 0x0004;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm);
if (ret) {
AICWFDBG(LOGERROR, "cfg_base:%x vcet1 rd fail: %d\n", cfg_base, ret);
return ret;
}
vect1 = cfm.memdata;
if ((vect1 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) {
AICWFDBG(LOGERROR, "vect1 invalid: %x\n", vect1);
return ret;
}
cfg_base = RAM_LMAC_FW_ADDR + 0x0008;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm);
if (ret) {
AICWFDBG(LOGERROR, "cfg_base:%x vcet2 rd fail: %d\n", cfg_base, ret);
return ret;
}
vect2 = cfm.memdata;
if ((vect2 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) {
AICWFDBG(LOGERROR, "vect2 invalid: %x\n", vect2);
return ret;
}
cfg_base = RAM_LMAC_FW_ADDR + 0x0164; cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
} }
// init misc ram // init misc ram
@@ -3114,7 +3235,6 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out)
*valid_out = 1; *valid_out = 1;
} }
} }
}
return ret; return ret;
} }
@@ -3511,17 +3631,6 @@ int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){
int size; int size;
u32 *dst=NULL; u32 *dst=NULL;
char *filename = FW_USERCONFIG_NAME_8800DW; 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); 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 */ /* Copy the file on the Embedded side */
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code); rwnx_plat_powerlimit_parsing((char *)dst, size);
rwnx_release_firmware_common(&dst); 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; array3_tbl_t p_syscfg_msk_tbl;
int ret, cnt; int ret, cnt;
const u32 mem_addr = 0x40500000; const u32 mem_addr = 0x40500000;
const u32 cache_mem_addr = 0x40100020;
struct dbg_mem_read_cfm rd_mem_addr_cfm; struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm); ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
@@ -3644,21 +3752,6 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){
chip_mcu_id = 1; chip_mcu_id = 1;
} }
if (chip_mcu_id) {
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cache_mem_addr, &rd_mem_addr_cfm);
if (ret) {
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
return;
}
rd_mem_addr_cfm.memdata |= 0x01;
ret = rwnx_send_dbg_mem_write_req(rwnx_hw, cache_mem_addr, rd_mem_addr_cfm.memdata);
if (ret) {
AICWFDBG(LOGERROR, "%x write fail: %d\n", cache_mem_addr, ret);
return;
}
}
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm); ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm);
if (ret) { if (ret) {
AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret); AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret);
@@ -60,3 +60,6 @@ int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw);
int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id); int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id);
#endif #endif
void system_config_8800dc(struct rwnx_hw *rwnx_hw); void system_config_8800dc(struct rwnx_hw *rwnx_hw);
int aicwf_patch_var_config_8800dc(struct rwnx_hw *rwnx_hw);
int set_bbpll_config(struct rwnx_hw *rwnx_hw);
@@ -0,0 +1,330 @@
#include "rwnx_main.h"
#include "rwnx_msg_tx.h"
#include "reg_access.h"
#include "rwnx_platform.h"
#include "aicwf_compat_8800dln.h"
#define FW_USERCONFIG_NAME_8800DLN "aic_userconfig_8800dln.txt"
#define FW_POWERLIMIT_NAME_8800DLN "aic_powerlimit_8800dln.txt"
#define RWNX_MAC_FW_RF_BASE_NAME_8800DLN "lmacfw_rf_8800dln.bin"
#define RWNX_MAC_FW_INITVAR_NAME_8800DLN "fmacfw_initvar_8800dln.bin"
#define RWNX_MAC_FW_GAINTBL_NAME_8800DLN "fmacfw_gaintbl_8800dln.bin"
#define WF_RXGAIN_TBL_IDX_MAX 20
#define WF_RXGAIN_TBL_SIZE 256
#define WF_TXGAIN_TBL_IDX_MAX 21
#define WF_TXGAIN_TBL_SIZE 128
extern char aic_fw_path[200];
int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
char *filename);
int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw,
u32** buffer, const char *filename);
void rwnx_plat_userconfig_parsing(char *buffer, int size);
void rwnx_release_firmware_common(u32** buffer);
extern int get_adap_test(void);
typedef u32 (*array2_tbl_t)[2];
typedef u32 (*array3_tbl_t)[3];
u32 syscfg_tbl_masked_8800dln[][3] = {
// {Address, mask, value}
{0x00000000, 0x00000000, 0x00000000}, // last one
};
u32 patch_tbl_wifisetting_8800dln[][2] =
{
};
//adap test
u32 adaptivity_patch_tbl_8800dln[][2] = {
};
u32 patch_tbl_rf_func_8800dln[][2] =
{
};
extern int testmode;
extern u8 chip_id;
extern u8 chip_mcu_id;
void system_config_8800dln(struct rwnx_hw *rwnx_hw)
{
int syscfg_num;
array3_tbl_t p_syscfg_msk_tbl;
int ret, cnt;
const u32 mem_addr = 0x40500000;
struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
if (ret) {
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
return;
}
chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16);
//printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL) {
chip_mcu_id = 1;
}
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm);
if (ret) {
AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret);
return;
}
chip_sub_id = (u8)(rd_mem_addr_cfm.memdata);
//printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
AICWFDBG(LOGINFO, "chip_id=%x, chip_sub_id=%x\n", chip_id, chip_sub_id);
syscfg_num = sizeof(syscfg_tbl_masked_8800dln) / sizeof(u32) / 3;
p_syscfg_msk_tbl = syscfg_tbl_masked_8800dln;
for (cnt = 0; cnt < syscfg_num; cnt++) {
if (p_syscfg_msk_tbl[cnt][0] == 0x00000000) {
break;
}
ret = rwnx_send_dbg_mem_mask_write_req(rwnx_hw,
p_syscfg_msk_tbl[cnt][0], p_syscfg_msk_tbl[cnt][1], p_syscfg_msk_tbl[cnt][2]);
if (ret) {
AICWFDBG(LOGERROR, "%x mask write fail: %d\n", p_syscfg_msk_tbl[cnt][0], ret);
return;
}
}
}
void aicwf_patch_config_8800dln(struct rwnx_hw *rwnx_hw)
{
#ifdef CONFIG_ROM_PATCH_EN
int ret = 0;
int cnt = 0;
//adap test
int adap_test = 0;
int adap_patch_num = 0;
adap_test = get_adap_test();
//adap test
if (testmode == 0) {
const u32 cfg_base = 0x8150;
struct dbg_mem_read_cfm cfm;
u32 wifisetting_cfg_addr;
u32 agc_cfg_addr;
u32 txgain_cfg_24g_addr;
u32 jump_tbl_addr = 0;
u32 patch_tbl_num;
//array2_tbl_t jump_tbl_base = NULL;
array2_tbl_t patch_tbl_base = NULL;
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm))) {
AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", cfg_base, ret);
}
wifisetting_cfg_addr = cfm.memdata;
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 4, &cfm))) {
AICWFDBG(LOGERROR, "jump_tbl base[0x%x] rd fail: %d\n", cfg_base + 4, ret);
}
jump_tbl_addr = cfm.memdata;
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x10, &cfm))) {
AICWFDBG(LOGERROR, "agc_cfg base[0x%x] rd fail: %d\n", cfg_base + 0xc, ret);
}
agc_cfg_addr = cfm.memdata;
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) {
AICWFDBG(LOGERROR, "txgain_cfg_24g base[0x%x] rd fail: %d\n", cfg_base + 0x10, ret);
}
txgain_cfg_24g_addr = cfm.memdata;
AICWFDBG(LOGINFO, "wifisetting_cfg_addr=%x, jump_tbl_addr=%x, agc_cfg_addr=%x, txgain_cfg_24g_addr=%x\n",
wifisetting_cfg_addr, jump_tbl_addr, agc_cfg_addr, txgain_cfg_24g_addr);
patch_tbl_num = sizeof(patch_tbl_wifisetting_8800dln)/sizeof(u32)/2;
patch_tbl_base = patch_tbl_wifisetting_8800dln;
for (cnt = 0; cnt < patch_tbl_num; cnt++) {
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + patch_tbl_base[cnt][0], patch_tbl_base[cnt][1]))) {
AICWFDBG(LOGERROR, "wifisetting %x write fail\n", patch_tbl_base[cnt][0]);
}
}
//adap test
if (adap_test) {
adap_patch_num = sizeof(adaptivity_patch_tbl_8800dln)/sizeof(u32)/2;
patch_tbl_base = adaptivity_patch_tbl_8800dln;
for(cnt = 0; cnt < adap_patch_num; cnt++)
{
if((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + patch_tbl_base[cnt][0], patch_tbl_base[cnt][1]))) {
AICWFDBG(LOGERROR, "%x write fail\n", wifisetting_cfg_addr + patch_tbl_base[cnt][0]);
}
}
}
//adap test
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, txgain_cfg_24g_addr, RWNX_MAC_FW_INITVAR_NAME_8800DLN);
if (ret) {
AICWFDBG(LOGINFO, "load initvar bin fail: %d\n", ret);
return;
}
}
else {
u32 patch_tbl_rf_func_num = sizeof(patch_tbl_rf_func_8800dln)/sizeof(u32)/2;
for (cnt = 0; cnt < patch_tbl_rf_func_num; cnt++) {
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_rf_func_8800dln[cnt][0], patch_tbl_rf_func_8800dln[cnt][1]))) {
AICWFDBG(LOGERROR, "patch_tbl_rf_func %x write fail\n", patch_tbl_rf_func_8800dln[cnt][0]);
}
}
}
#endif
}
int aicwf_plat_rftest_load_8800dln(struct rwnx_hw *rwnx_hw)
{
int ret = 0;
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, RAM_LMAC_FW_ADDR, RWNX_MAC_FW_RF_BASE_NAME_8800DLN);
if (ret) {
AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret);
return ret;
}
return ret;
}
int aicwf_plat_gain_table_load_8800dln(struct rwnx_hw *rwnx_hw)
{
int size, desired_size, idx, ret;
u32 *dst=NULL;
u8_l *tbl_base;
char *filename = RWNX_MAC_FW_GAINTBL_NAME_8800DLN;
AICWFDBG(LOGINFO, "gaintbl file path:%s\n", filename);
/* load file */
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
desired_size = WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE + WF_TXGAIN_TBL_IDX_MAX * WF_TXGAIN_TBL_SIZE;
if ((size <= 0) || (size != desired_size)) {
AICWFDBG(LOGERROR, "wrong size of firmware file, desired=%d, size=%d\n", desired_size, size);
if (dst) {
rwnx_release_firmware_common(&dst);
dst = NULL;
}
return 0;
}
/* Copy the file on the Embedded side */
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
/* RX gain */
tbl_base = (u8_l *)dst;
for (idx = 0; idx < WF_RXGAIN_TBL_IDX_MAX; idx++) {
u16_l ofst = idx * 16;
u8_l *tbl_ptr = tbl_base + idx * WF_RXGAIN_TBL_SIZE;
ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 0, tbl_ptr, WF_RXGAIN_TBL_SIZE);
if (ret) {
AICWFDBG(LOGERROR, "rx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst);
break;
}
}
/* TX gain */
tbl_base = (u8_l *)dst + WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE;
for (idx = 0; idx < WF_TXGAIN_TBL_IDX_MAX; idx++) {
u16_l ofst = idx * 16;
u8_l *tbl_ptr = tbl_base + idx * WF_TXGAIN_TBL_SIZE;
ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 2, tbl_ptr, WF_TXGAIN_TBL_SIZE);
if (ret) {
AICWFDBG(LOGERROR, "tx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst);
break;
}
}
rwnx_release_firmware_common(&dst);
AICWFDBG(LOGINFO, "gaintbl download complete\n\n");
return 0;
}
int aicwf_set_rf_config_8800dln(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm)
{
int ret = 0;
if ((ret = rwnx_send_txpwr_lvl_req(rwnx_hw))) {
return -1;
}
if ((ret = rwnx_send_txpwr_lvl_adj_v2_req(rwnx_hw))) {
return -1;
}
if ((ret = rwnx_send_txpwr_ofst2x_v3_req(rwnx_hw))) {
return -1;
}
if (testmode == FW_NORMAL_MODE) {
aicwf_plat_gain_table_load_8800dln(rwnx_hw);
}
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
return -1;
}
return 0 ;
}
int rwnx_plat_userconfig_load_8800dln(struct rwnx_hw *rwnx_hw){
int size;
u32 *dst=NULL;
char *filename = FW_USERCONFIG_NAME_8800DLN;
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
/* load file */
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
if (size <= 0) {
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
dst = NULL;
return 0;
}
/* Copy the file on the Embedded side */
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
rwnx_plat_userconfig_parsing((char *)dst, size);
rwnx_release_firmware_common(&dst);
AICWFDBG(LOGINFO, "userconfig download complete\n\n");
return 0;
}
#ifdef CONFIG_POWER_LIMIT
extern char country_code[];
int rwnx_plat_powerlimit_load_8800dln(struct rwnx_hw *rwnx_hw)
{
int size;
u32 *dst=NULL;
char *filename = FW_POWERLIMIT_NAME_8800DLN;
AICWFDBG(LOGINFO, "powerlimit file path:%s \r\n", filename);
/* load file */
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
if (size <= 0) {
AICWFDBG(LOGERROR, "wrong size of cfg file\n");
dst = NULL;
return 0;
}
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
/* parsing the file */
rwnx_plat_powerlimit_parsing((char *)dst, size);
rwnx_release_firmware_common(&dst);
AICWFDBG(LOGINFO, "powerlimit download complete\n\n");
return 0;
}
#endif
@@ -0,0 +1,17 @@
#include <linux/types.h>
void system_config_8800dln(struct rwnx_hw *rwnx_hw);
void aicwf_patch_config_8800dln(struct rwnx_hw *rwnx_hw);
int aicwf_plat_rftest_load_8800dln(struct rwnx_hw *rwnx_hw);
int aicwf_plat_gain_table_load_8800dln(struct rwnx_hw *rwnx_hw);
int rwnx_plat_userconfig_load_8800dln(struct rwnx_hw *rwnx_hw);
#ifdef CONFIG_POWER_LIMIT
int rwnx_plat_powerlimit_load_8800dln(struct rwnx_hw *rwnx_hw);
#endif
int aicwf_set_rf_config_8800dln(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
+1 -5
View File
@@ -1,5 +1,3 @@
#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__ #define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__
@@ -11,6 +9,7 @@
#define LOGDEBUG 0x0008 #define LOGDEBUG 0x0008
#define LOGDATA 0x0010 #define LOGDATA 0x0010
#define LOGSTEER 0x0020 #define LOGSTEER 0x0020
#define LOGFW 0x0200
extern int aicwf_dbg_level; extern int aicwf_dbg_level;
void rwnx_data_dump(char* tag, void* data, unsigned long len); void rwnx_data_dump(char* tag, void* data, unsigned long len);
@@ -48,6 +47,3 @@ do { \
} \ } \
} while (0) } while (0)
#endif #endif
+4 -4
View File
@@ -49,7 +49,7 @@ static int freq_to_channel(int freq)
} else if (freq >= FREQ_6G_MIN && freq <= FREQ_6G_MAX) { } else if (freq >= FREQ_6G_MIN && freq <= FREQ_6G_MAX) {
return (freq - 5950) / 5; return (freq - 5950) / 5;
} else { } else {
AICWFDBG(LOGERROR, MANAGER_STR"aic Unsupported frequency: %d MHz\n", freq); AICWFDBG(LOGERROR, MANAGER_STR"Unsupported frequency: %d MHz\n", freq);
return -1; return -1;
} }
} }
@@ -91,7 +91,7 @@ void aicwf_nl_recv_msg(struct sk_buff *skb)
rwnx_hook = nl_hook[band][ssid]; rwnx_hook = nl_hook[band][ssid];
if (!rwnx_hook) { if (!rwnx_hook) {
AICWFDBG(LOGSTEER, MANAGER_STR"%s, !rwnx_hook, %d,%d\n", __func__, band, ssid); AICWFDBG(LOGSTEER, MANAGER_STR"%s, search for the next rwnx_hook, %d,%d\n", __func__, band, ssid);
continue; continue;
} }
if (rwnx_vif == NULL || rwnx_vif->up == false) { if (rwnx_vif == NULL || rwnx_vif->up == false) {
@@ -144,7 +144,7 @@ void aicwf_nl_recv_msg(struct sk_buff *skb)
rwnx_hook = nl_hook[band][ssid]; rwnx_hook = nl_hook[band][ssid];
if (!rwnx_hook) { if (!rwnx_hook) {
AICWFDBG(LOGSTEER, MANAGER_STR"rwnx_hook is null p1.\n"); //AICWFDBG(LOGSTEER, MANAGER_STR"Not this driver's msg p1.\n");
break; break;
} }
if (rwnx_vif == NULL || rwnx_vif->up == false) { if (rwnx_vif == NULL || rwnx_vif->up == false) {
@@ -185,7 +185,7 @@ void aicwf_nl_recv_msg(struct sk_buff *skb)
rwnx_hook = nl_hook[band][ssid]; rwnx_hook = nl_hook[band][ssid];
if (!rwnx_hook) { if (!rwnx_hook) {
AICWFDBG(LOGERROR, MANAGER_STR"rwnx_hook is null p2.\n"); //AICWFDBG(LOGERROR, MANAGER_STR"Not this driver's msg p2.\n");
break; break;
} }
if (rwnx_vif == NULL || rwnx_vif->up == false) { if (rwnx_vif == NULL || rwnx_vif->up == false) {
+2 -9
View File
@@ -527,11 +527,7 @@ static void aicwf_sdio_bus_stop(struct device *dev)
aicwf_sdio_pwrctl_timer(sdiodev, 0); aicwf_sdio_pwrctl_timer(sdiodev, 0);
if(timer_pending(&sdiodev->rwnx_hw->p2p_alive_timer)){ if(timer_pending(&sdiodev->rwnx_hw->p2p_alive_timer)){
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
ret = timer_delete(&sdiodev->rwnx_hw->p2p_alive_timer);}
#else
ret = del_timer(&sdiodev->rwnx_hw->p2p_alive_timer);} ret = del_timer(&sdiodev->rwnx_hw->p2p_alive_timer);}
#endif
sdio_dbg("%s\n",__func__); sdio_dbg("%s\n",__func__);
if (sdiodev->pwrctl_tsk) { if (sdiodev->pwrctl_tsk) {
complete(&sdiodev->pwrctrl_trgg); complete(&sdiodev->pwrctrl_trgg);
@@ -1001,7 +997,8 @@ static void aicwf_sdio_bus_pwrctl(struct timer_list *t)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data; struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0) #elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
struct aic_sdio_dev *sdiodev = timer_container_of(sdiodev, t, timer);#else struct aic_sdio_dev *sdiodev = timer_container_of(sdiodev, t, timer);
#else
struct aic_sdio_dev *sdiodev = from_timer(sdiodev, t, timer); struct aic_sdio_dev *sdiodev = from_timer(sdiodev, t, timer);
#endif #endif
@@ -1085,11 +1082,7 @@ void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration)
spin_lock_bh(&sdiodev->pwrctl_lock); spin_lock_bh(&sdiodev->pwrctl_lock);
if (!duration) { if (!duration) {
if (timer_pending(&sdiodev->timer)) if (timer_pending(&sdiodev->timer))
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
timer_delete_sync(&sdiodev->timer);
#else
del_timer_sync(&sdiodev->timer); del_timer_sync(&sdiodev->timer);
#endif
} else { } else {
sdiodev->active_duration = duration; sdiodev->active_duration = duration;
timeout = msecs_to_jiffies(sdiodev->active_duration); timeout = msecs_to_jiffies(sdiodev->active_duration);
@@ -8,6 +8,7 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/version.h>
#define TCP_ACK_NUM 32 #define TCP_ACK_NUM 32
@@ -89,4 +90,29 @@ int filter_send_tcp_ack(struct rwnx_hw *priv, struct msg_buf *msgbuf,unsigned ch
void filter_rx_tcp_ack(struct rwnx_hw *priv,unsigned char *buf, unsigned plen); void filter_rx_tcp_ack(struct rwnx_hw *priv,unsigned char *buf, unsigned plen);
void move_tcpack_msg(struct rwnx_hw *priv, struct msg_buf * msg); void move_tcpack_msg(struct rwnx_hw *priv, struct msg_buf * msg);
void intf_tcp_drop_msg(struct rwnx_hw *priv, struct msg_buf *msg);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
void tcp_ack_timeout(unsigned long data);
#else
void tcp_ack_timeout(struct timer_list *t);
#endif
int tcp_check_quick_ack(unsigned char *buf, struct tcp_ack_msg *msg);
int tcp_check_ack(unsigned char *buf,
struct tcp_ack_msg *msg,
unsigned short *win_scale);
int tcp_ack_match(struct tcp_ack_manage *ack_m, struct tcp_ack_msg *ack_msg);
void tcp_ack_update(struct tcp_ack_manage *ack_m);
int tcp_ack_alloc_index(struct tcp_ack_manage *ack_m);
int tcp_ack_handle(struct msg_buf *new_msgbuf,
struct tcp_ack_manage *ack_m,
struct tcp_ack_info *ack_info,
struct tcp_ack_msg *ack_msg,
int type);
int tcp_ack_handle_new(struct msg_buf *new_msgbuf,
struct tcp_ack_manage *ack_m,
struct tcp_ack_info *ack_info,
struct tcp_ack_msg *ack_msg,
int type);
#endif #endif
+3 -2
View File
@@ -23,7 +23,7 @@
#define DATA_BUF_MAX 2048 #define DATA_BUF_MAX 2048
#define TXPKT_BLOCKSIZE 512 #define TXPKT_BLOCKSIZE 512
#define MAX_AGGR_TXPKT_LEN (1536*64) #define MAX_AGGR_TXPKT_LEN (1536*64)
#define CMD_TX_TIMEOUT 2000 #define CMD_TX_TIMEOUT 5000
#define TX_ALIGNMENT 4 #define TX_ALIGNMENT 4
#ifdef CONFIG_USB_TX_AGGR #ifdef CONFIG_USB_TX_AGGR
@@ -155,7 +155,7 @@ struct aicwf_tx_priv {
#define DEFRAG_MAX_WAIT 40 //100 #define DEFRAG_MAX_WAIT 40 //100
#ifdef AICWF_RX_REORDER #ifdef AICWF_RX_REORDER
#define MAX_REORD_RXFRAME 250 #define MAX_REORD_RXFRAME 250
#define REORDER_UPDATE_TIME 500//50 #define REORDER_UPDATE_TIME 50
#define AICWF_REORDER_WINSIZE 64 #define AICWF_REORDER_WINSIZE 64
//SN_LESS(a, b) a-b<0 is ture //SN_LESS(a, b) a-b<0 is ture
#define SN_LESS(a, b) (((a-b)&0x800)!=0) #define SN_LESS(a, b) (((a-b)&0x800)!=0)
@@ -307,6 +307,7 @@ void aicwf_rxframe_queue_init_2(struct rx_frame_queue *pq, int max_len);
void rxbuff_free(struct rx_buff *rxbuff); void rxbuff_free(struct rx_buff *rxbuff);
struct rx_buff *rxbuff_dequeue(struct rx_frame_queue *pq); struct rx_buff *rxbuff_dequeue(struct rx_frame_queue *pq);
bool aicwf_rxbuff_enqueue(struct device *dev, struct rx_frame_queue *rxq, struct rx_buff *pkt); bool aicwf_rxbuff_enqueue(struct device *dev, struct rx_frame_queue *rxq, struct rx_buff *pkt);
struct rx_buff *rxbuff_queue_penq(struct rx_frame_queue *pq, struct rx_buff *p);
extern struct aicwf_rx_buff_list aic_rx_buff_list; extern struct aicwf_rx_buff_list aic_rx_buff_list;
#endif #endif
+53 -33
View File
@@ -155,22 +155,24 @@ static void aicwf_usb_msg_rx_buf_put(struct aic_usb_dev *usb_dev, struct aicwf_u
} }
#endif #endif
void rwnx_stop_sta_all_queues(struct rwnx_sta *sta, struct rwnx_hw *rwnx_hw) void rwnx_stop_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw)
{ {
u8 tid; u8 tid;
struct rwnx_txq *txq; struct rwnx_txq *txq;
struct rwnx_sta *sta_tmp = (struct rwnx_sta *)sta;
for(tid=0; tid<8; tid++) { for(tid=0; tid<8; tid++) {
txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); txq = rwnx_txq_sta_get(sta_tmp, tid, rwnx_hw);
netif_stop_subqueue(txq->ndev, txq->ndev_idx); netif_stop_subqueue(txq->ndev, txq->ndev_idx);
} }
} }
void rwnx_wake_sta_all_queues(struct rwnx_sta *sta, struct rwnx_hw *rwnx_hw) void rwnx_wake_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw)
{ {
u8 tid; u8 tid;
struct rwnx_txq *txq; struct rwnx_txq *txq;
struct rwnx_sta *sta_tmp = (struct rwnx_sta *)sta;
for(tid=0; tid<8; tid++) { for(tid=0; tid<8; tid++) {
txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); txq = rwnx_txq_sta_get(sta_tmp, tid, rwnx_hw);
netif_wake_subqueue(txq->ndev, txq->ndev_idx); netif_wake_subqueue(txq->ndev, txq->ndev_idx);
} }
} }
@@ -200,7 +202,7 @@ static void usb_txc_sta_flowctrl(struct aicwf_usb_buf *usb_buf, struct aic_usb_d
usb_dev->rwnx_hw->sta_flowctrl[sta_idx].flowctrl) { usb_dev->rwnx_hw->sta_flowctrl[sta_idx].flowctrl) {
//AICWFDBG(LOGDEBUG, "sta 0x%x:0x%x, %d pending %d, wake\n", sta->mac_addr[4], sta->mac_addr[5], sta->sta_idx, atomic_read(&usb_dev->rwnx_hw->sta_flowctrl[sta_idx].tx_pending_cnt)); //AICWFDBG(LOGDEBUG, "sta 0x%x:0x%x, %d pending %d, wake\n", sta->mac_addr[4], sta->mac_addr[5], sta->sta_idx, atomic_read(&usb_dev->rwnx_hw->sta_flowctrl[sta_idx].tx_pending_cnt));
if(!usb_dev->tbusy) if(!usb_dev->tbusy)
rwnx_wake_sta_all_queues(sta, usb_dev->rwnx_hw); rwnx_wake_sta_all_queues((void *)sta, usb_dev->rwnx_hw);
usb_dev->rwnx_hw->sta_flowctrl[sta_idx].flowctrl = 0; usb_dev->rwnx_hw->sta_flowctrl[sta_idx].flowctrl = 0;
} }
} }
@@ -781,7 +783,7 @@ static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev,
aicwf_prealloc_rxbuff_free(rx_buff, &usb_dev->rx_priv->rxbuff_lock); aicwf_prealloc_rxbuff_free(rx_buff, &usb_dev->rx_priv->rxbuff_lock);
aicwf_usb_rx_buf_put(usb_dev, usb_buf); aicwf_usb_rx_buf_put(usb_dev, usb_buf);
msleep(100); mdelay(100);
return -1; return -1;
}else{ }else{
atomic_inc(&rx_urb_cnt); atomic_inc(&rx_urb_cnt);
@@ -840,7 +842,7 @@ static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev,
usb_buf->skb = NULL; usb_buf->skb = NULL;
aicwf_usb_rx_buf_put(usb_dev, usb_buf); aicwf_usb_rx_buf_put(usb_dev, usb_buf);
msleep(100); mdelay(100);
return -1; return -1;
}else{ }else{
atomic_inc(&rx_urb_cnt); atomic_inc(&rx_urb_cnt);
@@ -913,7 +915,7 @@ static int aicwf_usb_submit_msg_rx_urb(struct aic_usb_dev *usb_dev,
usb_buf->skb = NULL; usb_buf->skb = NULL;
aicwf_usb_msg_rx_buf_put(usb_dev, usb_buf); aicwf_usb_msg_rx_buf_put(usb_dev, usb_buf);
msleep(100); mdelay(100);
} }
return 0; return 0;
} }
@@ -1214,9 +1216,6 @@ fail:
usb_buf->skb = NULL; usb_buf->skb = NULL;
aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf, aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf,
&usb_dev->tx_free_count, &usb_dev->tx_free_lock); &usb_dev->tx_free_count, &usb_dev->tx_free_lock);
if (ret == -ENODEV) {
break;
}
#endif #endif
} }
} }
@@ -1677,7 +1676,7 @@ static void usb_tx_flow_ctrl(struct rwnx_txhdr *txhdr, struct aic_usb_dev *usb_d
rwnx_hw->sta_flowctrl[sta_idx].flowctrl) { rwnx_hw->sta_flowctrl[sta_idx].flowctrl) {
//AICWFDBG(LOGDEBUG, "sta 0x%x:0x%x, %d pending %d, stop\n", sta->mac_addr[4], sta->mac_addr[5], sta->sta_idx, atomic_read(&rwnx_hw->sta_flowctrl[sta_idx].tx_pending_cnt)); //AICWFDBG(LOGDEBUG, "sta 0x%x:0x%x, %d pending %d, stop\n", sta->mac_addr[4], sta->mac_addr[5], sta->sta_idx, atomic_read(&rwnx_hw->sta_flowctrl[sta_idx].tx_pending_cnt));
if(!usb_dev->tbusy) if(!usb_dev->tbusy)
rwnx_stop_sta_all_queues(sta, usb_dev->rwnx_hw); rwnx_stop_sta_all_queues((void *)sta, usb_dev->rwnx_hw);
rwnx_hw->sta_flowctrl[sta_idx].flowctrl = 1; rwnx_hw->sta_flowctrl[sta_idx].flowctrl = 1;
} }
} }
@@ -1903,15 +1902,14 @@ static int aicwf_usb_bus_start(struct device *dev)
aicwf_usb_state_change(usb_dev, USB_UP_ST); aicwf_usb_state_change(usb_dev, USB_UP_ST);
usb_dev->rx_prepare_ready = false; usb_dev->rx_prepare_ready = false;
aicwf_usb_rx_prepare(usb_dev);
aicwf_usb_tx_prepare(usb_dev); aicwf_usb_tx_prepare(usb_dev);
#ifdef CONFIG_USB_MSG_IN_EP #ifdef CONFIG_USB_MSG_IN_EP
if(usb_dev->msg_in_pipe){ if(usb_dev->msg_in_pipe){
aicwf_usb_msg_rx_prepare(usb_dev); aicwf_usb_msg_rx_prepare(usb_dev);
} else {
aicwf_usb_rx_prepare(usb_dev);
} }
#endif #endif
if(!usb_dev->msg_in_pipe && !usb_dev->rx_prepare_ready){ if(!usb_dev->rx_prepare_ready){
AICWFDBG(LOGERROR, "%s rx prepare fail\r\n", __func__); AICWFDBG(LOGERROR, "%s rx prepare fail\r\n", __func__);
return -1; return -1;
}else{ }else{
@@ -2154,12 +2152,13 @@ static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *in
AICWFDBG(LOGERROR, "AIC8800DC change to AIC8800DW\n"); AICWFDBG(LOGERROR, "AIC8800DC change to AIC8800DW\n");
usb_dev->chipid = PRODUCT_ID_AIC8800DW; usb_dev->chipid = PRODUCT_ID_AIC8800DW;
}else if (usb_dev->chipid == PRODUCT_ID_AIC8800DW) { }else if (usb_dev->chipid == PRODUCT_ID_AIC8800DW) {
AICWFDBG(LOGINFO, "AIC8800DW\n");} AICWFDBG(LOGINFO, "AIC8800DW\n");
else if (usb_dev->chipid == PRODUCT_ID_AIC8800D81) { } else if (usb_dev->chipid == PRODUCT_ID_AIC8800D80N) {
AICWFDBG(LOGINFO, "AIC8800D80\n"); AICWFDBG(LOGERROR, "AIC8800D80N change to AIC8800D80WN\n");
} else if(usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 || } else if (usb_dev->chipid == PRODUCT_ID_AIC8800DLN) {
usb_dev->chipid == PRODUCT_ID_AIC8800D89X2 || AICWFDBG(LOGERROR, "AIC8800DLN change to AIC8800DWN\n");
usb_dev->chipid == PRODUCT_ID_AIC8800D81){ }else if(usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 ||
usb_dev->chipid == PRODUCT_ID_AIC8800D89X2){
//TODO //TODO
}else{ }else{
ret = -ENODEV; ret = -ENODEV;
@@ -2356,11 +2355,12 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid
return 0; return 0;
}else if(pid == USB_PRODUCT_ID_AIC8800D81 || pid == USB_PRODUCT_ID_AIC8800D41 }else if(pid == USB_PRODUCT_ID_AIC8800D81 || pid == USB_PRODUCT_ID_AIC8800D41
|| pid == USB_PRODUCT_ID_TENDA_U11 || pid == USB_PRODUCT_ID_TENDA_U11_PRO || pid == USB_PRODUCT_ID_TENDA_U11 || pid == USB_PRODUCT_ID_TENDA_U11_PRO
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS1 || pid == USB_PRODUCT_ID_AIC8800M80_CUS2 || pid == USB_PRODUCT_ID_AIC8800M80_CUS0 || pid == USB_PRODUCT_ID_AIC8800M80_CUS1
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS2
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS3 || pid == USB_PRODUCT_ID_AIC8800M80_CUS4 || pid == USB_PRODUCT_ID_AIC8800M80_CUS3 || pid == USB_PRODUCT_ID_AIC8800M80_CUS4
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS5 || pid == USB_PRODUCT_ID_AIC8800M80_CUS6 || pid == USB_PRODUCT_ID_AIC8800M80_CUS5 || pid == USB_PRODUCT_ID_AIC8800M80_CUS6
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS7 || pid == USB_PRODUCT_ID_AIC8800M80_CUS8 || pid == USB_PRODUCT_ID_AIC8800M80_CUS7 || pid == USB_PRODUCT_ID_AIC8800M80_CUS8
|| pid == USB_PRODUCT_ID_AIC8800D80_UGREEN){ || pid == USB_PRODUCT_ID_AIC8800D80_UGREEN || pid == USB_PRODUCT_ID_MERCURY){
usb_dev->chipid = PRODUCT_ID_AIC8800D81; usb_dev->chipid = PRODUCT_ID_AIC8800D81;
aicwf_usb_rx_aggr = true; aicwf_usb_rx_aggr = true;
AICWFDBG(LOGINFO, "%s USE AIC8800D81\r\n", __func__); AICWFDBG(LOGINFO, "%s USE AIC8800D81\r\n", __func__);
@@ -2393,7 +2393,23 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid
} }
AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__); AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__);
return 0; return 0;
}else{ } else if ((pid == USB_PRODUCT_ID_AIC8800D80N) ||
(pid == USB_PRODUCT_ID_AIC8800D80LN) ||
(pid == USB_PRODUCT_ID_AIC8800D80WN) ||
(pid == USB_PRODUCT_ID_AIC8800D40N) ||
(pid == USB_PRODUCT_ID_AIC8800D40LN) ||
(pid == USB_PRODUCT_ID_AIC8800D40WN)) {
usb_dev->chipid = PRODUCT_ID_AIC8800D80N;
aicwf_usb_rx_aggr = true;
AICWFDBG(LOGINFO, "%s USE AIC8800D80N\r\n", __func__);
return 0;
} else if ((pid == USB_PRODUCT_ID_AIC8800DLN) ||
(pid == USB_PRODUCT_ID_AIC8800DWN)) {
usb_dev->chipid = PRODUCT_ID_AIC8800DLN;
aicwf_usb_rx_aggr = true;
AICWFDBG(LOGINFO, "%s USE AIC8800DLN\r\n", __func__);
return 0;
} else{
return -1; return -1;
} }
} }
@@ -2457,9 +2473,6 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i
usb_dev->dev = &usb->dev; usb_dev->dev = &usb->dev;
usb_set_intfdata(intf, usb_dev); usb_set_intfdata(intf, usb_dev);
usb_dev->vid = id->idVendor;
usb_dev->pid = id->idProduct;
ret = aicwf_usb_chipmatch(usb_dev, id->idVendor, id->idProduct); ret = aicwf_usb_chipmatch(usb_dev, id->idVendor, id->idProduct);
if (ret < 0) { if (ret < 0) {
@@ -2531,9 +2544,6 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i
AICWFDBG(LOGERROR, "aicwf_rwnx_usb_platform_init err %d\n", ret); AICWFDBG(LOGERROR, "aicwf_rwnx_usb_platform_init err %d\n", ret);
goto out_free_bus; goto out_free_bus;
} }
if(usb_dev->msg_in_pipe){
aicwf_usb_rx_prepare(usb_dev);
}
aicwf_hostif_ready(); aicwf_hostif_ready();
#ifdef CONFIG_GPIO_WAKEUP #ifdef CONFIG_GPIO_WAKEUP
@@ -2602,7 +2612,9 @@ static int aicwf_usb_suspend(struct usb_interface *intf, pm_message_t state)
AICWFDBG(LOGINFO, "%s enter\r\n", __func__); AICWFDBG(LOGINFO, "%s enter\r\n", __func__);
#ifdef CONFIG_WOWLAN #ifdef CONFIG_WOWLAN
#ifndef ANDROID_PLATFORM
rwnx_send_dummy_reboot(usb_dev->rwnx_hw); rwnx_send_dummy_reboot(usb_dev->rwnx_hw);
#endif
#endif #endif
list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) { list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) {
if (rwnx_vif->ndev){ if (rwnx_vif->ndev){
@@ -2634,6 +2646,7 @@ static int aicwf_usb_resume(struct usb_interface *intf)
if (usb_dev->state != USB_UP_ST){ if (usb_dev->state != USB_UP_ST){
aicwf_bus_start(usb_dev->bus_if); aicwf_bus_start(usb_dev->bus_if);
g_rwnx_plat->wait_disconnect_cb = false;
} }
list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) { list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) {
@@ -2641,9 +2654,6 @@ static int aicwf_usb_resume(struct usb_interface *intf)
netif_tx_wake_all_queues(rwnx_vif->ndev); netif_tx_wake_all_queues(rwnx_vif->ndev);
} }
} }
if(usb_dev->msg_in_pipe){
aicwf_usb_rx_prepare(usb_dev);
}
return 0; return 0;
} }
@@ -2665,6 +2675,14 @@ static struct usb_device_id aicwf_usb_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800M80_CUS1)}, {USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800M80_CUS1)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D81X2, 0xff, 0xff, 0xff)}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D81X2, 0xff, 0xff, 0xff)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D89X2)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D89X2)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80N, 0xff, 0xff, 0xff)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80LN, 0xff, 0xff, 0xff)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80WN, 0xff, 0xff, 0xff)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D40N, 0xff, 0xff, 0xff)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D40LN, 0xff, 0xff, 0xff)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D40WN, 0xff, 0xff, 0xff)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800DLN, 0xff, 0xff, 0xff)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800DWN, 0xff, 0xff, 0xff)},
{USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA)}, {USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA)},
{USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U2)}, {USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U2)},
{USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U11)}, {USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U11)},
@@ -2676,6 +2694,7 @@ static struct usb_device_id aicwf_usb_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS4)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS4)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS5)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS5)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS6)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS6)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS0)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS1)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS1)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS2)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS2)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS3)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS3)},
@@ -2685,6 +2704,7 @@ static struct usb_device_id aicwf_usb_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS7)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS7)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS8)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS8)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80_UGREEN)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80_UGREEN)},
{USB_DEVICE(USB_VENDOR_ID_TP, USB_PRODUCT_ID_MERCURY)},
#endif #endif
{} {}
}; };
+22 -7
View File
@@ -16,11 +16,17 @@
/* USB Device ID */ /* USB Device ID */
#define USB_VENDOR_ID_AIC 0xA69C #define USB_VENDOR_ID_AIC 0xA69C
#define USB_VENDOR_ID_AIC_V2 0x368B #define USB_VENDOR_ID_TP 0x2357
#define USB_VENDOR_ID_TENDA 0x2604 #define USB_VENDOR_ID_TENDA 0x2604
#define USB_VENDOR_ID_TENDA_V2 0x3625 #define USB_VENDOR_ID_TENDA_V2 0x3625
#define USB_VENDOR_ID_AIC_V2 0x368B
#define USB_PRODUCT_ID_TP 0x014e
#define USB_PRODUCT_ID_MERCURY 0x014b
#define USB_PRODUCT_ID_FAST 0x014f
#define USB_PRODUCT_ID_TENDA_U11 0x001f
#define USB_PRODUCT_ID_TENDA_U11_PRO 0x0020
#ifndef CONFIG_USB_BT #ifndef CONFIG_USB_BT
#define USB_PRODUCT_ID_AIC8800 0x8800 #define USB_PRODUCT_ID_AIC8800 0x8800
#define USB_PRODUCT_ID_AIC8801 0x8801 #define USB_PRODUCT_ID_AIC8801 0x8801
@@ -37,10 +43,16 @@
#define USB_PRODUCT_ID_AIC8800D41 0x8d41 #define USB_PRODUCT_ID_AIC8800D41 0x8d41
#define USB_PRODUCT_ID_AIC8800D81X2 0x8d91 #define USB_PRODUCT_ID_AIC8800D81X2 0x8d91
#define USB_PRODUCT_ID_AIC8800D89X2 0x8d99 #define USB_PRODUCT_ID_AIC8800D89X2 0x8d99
#define USB_PRODUCT_ID_AIC8800D80N 0x8d45
#define USB_PRODUCT_ID_AIC8800D80LN 0x8d46
#define USB_PRODUCT_ID_AIC8800D80WN 0x8d47
#define USB_PRODUCT_ID_AIC8800D40N 0x8d48
#define USB_PRODUCT_ID_AIC8800D40LN 0x8d49
#define USB_PRODUCT_ID_AIC8800D40WN 0x8d4a
#define USB_PRODUCT_ID_AIC8800DWN 0x8870
#define USB_PRODUCT_ID_AIC8800DLN 0x8871
#define USB_PRODUCT_ID_TENDA 0x0013 #define USB_PRODUCT_ID_TENDA 0x0013
#define USB_PRODUCT_ID_TENDA_U2 0x0014 #define USB_PRODUCT_ID_TENDA_U2 0x0014
#define USB_PRODUCT_ID_TENDA_U11 0x001f
#define USB_PRODUCT_ID_TENDA_U11_PRO 0x0020
#define USB_PRODUCT_ID_TENDA_TX1U_NANO 0x0110 #define USB_PRODUCT_ID_TENDA_TX1U_NANO 0x0110
#define USB_PRODUCT_ID_AIC8800FC_CUS1 0x88df #define USB_PRODUCT_ID_AIC8800FC_CUS1 0x88df
#define USB_PRODUCT_ID_AIC8800FC_CUS2 0x88E0 #define USB_PRODUCT_ID_AIC8800FC_CUS2 0x88E0
@@ -49,6 +61,7 @@
#define USB_PRODUCT_ID_AIC8800FC_CUS5 0x88E3 #define USB_PRODUCT_ID_AIC8800FC_CUS5 0x88E3
#define USB_PRODUCT_ID_AIC8800FC_CUS6 0x88E5 #define USB_PRODUCT_ID_AIC8800FC_CUS6 0x88E5
#define USB_PRODUCT_ID_AIC8800M80_CUS0 0x8D84
#define USB_PRODUCT_ID_AIC8800M80_CUS1 0x8D83 #define USB_PRODUCT_ID_AIC8800M80_CUS1 0x8D83
#define USB_PRODUCT_ID_AIC8800M80_CUS2 0x8D85 #define USB_PRODUCT_ID_AIC8800M80_CUS2 0x8D85
#define USB_PRODUCT_ID_AIC8800M80_CUS3 0x8D86 #define USB_PRODUCT_ID_AIC8800M80_CUS3 0x8D86
@@ -64,6 +77,8 @@ enum AICWF_IC{
PRODUCT_ID_AIC8801 = 0, PRODUCT_ID_AIC8801 = 0,
PRODUCT_ID_AIC8800DC, PRODUCT_ID_AIC8800DC,
PRODUCT_ID_AIC8800DW, PRODUCT_ID_AIC8800DW,
PRODUCT_ID_AIC8800DLN,
PRODUCT_ID_AIC8800D80N,
PRODUCT_ID_AIC8800D81, PRODUCT_ID_AIC8800D81,
PRODUCT_ID_AIC8800D81X2, PRODUCT_ID_AIC8800D81X2,
PRODUCT_ID_AIC8800D89X2 PRODUCT_ID_AIC8800D89X2
@@ -78,7 +93,7 @@ enum AICWF_IC{
#define TXQLEN (2048*4) #define TXQLEN (2048*4)
#define AICWF_USB_TX_URBS (50) #define AICWF_USB_TX_URBS (50)
#else #else
#define AICWF_USB_TX_URBS 50//(100) #define AICWF_USB_TX_URBS 200//(100)
#endif #endif
#define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4)//25% #define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4)//25%
#define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3)//75% #define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3)//75%
@@ -202,8 +217,6 @@ struct aic_usb_dev {
#endif #endif
u16 chipid; u16 chipid;
bool tbusy; bool tbusy;
u16_l vid;
u16_l pid;
}; };
extern void aicwf_usb_exit(void); extern void aicwf_usb_exit(void);
@@ -214,7 +227,9 @@ int usb_msg_busrx_thread(void *data);
#endif #endif
int usb_bustx_thread(void *data); int usb_bustx_thread(void *data);
int usb_busrx_thread(void *data); int usb_busrx_thread(void *data);
void rwnx_stop_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw);
void rwnx_wake_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw);
void aicwf_usb_cancel_all_urbs(struct aic_usb_dev *usb_dev);
extern void aicwf_hostif_ready(void); extern void aicwf_hostif_ready(void);
@@ -400,7 +400,7 @@ static char *aicwf_get_iwe_stream_mac_addr(struct rwnx_hw* rwnx_hw,
iwe->cmd = SIOCGIWAP; iwe->cmd = SIOCGIWAP;
iwe->u.ap_addr.sa_family = ARPHRD_ETHER; iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
if(scan_re->bss && &scan_re->bss->bssid[0]){ if(scan_re->bss){
memcpy(iwe->u.ap_addr.sa_data, scan_re->bss->bssid, ETH_ALEN); memcpy(iwe->u.ap_addr.sa_data, scan_re->bss->bssid, ETH_ALEN);
} }
@@ -616,8 +616,10 @@ static inline char *aicwf_get_iwe_stream_rate(struct rwnx_hw* rwnx_hw,
u16 vht_data_rate = 0; u16 vht_data_rate = 0;
u16 he_cap = false; u16 he_cap = false;
u8 he_ch_width_set = 0;
u8 he_bw = 0; u8 he_bw = 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)|| defined(CONFIG_HE_FOR_OLD_KERNEL)
u8 he_ch_width_set = 0;
#endif
/* parsing HT_CAP_IE */ /* parsing HT_CAP_IE */
ie_content = NULL; ie_content = NULL;
@@ -8,4 +8,6 @@ struct scanu_result_wext{
void aicwf_set_wireless_ext( struct net_device *ndev, struct rwnx_hw *rwnx_hw); void aicwf_set_wireless_ext( struct net_device *ndev, struct rwnx_hw *rwnx_hw);
void aicwf_scan_complete_event(struct net_device *dev); void aicwf_scan_complete_event(struct net_device *dev);
int aic_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len);
u8 aicwf_get_is_wps_ie(u8 *ie_ptr, uint *wps_ielen);
+57 -33
View File
@@ -413,6 +413,13 @@ enum mm_msg_tag
MM_SET_TXPWR_PER_STA_REQ, MM_SET_TXPWR_PER_STA_REQ,
MM_SET_TXPWR_PER_STA_CFM, MM_SET_TXPWR_PER_STA_CFM,
MM_GET_STATISTIC_REQ,
MM_GET_STATISTIC_CFM,
MM_VENDOR_SWCONFIG_IND,
MM_FW_PANIC_IND,
MM_FW_ASSERT_IND,
/// MAX number of messages /// MAX number of messages
MM_MAX, MM_MAX,
}; };
@@ -892,6 +899,7 @@ struct mm_ba_add_cfm
u8_l tid; u8_l tid;
/// Status of ba establishment /// Status of ba establishment
u8_l status; u8_l status;
u8_l alligned;
}; };
/// Structure containing the parameters of the @ref MM_BA_DEL_REQ message. /// Structure containing the parameters of the @ref MM_BA_DEL_REQ message.
@@ -1345,6 +1353,12 @@ struct mm_get_sta_info_req
u8_l sta_idx; u8_l sta_idx;
}; };
struct mm_get_sta_info_compat_req
{
u8_l sta_idx;
char pattern[3];
};
struct mm_get_sta_info_cfm struct mm_get_sta_info_cfm
{ {
u32_l rate_info; u32_l rate_info;
@@ -1412,6 +1426,12 @@ typedef struct
s8_l pwrlvl_adj_tbl_5g[6]; s8_l pwrlvl_adj_tbl_5g[6];
} txpwr_lvl_adj_conf_t; } txpwr_lvl_adj_conf_t;
typedef struct
{
u8_l enable;
s8_l pwrlvl_adj_tbl_2g4[3];
} txpwr_lvl_adj_conf_v2_t;
struct mm_set_txpwr_lvl_req struct mm_set_txpwr_lvl_req
{ {
union { union {
@@ -1424,7 +1444,10 @@ struct mm_set_txpwr_lvl_req
struct mm_set_txpwr_lvl_adj_req struct mm_set_txpwr_lvl_adj_req
{ {
union {
txpwr_lvl_adj_conf_t txpwr_lvl_adj; txpwr_lvl_adj_conf_t txpwr_lvl_adj;
txpwr_lvl_adj_conf_v2_t txpwr_lvl_adj_v2;
};
}; };
typedef struct typedef struct
@@ -1538,12 +1561,33 @@ typedef struct
s8_l pwrofst2x_tbl_6g_ant1[15]; s8_l pwrofst2x_tbl_6g_ant1[15];
} txpwr_ofst2x_conf_v2_t; } txpwr_ofst2x_conf_v2_t;
/*
* pwrofst2x_tbl_2g4[3][3]:
* +---------------+----------+----------+----------+
* | RateTyp\ChGrp | CH_1_4 | CH_5_9 | CH_10_13 |
* +---------------+----------+----------+----------+
* | DSSS | [0][0] | [0][1] | [0][2] |
* +---------------+----------+----------+----------+
* | OFDM_HIGHRATE | [1][0] | [1][1] | [1][2] |
* +---------------+----------+----------+----------+
* | OFDM_LOWRATE | [2][0] | [2][1] | [2][2] |
* +---------------+----------+----------+----------+
*/
typedef struct
{
u8_l enable;
s8_l pwrofst2x_tbl_2g4[3][3];
u8_l RESERVED[2];
} txpwr_ofst2x_conf_v3_t;
struct mm_set_txpwr_ofst_req struct mm_set_txpwr_ofst_req
{ {
union { union {
txpwr_ofst_conf_t txpwr_ofst; txpwr_ofst_conf_t txpwr_ofst;
txpwr_ofst2x_conf_t txpwr_ofst2x; txpwr_ofst2x_conf_t txpwr_ofst2x;
txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2; txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2;
txpwr_ofst2x_conf_v3_t txpwr_ofst2x_v3;
}; };
}; };
@@ -1664,6 +1708,18 @@ struct mm_csa_traffic_ind
bool_l enable; bool_l enable;
}; };
struct fw_panic_info_ind
{
uint32_t len;
uint8_t info[384];
};
struct fw_assert_info_ind
{
uint32_t len;
uint8_t info[384];
};
/// Structure containing the parameters of the @ref MM_MU_GROUP_UPDATE_REQ message. /// Structure containing the parameters of the @ref MM_MU_GROUP_UPDATE_REQ message.
/// Size allocated for the structure depends of the number of group /// Size allocated for the structure depends of the number of group
struct mm_mu_group_update_req struct mm_mu_group_update_req
@@ -2038,6 +2094,7 @@ struct me_sta_add_cfm
u8_l status; u8_l status;
/// PM state of the station /// PM state of the station
u8_l pm_state; u8_l pm_state;
u8_l alligned;
}; };
/// Structure containing the parameters of the @ref ME_STA_DEL_REQ message. /// Structure containing the parameters of the @ref ME_STA_DEL_REQ message.
@@ -3463,37 +3520,4 @@ struct mm_set_wakeup_info_req {
u16_l length; u16_l length;
u8_l mask_and_pattern[]; u8_l mask_and_pattern[];
}; };
struct dbg_pwm_init_req
{
/// PWM_CHANNEL_GPIO
u8 pwm_gpidx;
/// 0 normal 1 breath
u8 mode;
/// 0 config only 1 run after config
u8 run;
u32 tmr_cnt;
u32 dty_cnt;
u32 step_val;
/// 0 disable 1 enable
u8 gpio_en;
/// 0 input 1 output
u8 gpio_dir;
/// 0 low 1 high
u8 gpio_val;
};
struct dbg_pwm_deinit_req
{
/// PWM_CHANNEL_GPIO
u8 pwm_gpidx;
/// 0 disable 1 enable
u8 gpio_en;
/// 0 input 1 output
u8 gpio_dir;
/// 0 low 1 high
u8 gpio_val;
};
#endif // LMAC_MSG_H_ #endif // LMAC_MSG_H_
File diff suppressed because it is too large Load Diff
+14 -12
View File
@@ -139,9 +139,13 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
#endif #endif
if(cmd->e2a_msg != NULL) { if(cmd->e2a_msg != NULL) {
do { do {
if(cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED)
break;
spin_lock_bh(&cmd_mgr->lock); spin_lock_bh(&cmd_mgr->lock);
if(cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
AICWFDBG(LOGERROR, "cmd queue crashed\n");
cmd->result = -EPIPE;
spin_unlock_bh(&cmd_mgr->lock);
return -EPIPE;
}
empty = list_empty(&cmd_mgr->cmds); empty = list_empty(&cmd_mgr->cmds);
if(!empty) { if(!empty) {
spin_unlock_bh(&cmd_mgr->lock); spin_unlock_bh(&cmd_mgr->lock);
@@ -156,15 +160,13 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
} while(!empty);//wait for cmd queue empty } while(!empty);//wait for cmd queue empty
} else { } else {
spin_lock_bh(&cmd_mgr->lock); spin_lock_bh(&cmd_mgr->lock);
}
if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) { if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
printk(KERN_CRIT"cmd queue crashed\n"); printk(KERN_CRIT"cmd queue crashed\n");
cmd->result = -EPIPE; cmd->result = -EPIPE;
spin_unlock_bh(&cmd_mgr->lock); spin_unlock_bh(&cmd_mgr->lock);
return -EPIPE; return -EPIPE;
} }
}
#ifndef CONFIG_RWNX_FHOST #ifndef CONFIG_RWNX_FHOST
if (!list_empty(&cmd_mgr->cmds)) { if (!list_empty(&cmd_mgr->cmds)) {
@@ -221,8 +223,9 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
//printk("defer push: tkn=%d\r\n", cmd->tkn); //printk("defer push: tkn=%d\r\n", cmd->tkn);
} }
spin_unlock_bh(&cmd_mgr->lock); //spin_unlock_bh(&cmd_mgr->lock);
if (!defer_push) { if (!defer_push) {
spin_unlock_bh(&cmd_mgr->lock);
AICWFDBG(LOGTRACE, "queue:id=%x, param_len=%u\n",cmd->a2e_msg->id, cmd->a2e_msg->param_len); AICWFDBG(LOGTRACE, "queue:id=%x, param_len=%u\n",cmd->a2e_msg->id, cmd->a2e_msg->param_len);
#ifdef AICWF_SDIO_SUPPORT #ifdef AICWF_SDIO_SUPPORT
@@ -234,8 +237,11 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
kfree(cmd->a2e_msg); kfree(cmd->a2e_msg);
} else { } else {
if(cmd_mgr->queue_sz <= 1){ if(cmd_mgr->queue_sz <= 1) {
spin_unlock_bh(&cmd_mgr->lock);
WAKE_CMD_WORK(cmd_mgr); WAKE_CMD_WORK(cmd_mgr);
} else {
spin_unlock_bh(&cmd_mgr->lock);
} }
return 0; return 0;
} }
@@ -559,7 +565,6 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len)
{ {
u8 *buffer = NULL; u8 *buffer = NULL;
u16 index = 0; u16 index = 0;
int ret = 0;
#ifdef AICWF_SDIO_SUPPORT #ifdef AICWF_SDIO_SUPPORT
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev; struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev;
struct aicwf_bus *bus = sdiodev->bus_if; struct aicwf_bus *bus = sdiodev->bus_if;
@@ -594,9 +599,6 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len)
index += 2; index += 2;
memcpy(&buffer[index], (u8 *)msg->param, msg->param_len); memcpy(&buffer[index], (u8 *)msg->param, msg->param_len);
ret = aicwf_bus_txmsg(bus, buffer, len + 8); aicwf_bus_txmsg(bus, buffer, len + 8);
if (ret == -EIO) {
ret = aicwf_bus_txmsg(bus, buffer, len + 8);
}
} }
+1
View File
@@ -116,5 +116,6 @@ void rwnx_cmd_mgr_init(struct rwnx_cmd_mgr *cmd_mgr);
void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr); void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr);
int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd); int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd);
void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len); void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len);
void cmd_mgr_task_process(struct work_struct *work);
#endif /* _RWNX_CMDS_H_ */ #endif /* _RWNX_CMDS_H_ */
+2 -1
View File
@@ -41,7 +41,7 @@
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK
#endif #endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 18, 0) #if LINUX_VERSION_CODE > KERNEL_VERSION(5, 15, 60)
#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE #define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE
#endif #endif
@@ -380,6 +380,7 @@ enum {
rwnx_ops_hw_scan(hw, vif, struct cfg80211_scan_request *req) rwnx_ops_hw_scan(hw, vif, struct cfg80211_scan_request *req)
#endif #endif
u16 rwnx_select_txq(struct rwnx_vif *rwnx_vif, struct sk_buff *skb);
/* NET */ /* NET */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
#define rwnx_select_queue(dev, skb, sb_dev) \ #define rwnx_select_queue(dev, skb, sb_dev) \
+4 -5
View File
@@ -1777,7 +1777,7 @@ static ssize_t rwnx_dbgfs_dbg_level_read(struct file *file,
char __user *user_buf, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct rwnx_hw *priv = file->private_data; //struct rwnx_hw *priv = file->private_data;
char buf[32]; char buf[32];
int ret; int ret;
ssize_t read; ssize_t read;
@@ -1796,7 +1796,7 @@ static ssize_t rwnx_dbgfs_dbg_level_write(struct file *file,
const char __user *user_buf, const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct rwnx_hw *priv = file->private_data; //struct rwnx_hw *priv = file->private_data;
char buf[32]; char buf[32];
int val; int val;
size_t len = min_t(size_t, count, sizeof(buf) - 1); size_t len = min_t(size_t, count, sizeof(buf) - 1);
@@ -2019,7 +2019,7 @@ static void idx_to_rate_cfg1(unsigned int formatmod,
case FORMATMOD_NON_HT: case FORMATMOD_NON_HT:
{ {
r_cfg->formatModTx = formatmod; r_cfg->formatModTx = formatmod;
r_cfg->giAndPreTypeTx = 1; r_cfg->giAndPreTypeTx = 2;
r_cfg->mcsIndexTx = mcs; r_cfg->mcsIndexTx = mcs;
break; break;
} }
@@ -2236,8 +2236,7 @@ static ssize_t rwnx_dbgfs_rc_fixed_rate_idx_write(struct file *file,
/* Get the station index from MAC address */ /* Get the station index from MAC address */
sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
if (&mac[0] == NULL)
return 0;
sta = rwnx_get_sta(priv, mac); sta = rwnx_get_sta(priv, mac);
if (sta == NULL) if (sta == NULL)
return 0; return 0;
@@ -198,6 +198,7 @@ static inline void rwnx_dbgfs_register_rc_stat(struct rwnx_hw *rwnx_hw, struct r
static inline void rwnx_dbgfs_unregister_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) {} static inline void rwnx_dbgfs_unregister_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) {}
#endif #endif
#endif /* CONFIG_RWNX_DEBUGFS */ #endif /* CONFIG_RWNX_DEBUGFS */
void _rwnx_dbgfs_rc_stat_write(struct rwnx_debugfs *rwnx_debugfs, uint8_t sta_idx);
#endif /* _RWNX_DEBUGFS_H_ */ #endif /* _RWNX_DEBUGFS_H_ */
+33 -11
View File
@@ -79,20 +79,11 @@
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION #if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
#ifndef IEEE80211_MAX_AMPDU_BUF
#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE #define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE
#endif
#ifndef IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB
#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB #define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB
#endif
#ifndef IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB
#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB #define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB
#endif
#ifndef IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA
#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU #define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU
#endif #endif
#endif
#ifndef IEEE80211_MAX_AMPDU_BUF #ifndef IEEE80211_MAX_AMPDU_BUF
#define IEEE80211_MAX_AMPDU_BUF 0x100 #define IEEE80211_MAX_AMPDU_BUF 0x100
@@ -107,6 +98,7 @@
#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40 #define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40
#endif #endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL)
enum nl80211_ac { enum nl80211_ac {
NL80211_AC_VO, NL80211_AC_VO,
@@ -237,6 +229,7 @@ struct tmp_feature_sta {
u8_l supported_band; u8_l supported_band;
}; };
#if 0
#define MAX_PENDING_PROBES 3 #define MAX_PENDING_PROBES 3
struct ap_probe_rsp { struct ap_probe_rsp {
u8_l da[6]; u8_l da[6];
@@ -244,6 +237,7 @@ struct ap_probe_rsp {
bool in_use; bool in_use;
}; };
#endif #endif
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
#define NL80211_MESHCONF_POWER_MODE 26 #define NL80211_MESHCONF_POWER_MODE 26
@@ -388,6 +382,18 @@ enum rwnx_ap_flags {
RWNX_AP_ISOLATE = BIT(0), RWNX_AP_ISOLATE = BIT(0),
}; };
#ifdef CONFIG_DYNAMIC_PERPWR
struct sta_pwrthd {
s8_l rssi_thd_0; //rssi 0 (dBm)
s8_l rssi_thd_1; //rssi 1 (dBm)
s8_l rssi_thd_2; //rssi 2 (dBm)
s8_l pwr_loss_lvl_0; //RSSI > RSSI_THD_0
s8_l pwr_loss_lvl_1; //RSSI_THD_1 < RSSI <= RSSI_THD_0
s8_l pwr_loss_lvl_2; //RSSI_THD_2 < RSSI <= RSSI_THD_1
s8_l pwr_loss_lvl_3; //RSSI <= RSSI_THD_2
};
#endif
/* /*
* Structure used to save information relative to the managed interfaces. * Structure used to save information relative to the managed interfaces.
* This is also linked within the rwnx_hw vifs list. * This is also linked within the rwnx_hw vifs list.
@@ -402,6 +408,7 @@ struct rwnx_vif {
struct rwnx_key key[6]; struct rwnx_key key[6];
unsigned long drv_flags; unsigned long drv_flags;
atomic_t drv_conn_state; atomic_t drv_conn_state;
spinlock_t conn_state_lock;
u8 drv_vif_index; /* Identifier of the VIF in driver */ u8 drv_vif_index; /* Identifier of the VIF in driver */
u8 vif_index; /* Identifier of the station in FW */ u8 vif_index; /* Identifier of the station in FW */
u8 ch_index; /* Channel context identifier */ u8 ch_index; /* Channel context identifier */
@@ -458,6 +465,7 @@ struct rwnx_vif {
u32_l freq; u32_l freq;
bool start; bool start;
#endif #endif
u32_l ap_freq;
enum nl80211_mesh_power_mode mesh_pm; /* mesh power save mode currently set in firmware */ enum nl80211_mesh_power_mode mesh_pm; /* mesh power save mode currently set in firmware */
enum nl80211_mesh_power_mode next_mesh_pm; /* mesh power save mode for next peer */ enum nl80211_mesh_power_mode next_mesh_pm; /* mesh power save mode for next peer */
} ap; } ap;
@@ -487,12 +495,14 @@ struct rwnx_vif {
struct br_ext_info ethBrExtInfo; struct br_ext_info ethBrExtInfo;
#endif /* CONFIG_BR_SUPPORT */ #endif /* CONFIG_BR_SUPPORT */
#ifdef CONFIG_BAND_STEERING #ifdef CONFIG_BAND_STEERING
struct workqueue_struct *rsp_wq;
struct timer_list steer_timer; struct timer_list steer_timer;
struct work_struct steer_work; struct work_struct steer_work;
struct b_steer_priv bsteerpriv; struct b_steer_priv bsteerpriv;
#if 0
struct workqueue_struct *rsp_wq;
struct ap_probe_rsp pb_pool[MAX_PENDING_PROBES]; struct ap_probe_rsp pb_pool[MAX_PENDING_PROBES];
#endif #endif
#endif
}; };
@@ -724,7 +734,7 @@ struct amsdu_subframe_hdr {
}; };
/* rwnx driver status */ /* rwnx driver status */
void rwnx_set_conn_state(atomic_t *drv_conn_state, int state); void rwnx_set_conn_state(struct rwnx_vif *vif, atomic_t *drv_conn_state, int state);
enum rwnx_drv_connect_status { enum rwnx_drv_connect_status {
RWNX_DRV_STATUS_DISCONNECTED = 0, RWNX_DRV_STATUS_DISCONNECTED = 0,
@@ -885,6 +895,7 @@ struct rwnx_hw {
char wext_essid[33]; char wext_essid[33];
int support_freqs[SCAN_CHANNEL_MAX]; int support_freqs[SCAN_CHANNEL_MAX];
int support_freqs_number; int support_freqs_number;
#endif
#ifdef CONFIG_DYNAMIC_PWR #ifdef CONFIG_DYNAMIC_PWR
struct timer_list pwrloss_timer; struct timer_list pwrloss_timer;
struct work_struct pwrloss_work; struct work_struct pwrloss_work;
@@ -892,11 +903,22 @@ struct rwnx_hw {
s8 pwrloss_lvl; s8 pwrloss_lvl;
u8 sta_rssi_idx; u8 sta_rssi_idx;
#endif #endif
#ifdef CONFIG_TEMP_CONTROL
struct timer_list tc_timer;
struct work_struct tc_work;
s8 tc_range;
#endif #endif
#ifdef CONFIG_BAND_STEERING #ifdef CONFIG_BAND_STEERING
u8_l iface_idx; u8_l iface_idx;
struct tmp_feature_sta feature_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX]; struct tmp_feature_sta feature_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX];
#endif #endif
#ifdef CONFIG_DYNAMIC_PERPWR
struct sta_pwrthd pwrth;
#endif
ktime_t last_time;
char last_alpha2[3];
}; };
u8 *rwnx_build_bcn(struct rwnx_bcn *bcn, struct cfg80211_beacon_data *new); u8 *rwnx_build_bcn(struct rwnx_bcn *bcn, struct cfg80211_beacon_data *new);
+2
View File
@@ -16,5 +16,7 @@
int rwnx_dini_platform_init(struct pci_dev *pci_dev, int rwnx_dini_platform_init(struct pci_dev *pci_dev,
struct rwnx_plat **rwnx_plat); struct rwnx_plat **rwnx_plat);
int rwnx_cfpga_irq_enable(struct rwnx_hw *rwnx_hw);
int rwnx_cfpga_irq_disable(struct rwnx_hw *rwnx_hw);
#endif /* _RWNX_DINI_H_ */ #endif /* _RWNX_DINI_H_ */
+1 -1
View File
@@ -12,7 +12,7 @@
#include "rwnx_defs.h" #include "rwnx_defs.h"
#include "ipc_host.h" #include "ipc_host.h"
#include "rwnx_prof.h" #include "rwnx_prof.h"
#include "rwnx_irqs.h"
/** /**
* rwnx_irq_hdlr - IRQ handler * rwnx_irq_hdlr - IRQ handler
* *
File diff suppressed because it is too large Load Diff
+60 -2
View File
@@ -37,6 +37,21 @@ extern u8 chip_mcu_id;
#define PWR_LOSS_LVL3 (0)//(2) //RSSI <RSSI_THD_2 #define PWR_LOSS_LVL3 (0)//(2) //RSSI <RSSI_THD_2
#define PWR_DELAY_TIME (10 * 1000) //pwr reduced latency time (ms) #define PWR_DELAY_TIME (10 * 1000) //pwr reduced latency time (ms)
#define PWR_FAST_SWITCH_PROTECT_TIME (2 * 1000) //quickly switch protection time (ms)
#define RSSI_HYSTERESIS_OFFSET 2 //buffer zone (dB)
#define RSSI_HYSTERESIS_THRESHOLD 2 //range of signal variation (dB)
#ifdef CONFIG_TEMP_CONTROL
#define TEMP_GET_INTERVAL (10 * 1000) //time interval
#define TEMP_THD_0 (110) //℃
#define TEMP_THD_1 (95) //℃
#define TEMP_THD_2 (85) //℃
#define TC_LOSS_LVL0 (-10) //TEMP >= TEMP_THD_0
#define TC_LOSS_LVL1 (-5) //TEMP_THD_1 < TEMP <= TEMP_THD_0
#define TC_LOSS_LVL2 (-2) //TEMP_THD_2 < TEMP <= TEMP_THD_1
#define TC_LOSS_LVL3 (0) //TEMP <= TEMP_THD_2
#endif
struct rwnx_sta *rwnx_retrieve_sta(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_retrieve_sta(struct rwnx_hw *rwnx_hw,
struct rwnx_vif *rwnx_vif, u8 *addr, struct rwnx_vif *rwnx_vif, u8 *addr,
@@ -53,13 +68,56 @@ void aicwf_steering_timeout(struct timer_list *t);
#endif #endif
#ifdef CONFIG_DYNAMIC_PERPWR #ifdef CONFIG_DYNAMIC_PERPWR
void rssi_update_txpwrloss(struct rwnx_sta *sta, s8_l rssi); void rssi_update_txpwrloss(struct rwnx_sta *sta, s8_l rssi, struct rwnx_vif *vif);
void aicwf_txpwer_per_sta_worker(struct work_struct *work); void aicwf_txpwer_per_sta_worker(struct work_struct *work);
#endif #endif
#ifdef CONFIG_DYNAMIC_PWR
void set_txpwrloss_ctrl(struct rwnx_hw *rwnx_hw, s8 value); void set_txpwrloss_ctrl(struct rwnx_hw *rwnx_hw, s8 value);
#ifdef CONFIG_DYNAMIC_PWR
void aicwf_pwrloss_worker(struct work_struct *work); void aicwf_pwrloss_worker(struct work_struct *work);
#endif #endif
#ifdef CONFIG_TEMP_CONTROL
void aicwf_tcloss_worker(struct work_struct *work);
#endif
void rwnx_skb_align_8bytes(struct sk_buff *skb);
void rwnx_frame_parser(char* tag, char* data, unsigned long len);
void rwnx_update_mesh_power_mode(struct rwnx_vif *vif);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
void aicwf_p2p_alive_timeout(ulong data);
#else
void aicwf_p2p_alive_timeout(struct timer_list *t);
#endif
int rwnx_send_check_p2p(struct cfg80211_scan_request *param);
void apm_staloss_work_process(struct work_struct *work);
void apm_probe_sta_work_process(struct work_struct *work);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
struct net_device *dev,
struct cfg80211_chan_def *chandef);
#else
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef);
#endif
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
const u8 *peer, u64 *cookie);
void rwnx_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
struct net_device *dev,
#else
struct wireless_dev *wdev,
#endif
u16 frame_type, bool reg);
int rwnx_cfg80211_channel_switch(struct wiphy *wiphy,
struct net_device *dev,
struct cfg80211_csa_settings *params);
int rwnx_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev,
struct bss_parameters *params);
int rwnx_ic_system_init(struct rwnx_hw *rwnx_hw);
int rwnx_ic_rf_init(struct rwnx_hw *rwnx_hw);
void aic_ipc_setting(struct rwnx_vif *rwnx_vif);
u16 rwnx_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev);
#endif /* _RWNX_MAIN_H_ */ #endif /* _RWNX_MAIN_H_ */
+11 -2
View File
@@ -55,6 +55,7 @@ struct rwnx_mod_params rwnx_mod_params = {
COMMON_PARAM(mutx, true, true) COMMON_PARAM(mutx, true, true)
COMMON_PARAM(mutx_on, true, true) COMMON_PARAM(mutx_on, true, true)
COMMON_PARAM(use_80, true, true) COMMON_PARAM(use_80, true, true)
/* false: use crda(iw reg set CN); true: drive self-management(wifi_test wlan0 country_set CN) */
COMMON_PARAM(custregd, true, true) COMMON_PARAM(custregd, true, true)
COMMON_PARAM(custchan, false, false) COMMON_PARAM(custchan, false, false)
COMMON_PARAM(roc_dur_max, 500, 500) COMMON_PARAM(roc_dur_max, 500, 500)
@@ -1781,6 +1782,8 @@ int rwnx_handle_dynparams(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 && if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 &&
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 && rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 &&
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 && rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 &&
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D80N &&
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800DLN &&
rwnx_hw->mod_params->he_mcs_map > IEEE80211_HE_MCS_SUPPORT_0_9){ rwnx_hw->mod_params->he_mcs_map > IEEE80211_HE_MCS_SUPPORT_0_9){
rwnx_hw->mod_params->he_mcs_map = IEEE80211_HE_MCS_SUPPORT_0_9; rwnx_hw->mod_params->he_mcs_map = IEEE80211_HE_MCS_SUPPORT_0_9;
} else { } else {
@@ -1791,6 +1794,7 @@ int rwnx_handle_dynparams(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 && if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 &&
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 && rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 &&
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 && rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 &&
rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D80N &&
rwnx_hw->mod_params->use_80 == true){ rwnx_hw->mod_params->use_80 == true){
rwnx_hw->mod_params->use_80 = false; rwnx_hw->mod_params->use_80 = false;
} else { } else {
@@ -1837,11 +1841,13 @@ void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED; #endif
if (!rwnx_hw->mod_params->custregd) if (!rwnx_hw->mod_params->custregd)
return; return;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
rtnl_lock(); rtnl_lock();
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)
if (regulatory_set_wiphy_regd_sync(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){ if (regulatory_set_wiphy_regd_sync(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){
@@ -1852,6 +1858,7 @@ void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
wiphy_err(wiphy, "Failed to set custom regdomain\n"); wiphy_err(wiphy, "Failed to set custom regdomain\n");
} }
#endif #endif
else{ else{
wiphy_err(wiphy,"\n" wiphy_err(wiphy,"\n"
"*******************************************************\n" "*******************************************************\n"
@@ -1860,4 +1867,6 @@ void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
} }
rtnl_unlock(); rtnl_unlock();
#endif #endif
} }
@@ -71,6 +71,8 @@ struct ieee80211_regdomain *getRegdomainFromRwnxDB(struct wiphy *wiphy,
struct ieee80211_regdomain *getRegdomainFromRwnxDBIndex(struct wiphy *wiphy, struct ieee80211_regdomain *getRegdomainFromRwnxDBIndex(struct wiphy *wiphy,
int index); int index);
void rwnx_get_countrycode_channels(struct wiphy *wiphy,
struct ieee80211_regdomain *regdomain);
#endif /* _RWNX_MOD_PARAM_H_ */ #endif /* _RWNX_MOD_PARAM_H_ */
+88 -8
View File
@@ -28,6 +28,8 @@
#ifdef CONFIG_USE_WIRELESS_EXT #ifdef CONFIG_USE_WIRELESS_EXT
#include "aicwf_wext_linux.h" #include "aicwf_wext_linux.h"
#endif #endif
#include "rwnx_msg_rx.h"
void rwnx_cfg80211_unlink_bss(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif); void rwnx_cfg80211_unlink_bss(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif);
static int rwnx_freq_to_idx(struct rwnx_hw *rwnx_hw, int freq) static int rwnx_freq_to_idx(struct rwnx_hw *rwnx_hw, int freq)
@@ -790,7 +792,15 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw,
#ifdef CONFIG_USE_WIRELESS_EXT #ifdef CONFIG_USE_WIRELESS_EXT
if(rwnx_hw->wext_scan){ if(rwnx_hw->wext_scan){
if (!bss ) {
AICWFDBG(LOGERROR, "%s: Invalid BSS structure\n", __func__);
goto putbss;
}
list_for_each_entry(scan_re_wext, &rwnx_hw->wext_scanre_list, scanu_re_list) { list_for_each_entry(scan_re_wext, &rwnx_hw->wext_scanre_list, scanu_re_list) {
if (!scan_re_wext || !scan_re_wext->bss ) {
AICWFDBG(LOGDEBUG, "%s: Corrupted list entry detected\n", __func__);
continue;
}
if (!memcmp(scan_re_wext->bss->bssid, bss->bssid, ETH_ALEN)) { if (!memcmp(scan_re_wext->bss->bssid, bss->bssid, ETH_ALEN)) {
AICWFDBG(LOGDEBUG, "%s: BSSID already exists, no need to add again\r\n", __func__); AICWFDBG(LOGDEBUG, "%s: BSSID already exists, no need to add again\r\n", __func__);
goto putbss; goto putbss;
@@ -1043,9 +1053,9 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
rwnx_vif->wep_auth_err = true; rwnx_vif->wep_auth_err = true;
AICWFDBG(LOGINFO, "con ind wep_auth_err %d\n", rwnx_vif->wep_auth_err); AICWFDBG(LOGINFO, "con ind wep_auth_err %d\n", rwnx_vif->wep_auth_err);
} }
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
}else{ }else{
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
} }
@@ -1067,9 +1077,13 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
ind->assoc_rsp_ie_len, ind->status_code, ind->assoc_rsp_ie_len, ind->status_code,
GFP_ATOMIC); GFP_ATOMIC);
if (ind->status_code == 0) { if (ind->status_code == 0) {
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
} else { } else {
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED) {
AICWFDBG(LOGINFO, "%s roaming fail no roamed ind \r\n", __func__);
cfg80211_disconnected(dev, 0, NULL, 0, 1, GFP_ATOMIC);
}
rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
rwnx_external_auth_disable(rwnx_vif); rwnx_external_auth_disable(rwnx_vif);
} }
AICWFDBG(LOGINFO, "%s cfg80211_connect_result pass, rwnx_vif->drv_conn_state:%d\r\n", __func__, (int)atomic_read(&rwnx_vif->drv_conn_state)); AICWFDBG(LOGINFO, "%s cfg80211_connect_result pass, rwnx_vif->drv_conn_state:%d\r\n", __func__, (int)atomic_read(&rwnx_vif->drv_conn_state));
@@ -1078,7 +1092,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
if(ind->status_code != 0){ if(ind->status_code != 0){
AICWFDBG(LOGINFO, "%s roaming fail to notify disconnect \r\n", __func__); AICWFDBG(LOGINFO, "%s roaming fail to notify disconnect \r\n", __func__);
cfg80211_disconnected(dev, 0, NULL, 0,1, GFP_ATOMIC); cfg80211_disconnected(dev, 0, NULL, 0,1, GFP_ATOMIC);
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
rwnx_external_auth_disable(rwnx_vif); rwnx_external_auth_disable(rwnx_vif);
}else{ }else{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
@@ -1116,7 +1130,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
, ind->assoc_rsp_ie_len , ind->assoc_rsp_ie_len
, GFP_ATOMIC); , GFP_ATOMIC);
#endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)*/ #endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)*/
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
} }
rwnx_vif->sta.is_roam = false; rwnx_vif->sta.is_roam = false;
} }
@@ -1263,7 +1277,7 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
//msleep(200); //msleep(200);
if (rwnx_vif->sta.is_roam == false) { if (rwnx_vif->sta.is_roam == false) {
rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
} }
return 0; return 0;
@@ -1577,6 +1591,68 @@ static inline int rwnx_rx_dbg_error_ind(struct rwnx_hw *rwnx_hw,
return 0; return 0;
} }
struct fault_ctxt {
uint32_t reg_i[13];
uint32_t SP;
uint32_t LR;
uint32_t PC;
uint32_t xPSR;
uint32_t PSP;
uint32_t MSP;
uint32_t EXC_RETURN;
uint32_t CONTROL;
};
static inline int rwnx_fw_panic_ind(struct rwnx_hw *rwnx_hw,
struct rwnx_cmd *cmd,
struct ipc_e2a_msg *msg)
{
struct fw_panic_info_ind *ind = (struct fw_panic_info_ind *)msg->param;
uint8_t version[36];
struct fault_ctxt fault;
uint32_t msp[64];
uint8_t i;
memcpy(version, ind->info, 36);
version[35] = '\0';
memcpy(&fault, &ind->info[36], sizeof(struct fault_ctxt));
memcpy(msp, &ind->info[36+sizeof(struct fault_ctxt)], 64*4);
printk("fw_panic: len=%d\n", ind->len);
printk("firmware: %s\n", version);
for(i=0; i<13; i++)
printk("REG %d = [%x]\n", i, fault.reg_i[i]);
printk("SP = [%x]\n", fault.SP);
printk("LR = [%x]\n", fault.LR);
printk("PC = [%x]\n", fault.PC);
printk("PSP = [%x]\n", fault.PSP);
printk("xPSR = [%x]\n", fault.xPSR);
printk("EXC_RETURN = [%x]\n", fault.EXC_RETURN);
printk("CONTROL = [%x]\n", fault.CONTROL);
printk("STACK:\n");
for(i=0; i<64; i+=4) {
printk("%08x, %08x, %08x, %08x\n", msp[i], msp[i+1], msp[i+2], msp[i+3]);
}
return 0;
}
static inline int rwnx_fw_assert_ind(struct rwnx_hw *rwnx_hw,
struct rwnx_cmd *cmd,
struct ipc_e2a_msg *msg)
{
struct fw_assert_info_ind *ind = (struct fw_assert_info_ind *)msg->param;
uint8_t buffer[256];
memcpy(buffer, ind->info, ind->len);
buffer[ind->len] = '\0';
printk("%s: %s\n", __func__, buffer);
return 0;
}
#ifdef CONFIG_RWNX_FULLMAC #ifdef CONFIG_RWNX_FULLMAC
static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = { static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = {
@@ -1595,6 +1671,8 @@ static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = {
[MSG_I(MM_PKTLOSS_IND)] = rwnx_rx_pktloss_notify_ind, [MSG_I(MM_PKTLOSS_IND)] = rwnx_rx_pktloss_notify_ind,
[MSG_I(MM_APM_STALOSS_IND)] = rwnx_apm_staloss_ind, [MSG_I(MM_APM_STALOSS_IND)] = rwnx_apm_staloss_ind,
[MSG_I(MM_RADAR_DETECT_IND)] = rwnx_radar_detect_ind, [MSG_I(MM_RADAR_DETECT_IND)] = rwnx_radar_detect_ind,
[MSG_I(MM_FW_PANIC_IND)] = rwnx_fw_panic_ind,
[MSG_I(MM_FW_ASSERT_IND)] = rwnx_fw_assert_ind,
}; };
static msg_cb_fct scan_hdlrs[MSG_I(SCANU_MAX)] = { static msg_cb_fct scan_hdlrs[MSG_I(SCANU_MAX)] = {
@@ -1669,12 +1747,14 @@ void rwnx_rx_handle_print(struct rwnx_hw *rwnx_hw, u8 *msg, u32 len)
u8 *data_end = NULL; u8 *data_end = NULL;
(void)data_end; (void)data_end;
msg[len-1] = '\0';
if (!rwnx_hw || !rwnx_hw->fwlog_en) { if (!rwnx_hw || !rwnx_hw->fwlog_en) {
pr_err("FWLOG-OVFL: %s", msg); pr_err("FWLOG-OVFL: %s", msg);
return; return;
} }
printk("FWLOG: %s", msg); AICWFDBG(LOGFW, "%s", msg);
#ifdef CONFIG_RWNX_DEBUGFS #ifdef CONFIG_RWNX_DEBUGFS
data_end = rwnx_hw->debugfs.fw_log.buf.dataend; data_end = rwnx_hw->debugfs.fw_log.buf.dataend;
+200 -67
View File
@@ -205,6 +205,7 @@ void rwnx_cmd_free(struct rwnx_cmd *cmd){
spin_lock_irqsave(&cmd_array_lock, flags); spin_lock_irqsave(&cmd_array_lock, flags);
cmd->used = 0; cmd->used = 0;
cmd->flags = 0;
AICWFDBG(LOGTRACE, "%s cmd_array[%d]:%p \r\n", __func__, cmd->array_id, cmd); AICWFDBG(LOGTRACE, "%s cmd_array[%d]:%p \r\n", __func__, cmd->array_id, cmd);
spin_unlock_irqrestore(&cmd_array_lock, flags); spin_unlock_irqrestore(&cmd_array_lock, flags);
} }
@@ -1150,6 +1151,34 @@ int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l *
return (error); return (error);
} }
int rwnx_send_rf_config_v2_req(struct rwnx_hw *rwnx_hw, u16_l ofst, u8_l sel, u8_l *tbl, u16_l len)
{
struct mm_set_rf_config_req *rf_config_req;
int error;
RWNX_DBG(RWNX_FN_ENTRY_STR);
/* Build the MM_SET_RF_CONFIG_REQ message */
rf_config_req = rwnx_msg_zalloc(MM_SET_RF_CONFIG_REQ, TASK_MM, DRV_TASK_ID,
sizeof(struct mm_set_rf_config_req));
if (!rf_config_req) {
return -ENOMEM;
}
rf_config_req->table_sel = sel;
rf_config_req->table_ofst = 0;
rf_config_req->table_num = 16;
rf_config_req->deft_page = ofst / 16;
memcpy(rf_config_req->data, tbl, len);
/* Send the MM_SET_RF_CONFIG_REQ message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, rf_config_req, 1, MM_SET_RF_CONFIG_CFM, NULL);
return (error);
}
#ifdef RF_WRITE_FILE #ifdef RF_WRITE_FILE
#define FW_PATH_MAX_LEN_RF 200 #define FW_PATH_MAX_LEN_RF 200
@@ -1271,6 +1300,9 @@ int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
rf_calib_req->cal_cfg_24g = 0x0f8f; rf_calib_req->cal_cfg_24g = 0x0f8f;
rf_calib_req->cal_cfg_5g = 0x0f0f; rf_calib_req->cal_cfg_5g = 0x0f0f;
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N){
rf_calib_req->cal_cfg_24g = 0x0f8f;
rf_calib_req->cal_cfg_5g = 0x0f0f;
} }
rf_calib_req->param_alpha = 0x0c34c008; rf_calib_req->param_alpha = 0x0c34c008;
@@ -1444,6 +1476,9 @@ int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
rf_calib_req->cal_cfg_24g = 0x0f8f; rf_calib_req->cal_cfg_24g = 0x0f8f;
rf_calib_req->cal_cfg_5g = 0x0f0f; rf_calib_req->cal_cfg_5g = 0x0f0f;
} else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N){
rf_calib_req->cal_cfg_24g = 0x0f8f;
rf_calib_req->cal_cfg_5g = 0x0f0f;
} }
rf_calib_req->param_alpha = 0x0c34c008; rf_calib_req->param_alpha = 0x0c34c008;
@@ -1494,8 +1529,23 @@ int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cf
int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_get_sta_info_cfm *cfm) int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_get_sta_info_cfm *cfm)
{ {
struct mm_get_sta_info_req *get_info_req; struct mm_get_sta_info_req *get_info_req;
struct mm_get_sta_info_compat_req *get_info_compat_req;
int error; int error;
if(rwnx_hw->usbdev->chipid < PRODUCT_ID_AIC8800D81X2) {
/* Build the MM_GET_STA_INFO_REQ message */
get_info_compat_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID,
sizeof(struct mm_get_sta_info_compat_req));
if (!get_info_compat_req) {
return -ENOMEM;
}
get_info_compat_req->sta_idx = sta_idx;
memcpy(get_info_compat_req->pattern, "sta", 3);
/* Send the MM_GET_STA_INFO_REQ message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, get_info_compat_req, 1, MM_GET_STA_INFO_CFM, cfm);
} else {
/* Build the MM_GET_STA_INFO_REQ message */ /* Build the MM_GET_STA_INFO_REQ message */
get_info_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID, get_info_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID,
sizeof(struct mm_get_sta_info_req)); sizeof(struct mm_get_sta_info_req));
@@ -1508,7 +1558,7 @@ int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_
/* Send the MM_GET_STA_INFO_REQ message to UMAC FW */ /* Send the MM_GET_STA_INFO_REQ message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, get_info_req, 1, MM_GET_STA_INFO_CFM, cfm); error = rwnx_send_msg(rwnx_hw, get_info_req, 1, MM_GET_STA_INFO_CFM, cfm);
}
return error; return error;
}; };
@@ -1709,6 +1759,7 @@ int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id,
printk("get_chip_temp err=%d\n", error); printk("get_chip_temp err=%d\n", error);
} }
} }
break;
case CUSTOMIZED_FREQ_REQ: case CUSTOMIZED_FREQ_REQ:
/* Build the CUSTOMIZED_FREQ_REQ message */ /* Build the CUSTOMIZED_FREQ_REQ message */
req5 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_customized_freq_req)); req5 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_customized_freq_req));
@@ -2386,7 +2437,8 @@ int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw)
txpwr_lvl_v2->pwrlvl_11ax_2g4[i] -= txpwr_loss->loss_value_2g4; txpwr_lvl_v2->pwrlvl_11ax_2g4[i] -= txpwr_loss->loss_value_2g4;
} }
if ((testmode == 0) && (chip_sub_id == 0)) { if ((rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800DLN) &&
(testmode == 0) && (chip_sub_id == 0)) {
txpwr_lvl_req->txpwr_lvl.enable = txpwr_lvl_v2->enable; txpwr_lvl_req->txpwr_lvl.enable = txpwr_lvl_v2->enable;
txpwr_lvl_req->txpwr_lvl.dsss = txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]; // 11M txpwr_lvl_req->txpwr_lvl.dsss = txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]; // 11M
txpwr_lvl_req->txpwr_lvl.ofdmlowrate_2g4= txpwr_lvl_v2->pwrlvl_11ax_2g4[4]; // MCS4 txpwr_lvl_req->txpwr_lvl.ofdmlowrate_2g4= txpwr_lvl_v2->pwrlvl_11ax_2g4[4]; // MCS4
@@ -2753,6 +2805,45 @@ int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw)
} }
} }
int rwnx_send_txpwr_lvl_adj_v2_req(struct rwnx_hw *rwnx_hw)
{
struct mm_set_txpwr_lvl_adj_req *txpwr_lvl_adj_req;
txpwr_lvl_adj_conf_v2_t txpwr_lvl_adj_v2_tmp;
txpwr_lvl_adj_conf_v2_t *txpwr_lvl_adj_v2;
int error;
RWNX_DBG(RWNX_FN_ENTRY_STR);
/* Build the MM_SET_TXPWR_LVL_REQ message */
txpwr_lvl_adj_req = rwnx_msg_zalloc(MM_SET_TXPWR_LVL_ADJ_REQ, TASK_MM, DRV_TASK_ID,
sizeof(struct mm_set_txpwr_lvl_adj_req));
if (!txpwr_lvl_adj_req) {
return -ENOMEM;
}
txpwr_lvl_adj_v2 = &txpwr_lvl_adj_v2_tmp;
get_userconfig_txpwr_lvl_adj_v2_in_fdrv(txpwr_lvl_adj_v2);
if (txpwr_lvl_adj_v2->enable == 0) {
rwnx_msg_free(rwnx_hw, txpwr_lvl_adj_req);
return 0;
} else {
AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_adj_v2->enable);
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_1_4:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[0]);
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_5_9:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[1]);
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_10_13:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[2]);
txpwr_lvl_adj_req->txpwr_lvl_adj_v2 = *txpwr_lvl_adj_v2;
/* Send the MM_SET_TXPWR_LVL_REQ message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, txpwr_lvl_adj_req, 1, MM_SET_TXPWR_LVL_ADJ_CFM, NULL);
return (error);
}
}
extern void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst); extern void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst);
int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw) int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw)
@@ -2839,6 +2930,8 @@ int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw)
} else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || } else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 ||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x); get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x);
} else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) {
get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x);
} }
if (txpwr_ofst2x->enable){ if (txpwr_ofst2x->enable){
AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_ofst2x->enable); AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_ofst2x->enable);
@@ -2922,6 +3015,53 @@ int rwnx_send_txpwr_ofst2x_v2_req(struct rwnx_hw *rwnx_hw)
return (error); return (error);
} }
int rwnx_send_txpwr_ofst2x_v3_req(struct rwnx_hw *rwnx_hw)
{
struct mm_set_txpwr_ofst_req *txpwr_ofst_req;
txpwr_ofst2x_conf_v3_t *txpwr_ofst2x_v3;
int error = 0;
int type, ch_grp;
RWNX_DBG(RWNX_FN_ENTRY_STR);
/* Build the MM_SET_TXPWR_OFST_REQ message */
txpwr_ofst_req = rwnx_msg_zalloc(MM_SET_TXPWR_OFST_REQ, TASK_MM, DRV_TASK_ID,
sizeof(struct mm_set_txpwr_ofst_req));
if (!txpwr_ofst_req) {
return -ENOMEM;
}
txpwr_ofst2x_v3 = &txpwr_ofst_req->txpwr_ofst2x_v3;
txpwr_ofst2x_v3->enable = 0;
for (type = 0; type < 3; type++) {
for (ch_grp = 0; ch_grp < 3; ch_grp++) {
txpwr_ofst2x_v3->pwrofst2x_tbl_2g4[type][ch_grp] = 0;
}
}
get_userconfig_txpwr_ofst2x_v3_in_fdrv(txpwr_ofst2x_v3);
if (txpwr_ofst2x_v3->enable){
AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_ofst2x_v3->enable);
AICWFDBG(LOGINFO, "pwrofst2x 2.4g: [0]:11b, [1]:ofdm_highrate, [2]:ofdm_lowrate\n"
" chan=" "\t1-4" "\t5-9" "\t10-13");
for (type = 0; type < 3; type++) {
AICWFDBG(LOGINFO, "\n [%d] =", type);
for (ch_grp = 0; ch_grp < 3; ch_grp++) {
AICWFDBG(LOGINFO, "\t%d", txpwr_ofst2x_v3->pwrofst2x_tbl_2g4[type][ch_grp]);
}
}
AICWFDBG(LOGINFO, "\n");
/* Send the MM_SET_TXPWR_OFST_REQ message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, txpwr_ofst_req, 1, MM_SET_TXPWR_OFST_CFM, NULL);
}else{
AICWFDBG(LOGINFO, "%s:Do not use txpwr_ofst2x_v3\r\n", __func__);
rwnx_msg_free(rwnx_hw, txpwr_ofst_req);
}
return (error);
}
int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter) int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter)
{ {
struct mm_set_filter_req *set_filter_req_param; struct mm_set_filter_req *set_filter_req_param;
@@ -3279,7 +3419,7 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par
#if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL) #if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL)
struct aic_sta *sta = &rwnx_hw->aic_table[rwnx_vif->ap.aic_index]; struct aic_sta *sta = &rwnx_hw->aic_table[rwnx_vif->ap.aic_index];
printk("assoc_req idx %d, he: %d, vht: %d\n ", rwnx_vif->ap.aic_index, sta->he, sta->vht); printk("assoc_req idx %d, he: %d, vht: %d\n ", rwnx_vif->ap.aic_index, sta->he, sta->vht);
if (rwnx_vif->ap.aic_index < NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX) if (rwnx_vif->ap.aic_index < (NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX - 1))
rwnx_vif->ap.aic_index++; rwnx_vif->ap.aic_index++;
else else
rwnx_vif->ap.aic_index = 0; rwnx_vif->ap.aic_index = 0;
@@ -3406,8 +3546,13 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par
req->flags |= STA_MFP_CAPA; req->flags |= STA_MFP_CAPA;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
if (link_sta_params->opmode_notif_used) { #if LINUX_VERSION_CODE < HIGH_KERNEL_VERSION
req->opmode = link_sta_params->opmode_notif_used; if (params->opmode_notif_used) {
req->opmode = params->opmode_notif;
#else
if (params->link_sta_params.opmode_notif_used) {
req->opmode = params->link_sta_params.opmode_notif;
#endif//LINUX_VERSION_CODE < HIGH_KERNEL_VERSION
req->flags |= STA_OPMOD_NOTIF; req->flags |= STA_OPMOD_NOTIF;
} }
#endif #endif
@@ -5038,6 +5183,54 @@ int rwnx_send_cfg_rssi_req(struct rwnx_hw *rwnx_hw, u8 vif_index, int rssi_thold
return rwnx_send_msg(rwnx_hw, req, 1, MM_CFG_RSSI_CFM, NULL); return rwnx_send_msg(rwnx_hw, req, 1, MM_CFG_RSSI_CFM, NULL);
} }
int rwnx_send_get_temp_req(struct rwnx_hw *rwnx_hw, s8_l *temp)
{
struct mm_get_chip_temp_req *hwreq;
struct mm_set_vendor_swconfig_req *swreq;
struct mm_set_vendor_hwconfig_cfm hwcfm;
struct mm_set_vendor_swconfig_cfm swcfm;
int ret = 0;
RWNX_DBG(RWNX_FN_ENTRY_STR);
if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC ||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){
/* Build the CHIP_TEMP_GET_REQ message */
hwreq = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_get_chip_temp_req));
if (!hwreq)
return -ENOMEM;
hwreq->hwconfig_id = CHIP_TEMP_GET_REQ;
/* Send the MM_SET_VENDOR_HWCONFIG_REQ message to UMAC FW */
ret = rwnx_send_msg(rwnx_hw, hwreq, 1, MM_SET_VENDOR_HWCONFIG_CFM, &hwcfm);
if (!ret) {
AICWFDBG(LOGINFO, "get_chip_temp degree=%d\n", hwcfm.chip_temp_cfm.degree);
*temp = hwcfm.chip_temp_cfm.degree;
} else {
AICWFDBG(LOGINFO, "get_chip_temp err=%d\n", ret);
return ret;
}
return ret;
} else if (rwnx_hw->usbdev->chipid >= PRODUCT_ID_AIC8800D80N) {
/* Build the TEMP_COMP_GET_REQ message */
swreq = rwnx_msg_zalloc(MM_SET_VENDOR_SWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_vendor_swconfig_req));
if (!swreq) {
AICWFDBG(LOGINFO, "%s msg_alloc fail\n", __func__);
return -ENOMEM;
}
swreq->swconfig_id = TEMP_COMP_GET_REQ;
ret = rwnx_send_msg(rwnx_hw, swreq, 1, MM_SET_VENDOR_SWCONFIG_CFM, &swcfm);
if (!ret) {
AICWFDBG(LOGINFO, "status=%d, temp=%d\n", swcfm.temp_comp_get_cfm.status, swcfm.temp_comp_get_cfm.degree);
*temp = swcfm.temp_comp_get_cfm.degree;
} else {
AICWFDBG(LOGINFO, "%s msg_fail\n", __func__);
return ret;
}
}
return ret;
}
//#ifdef CONFIG_USB_BT //#ifdef CONFIG_USB_BT
int rwnx_send_reboot(struct rwnx_hw *rwnx_hw) int rwnx_send_reboot(struct rwnx_hw *rwnx_hw)
{ {
@@ -5049,70 +5242,9 @@ int rwnx_send_reboot(struct rwnx_hw *rwnx_hw)
ret = rwnx_send_dbg_start_app_req(rwnx_hw, delay, HOST_START_APP_REBOOT); ret = rwnx_send_dbg_start_app_req(rwnx_hw, delay, HOST_START_APP_REBOOT);
return ret; return ret;
} }
int rwnx_send_pwm_init_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 mode, u8 run, u32 tmr_cnt,
u32 dty_cnt, u32 step_val, u8 gpio_en, u8 gpio_dir, u8 gpio_val)
{
struct dbg_pwm_init_req *pwm_init_req;
pwm_init_req = rwnx_msg_zalloc(DBG_PWM_INIT_REQ, TASK_DBG, DRV_TASK_ID,
sizeof(struct dbg_pwm_init_req));
if (!pwm_init_req)
return -ENOMEM;
pwm_init_req->pwm_gpidx = pwm_gpidx;
pwm_init_req->mode = mode;
pwm_init_req->run = run;
pwm_init_req->tmr_cnt = tmr_cnt;
pwm_init_req->dty_cnt = dty_cnt;
pwm_init_req->step_val = step_val;
pwm_init_req->gpio_en = gpio_en;
pwm_init_req->gpio_dir = gpio_dir;
pwm_init_req->gpio_val = gpio_val;
return rwnx_send_msg(rwnx_hw, pwm_init_req, 1, DBG_PWM_INIT_CFM, NULL);
}
int rwnx_send_pwm_deinit_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 gpio_en, u8 gpio_dir, u8 gpio_val)
{
struct dbg_pwm_deinit_req *pwm_deinit_req;
pwm_deinit_req = rwnx_msg_zalloc(DBG_PWM_DEINIT_REQ, TASK_DBG, DRV_TASK_ID,
sizeof(struct dbg_pwm_deinit_req));
if (!pwm_deinit_req)
return -ENOMEM;
pwm_deinit_req->pwm_gpidx = pwm_gpidx;
pwm_deinit_req->gpio_en = gpio_en;
pwm_deinit_req->gpio_dir = gpio_dir;
pwm_deinit_req->gpio_val = gpio_val;
return rwnx_send_msg(rwnx_hw, pwm_deinit_req, 1, DBG_PWM_DEINIT_CFM, NULL);
}
u32 pwm_tbl[][2] = {
{0x40504088, 4},
};
void rwnx_set_pwm_tbl(struct rwnx_hw *rwnx_hw)
{
int patch_num = 0;
int cnt = 0;
int ret = 0;
patch_num = sizeof(pwm_tbl) / sizeof(u32) / 2;
for (cnt = 0; cnt < patch_num; cnt++) {
ret = rwnx_send_dbg_mem_write_req(rwnx_hw, pwm_tbl[cnt][0], pwm_tbl[cnt][1]);
if (ret) {
break;
}
}
}
//#endif // CONFIG_USB_BT //#endif // CONFIG_USB_BT
#ifdef CONFIG_WOWLAN #ifdef CONFIG_WOWLAN
#ifndef ANDROID_PLATFORM
int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw) int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw)
{ {
int ret = 0; int ret = 0;
@@ -5124,3 +5256,4 @@ int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw)
return ret; return ret;
} }
#endif #endif
#endif
+8 -6
View File
@@ -67,6 +67,7 @@ int rwnx_send_arpoffload_en_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_v
u32_l ipaddr, u8_l enable); u32_l ipaddr, u8_l enable);
#endif #endif
int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l *tbl, u16_l len); int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l *tbl, u16_l len);
int rwnx_send_rf_config_v2_req(struct rwnx_hw *rwnx_hw, u16_l ofst, u8_l sel, u8_l *tbl, u16_l len);
int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm); int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cfm *cfm); int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cfm *cfm);
@@ -184,11 +185,13 @@ int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw);
int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw);
int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw);
int rwnx_send_txpwr_ofst2x_v2_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_ofst2x_v2_req(struct rwnx_hw *rwnx_hw);
int rwnx_send_txpwr_ofst2x_v3_req(struct rwnx_hw *rwnx_hw);
int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter); int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter);
int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw);
int rwnx_send_txpwr_lvl_v3_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_lvl_v3_req(struct rwnx_hw *rwnx_hw);
int rwnx_send_txpwr_lvl_v4_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_lvl_v4_req(struct rwnx_hw *rwnx_hw);
int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw);
int rwnx_send_txpwr_lvl_adj_v2_req(struct rwnx_hw *rwnx_hw);
#ifdef CONFIG_WOWLAN #ifdef CONFIG_WOWLAN
int rwnx_send_set_pkt_filter_req(struct rwnx_hw *rwnx_hw, u8_l *param); int rwnx_send_set_pkt_filter_req(struct rwnx_hw *rwnx_hw, u8_l *param);
int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw); int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw);
@@ -196,15 +199,14 @@ int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw);
#ifdef CONFIG_DYNAMIC_PERPWR #ifdef CONFIG_DYNAMIC_PERPWR
int rwnx_send_txpwr_per_sta_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta); int rwnx_send_txpwr_per_sta_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta);
#endif #endif
int rwnx_send_get_temp_req(struct rwnx_hw *rwnx_hw, s8_l *temp);
//#ifdef CONFIG_USB_BT //#ifdef CONFIG_USB_BT
int rwnx_send_reboot(struct rwnx_hw *rwnx_hw); int rwnx_send_reboot(struct rwnx_hw *rwnx_hw);
//#endif // CONFIG_USB_BT //#endif // CONFIG_USB_BT
struct rwnx_cmd *rwnx_cmd_malloc(void);
int rwnx_send_pwm_init_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 mode, u8 run, u32 tmr_cnt, void rwnx_cmd_free(struct rwnx_cmd *cmd);
u32 dty_cnt, u32 step_val, u8 gpio_en, u8 gpio_dir, u8 gpio_val); int rwnx_init_cmd_array(void);
int rwnx_send_pwm_deinit_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 gpio_en, u8 gpio_dir, u8 gpio_val); void rwnx_free_cmd_array(void);
void rwnx_set_pwm_tbl(struct rwnx_hw *rwnx_hw);
#endif /* _RWNX_MSG_TX_H_ */ #endif /* _RWNX_MSG_TX_H_ */
+1
View File
@@ -13,6 +13,7 @@
#include "rwnx_defs.h" #include "rwnx_defs.h"
#include "rwnx_dini.h" #include "rwnx_dini.h"
#include "rwnx_v7.h" #include "rwnx_v7.h"
#include "rwnx_pci.h"
#define PCI_VENDOR_ID_DINIGROUP 0x17DF #define PCI_VENDOR_ID_DINIGROUP 0x17DF
#define PCI_DEVICE_ID_DINIGROUP_DNV6_F2PCIE 0x1907 #define PCI_DEVICE_ID_DINIGROUP_DNV6_F2PCIE 0x1907
+268 -9
View File
@@ -34,6 +34,8 @@
#include "aicwf_compat_8800dc.h" #include "aicwf_compat_8800dc.h"
#include "aicwf_compat_8800d80.h" #include "aicwf_compat_8800d80.h"
#include "aicwf_compat_8800d80x2.h" #include "aicwf_compat_8800d80x2.h"
#include "aicwf_compat_8800d80n.h"
#include "aicwf_compat_8800dln.h"
#ifdef CONFIG_USE_FW_REQUEST #ifdef CONFIG_USE_FW_REQUEST
#include <linux/firmware.h> #include <linux/firmware.h>
#endif #endif
@@ -190,6 +192,15 @@ userconfig_info_t userconfig_info = {
.pwrofst2x_tbl_6g_ant0 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229 .pwrofst2x_tbl_6g_ant0 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229
.pwrofst2x_tbl_6g_ant1 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229 .pwrofst2x_tbl_6g_ant1 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229
}, },
.txpwr_ofst2x_v3 = {
.enable = 0,
.pwrofst2x_tbl_2g4 =
{ // ch1-4, ch5-9, ch10-13
{ 0, 0, 0 }, // 11b
{ 0, 0, 0 }, // ofdm_highrate
{ 0, 0, 0 }, // ofdm_lowrate
},
},
.xtal_cap = { .xtal_cap = {
.enable = 0, .enable = 0,
.xtal_cap = 24, .xtal_cap = 24,
@@ -248,6 +259,7 @@ reg_table reg_tables[] = {
{.ccode = "CL", .region = REGIONS_ETSI}, {.ccode = "CL", .region = REGIONS_ETSI},
{.ccode = "CO", .region = REGIONS_FCC}, {.ccode = "CO", .region = REGIONS_FCC},
{.ccode = "CR", .region = REGIONS_FCC}, {.ccode = "CR", .region = REGIONS_FCC},
{.ccode = "CU", .region = REGIONS_FCC},
{.ccode = "CX", .region = REGIONS_FCC}, {.ccode = "CX", .region = REGIONS_FCC},
{.ccode = "CY", .region = REGIONS_ETSI}, {.ccode = "CY", .region = REGIONS_ETSI},
{.ccode = "CZ", .region = REGIONS_ETSI}, {.ccode = "CZ", .region = REGIONS_ETSI},
@@ -272,7 +284,7 @@ reg_table reg_tables[] = {
{.ccode = "GL", .region = REGIONS_ETSI}, {.ccode = "GL", .region = REGIONS_ETSI},
{.ccode = "GP", .region = REGIONS_ETSI}, {.ccode = "GP", .region = REGIONS_ETSI},
{.ccode = "GR", .region = REGIONS_ETSI}, {.ccode = "GR", .region = REGIONS_ETSI},
{.ccode = "GT", .region = REGIONS_FCC}, {.ccode = "GT", .region = REGIONS_DEFAULT},
{.ccode = "GU", .region = REGIONS_FCC}, {.ccode = "GU", .region = REGIONS_FCC},
{.ccode = "GY", .region = REGIONS_DEFAULT}, {.ccode = "GY", .region = REGIONS_DEFAULT},
{.ccode = "HK", .region = REGIONS_ETSI}, {.ccode = "HK", .region = REGIONS_ETSI},
@@ -285,7 +297,7 @@ reg_table reg_tables[] = {
{.ccode = "IL", .region = REGIONS_ETSI}, {.ccode = "IL", .region = REGIONS_ETSI},
{.ccode = "IN", .region = REGIONS_ETSI}, {.ccode = "IN", .region = REGIONS_ETSI},
{.ccode = "IQ", .region = REGIONS_ETSI}, {.ccode = "IQ", .region = REGIONS_ETSI},
{.ccode = "IR", .region = REGIONS_JP}, {.ccode = "IR", .region = REGIONS_ETSI},
{.ccode = "IS", .region = REGIONS_ETSI}, {.ccode = "IS", .region = REGIONS_ETSI},
{.ccode = "IT", .region = REGIONS_ETSI}, {.ccode = "IT", .region = REGIONS_ETSI},
{.ccode = "JM", .region = REGIONS_FCC}, {.ccode = "JM", .region = REGIONS_FCC},
@@ -295,7 +307,7 @@ reg_table reg_tables[] = {
{.ccode = "KH", .region = REGIONS_ETSI}, {.ccode = "KH", .region = REGIONS_ETSI},
{.ccode = "KN", .region = REGIONS_ETSI}, {.ccode = "KN", .region = REGIONS_ETSI},
{.ccode = "KP", .region = REGIONS_JP}, {.ccode = "KP", .region = REGIONS_JP},
{.ccode = "KR", .region = REGIONS_ETSI}, {.ccode = "KR", .region = REGIONS_KCC},
{.ccode = "KW", .region = REGIONS_ETSI}, {.ccode = "KW", .region = REGIONS_ETSI},
{.ccode = "KY", .region = REGIONS_FCC}, {.ccode = "KY", .region = REGIONS_FCC},
{.ccode = "KZ", .region = REGIONS_DEFAULT}, {.ccode = "KZ", .region = REGIONS_DEFAULT},
@@ -339,7 +351,7 @@ reg_table reg_tables[] = {
{.ccode = "PF", .region = REGIONS_ETSI}, {.ccode = "PF", .region = REGIONS_ETSI},
{.ccode = "PG", .region = REGIONS_FCC}, {.ccode = "PG", .region = REGIONS_FCC},
{.ccode = "PH", .region = REGIONS_FCC}, {.ccode = "PH", .region = REGIONS_FCC},
{.ccode = "PK", .region = REGIONS_ETSI}, {.ccode = "PK", .region = REGIONS_DEFAULT},
{.ccode = "PL", .region = REGIONS_ETSI}, {.ccode = "PL", .region = REGIONS_ETSI},
{.ccode = "PM", .region = REGIONS_ETSI}, {.ccode = "PM", .region = REGIONS_ETSI},
{.ccode = "PR", .region = REGIONS_FCC}, {.ccode = "PR", .region = REGIONS_FCC},
@@ -361,7 +373,7 @@ reg_table reg_tables[] = {
{.ccode = "SN", .region = REGIONS_FCC}, {.ccode = "SN", .region = REGIONS_FCC},
{.ccode = "SR", .region = REGIONS_ETSI}, {.ccode = "SR", .region = REGIONS_ETSI},
{.ccode = "SV", .region = REGIONS_FCC}, {.ccode = "SV", .region = REGIONS_FCC},
{.ccode = "SY", .region = REGIONS_DEFAULT}, {.ccode = "SY", .region = REGIONS_ETSI},
{.ccode = "TC", .region = REGIONS_FCC}, {.ccode = "TC", .region = REGIONS_FCC},
{.ccode = "TD", .region = REGIONS_ETSI}, {.ccode = "TD", .region = REGIONS_ETSI},
{.ccode = "TG", .region = REGIONS_ETSI}, {.ccode = "TG", .region = REGIONS_ETSI},
@@ -372,6 +384,7 @@ reg_table reg_tables[] = {
{.ccode = "TR", .region = REGIONS_ETSI}, {.ccode = "TR", .region = REGIONS_ETSI},
{.ccode = "TT", .region = REGIONS_FCC}, {.ccode = "TT", .region = REGIONS_FCC},
{.ccode = "TW", .region = REGIONS_FCC}, {.ccode = "TW", .region = REGIONS_FCC},
{.ccode = "TZ", .region = REGIONS_ETSI},
{.ccode = "UA", .region = REGIONS_ETSI}, {.ccode = "UA", .region = REGIONS_ETSI},
{.ccode = "UG", .region = REGIONS_FCC}, {.ccode = "UG", .region = REGIONS_FCC},
{.ccode = "UY", .region = REGIONS_FCC}, {.ccode = "UY", .region = REGIONS_FCC},
@@ -382,10 +395,13 @@ reg_table reg_tables[] = {
{.ccode = "VN", .region = REGIONS_JP}, {.ccode = "VN", .region = REGIONS_JP},
{.ccode = "VU", .region = REGIONS_FCC}, {.ccode = "VU", .region = REGIONS_FCC},
{.ccode = "WF", .region = REGIONS_ETSI}, {.ccode = "WF", .region = REGIONS_ETSI},
{.ccode = "WS", .region = REGIONS_ETSI},
{.ccode = "YE", .region = REGIONS_DEFAULT}, {.ccode = "YE", .region = REGIONS_DEFAULT},
{.ccode = "YT", .region = REGIONS_ETSI}, {.ccode = "YT", .region = REGIONS_ETSI},
{.ccode = "ZA", .region = REGIONS_ETSI}, {.ccode = "ZA", .region = REGIONS_ETSI},
{.ccode = "ZM", .region = REGIONS_ETSI}, {.ccode = "ZM", .region = REGIONS_ETSI},
{.ccode = "FO", .region = REGIONS_ETSI},
{.ccode = "FK", .region = REGIONS_ETSI},
{.ccode = "ZW", .region = REGIONS_ETSI}, {.ccode = "ZW", .region = REGIONS_ETSI},
}; };
@@ -417,6 +433,8 @@ u8 get_region_index(char * name)
return REGIONS_ETSI; return REGIONS_ETSI;
else if (strncmp(name, "JP", 2) == 0) else if (strncmp(name, "JP", 2) == 0)
return REGIONS_JP; return REGIONS_JP;
else if (strncmp(name, "KCC", 3) == 0)
return REGIONS_KCC;
else if (strncmp(name, "UNSET", 5) == 0) else if (strncmp(name, "UNSET", 5) == 0)
return REGIONS_DEFAULT; return REGIONS_DEFAULT;
@@ -424,6 +442,7 @@ u8 get_region_index(char * name)
} }
#ifdef CONFIG_POWER_LIMIT #ifdef CONFIG_POWER_LIMIT
#define POWER_LIMIT_INVALID_VAL POWER_LEVEL_INVALID_VAL #define POWER_LIMIT_INVALID_VAL POWER_LEVEL_INVALID_VAL
@@ -431,7 +450,7 @@ u8 get_region_index(char * name)
#define MAX_2_4G_BW_NUM 2 #define MAX_2_4G_BW_NUM 2
#define MAX_5G_BW_NUM 3 #define MAX_5G_BW_NUM 3
#define MAX_REGION_NUM 5 #define MAX_REGION_NUM 6
typedef struct typedef struct
@@ -685,7 +704,7 @@ static int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *dev
} }
/* start to read from firmware file */ /* start to read from firmware file */
buffer = vmalloc(size); buffer = vmalloc(size + 1);
if (!buffer) { if (!buffer) {
*fw_buf = NULL; *fw_buf = NULL;
__putname(path); __putname(path);
@@ -700,6 +719,7 @@ static int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *dev
rdlen = kernel_read(fp, fp->f_pos, buffer, size); rdlen = kernel_read(fp, fp->f_pos, buffer, size);
#endif #endif
*((char*)buffer + size) = 0;
if (size != rdlen) { if (size != rdlen) {
AICWFDBG(LOGERROR, "%s: %s file rdlen invalid %d\n", __func__, name, (int)rdlen); AICWFDBG(LOGERROR, "%s: %s file rdlen invalid %d\n", __func__, name, (int)rdlen);
*fw_buf = NULL; *fw_buf = NULL;
@@ -836,6 +856,69 @@ int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
return err; return err;
} }
int rwnx_plat_bin_fw_upload_2_with_version(struct rwnx_hw *rwnx_hw, u32 fw_addr,
char *filename, char *version_str, int version_size)
{
int err = 0;
unsigned int i = 0, size;
u32 *dst = NULL;
/* Copy the file on the Embedded side */
AICWFDBG(LOGINFO, "### Upload %s firmware, @ = %x\n", filename, fw_addr);
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
if (!dst) {
AICWFDBG(LOGERROR, "No such file or directory\n");
return -1;
}
if (size <= 0) {
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
dst = NULL;
err = -1;
return -1;
}
AICWFDBG(LOGINFO, "size=%d, dst[0]=%x\n", size, dst[0]);
// get version if exist
if (version_str) {
char *bin_str = (char *)&dst[4];
int char_idx = 0;
for (char_idx = 0; char_idx < version_size; char_idx++) {
version_str[char_idx] = bin_str[char_idx];
if (bin_str[char_idx] == '\0') {
//break;
}
}
if (char_idx == version_size) {
version_str[version_size - 1] = '\0';
}
AICWFDBG(LOGINFO, "version_str=%s\n", version_str);
}
// upload
if (size > 512) {
for (; i < (size - 512); i += 512) {
//printk("wr blk 0: %p -> %x\r\n", dst + i / 4, fw_addr + i);
err = rwnx_send_dbg_mem_block_write_req(rwnx_hw, fw_addr + i, 512, dst + i / 4);
if (err) {
AICWFDBG(LOGERROR, "bin upload fail: %x, err:%d\r\n", fw_addr + i, err);
break;
}
}
}
if (!err && (i < size)) {
//printk("wr blk 1: %p -> %x\r\n", dst + i / 4, fw_addr + i);
err = rwnx_send_dbg_mem_block_write_req(rwnx_hw, fw_addr + i, size - i, dst + i / 4);
if (err) {
AICWFDBG(LOGERROR, "bin upload fail: %x, err:%d\r\n", fw_addr + i, err);
}
}
if (dst) {
rwnx_release_firmware_common(&dst);
}
return err;
}
#ifndef CONFIG_ROM_PATCH_EN #ifndef CONFIG_ROM_PATCH_EN
@@ -1723,8 +1806,52 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
return 1; // exit calib mode return 1; // exit calib mode
} }
} }
} else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) {
#ifndef ANDROID_PLATFORM
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80N");
#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
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800DLN");
#endif
if (testmode == FW_NORMAL_MODE) {
aicwf_patch_config_8800dln(rwnx_hw);
}
else if (testmode == FW_RFTEST_MODE) {
AICWFDBG(LOGINFO, "%s load rftest bin\n", __func__);
ret = aicwf_plat_rftest_load_8800dln(rwnx_hw);
if (ret) {
AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret);
return ret;
}
}
} }
return ret; return ret;
} }
#endif #endif
@@ -2242,6 +2369,16 @@ void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj)
AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_155:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[5]); AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_155:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[5]);
} }
void get_userconfig_txpwr_lvl_adj_v2_in_fdrv(txpwr_lvl_adj_conf_v2_t *txpwr_lvl_adj_v2)
{
*txpwr_lvl_adj_v2 = userconfig_info.txpwr_lvl_adj_v2;
AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_adj_v2->enable);
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_1_4:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[0]);
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_5_9:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[1]);
AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_10_13:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[2]);
}
void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst) void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst)
{ {
@@ -2311,6 +2448,23 @@ void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x
} }
AICWFDBG(LOGINFO, "\n"); AICWFDBG(LOGINFO, "\n");
} }
void get_userconfig_txpwr_ofst2x_v3_in_fdrv(txpwr_ofst2x_conf_v3_t *txpwr_ofst2x_v3)
{
int type, ch_grp;
*txpwr_ofst2x_v3 = userconfig_info.txpwr_ofst2x_v3;
AICWFDBG(LOGINFO, "%s:enable :%d\r\n", __func__, txpwr_ofst2x_v3->enable);
AICWFDBG(LOGINFO, "pwrofst2x 2.4g: [0]:11b, [1]:ofdm_highrate, [2]:ofdm_lowrate\n"
" chan=" "\t1-4" "\t5-9" "\t10-13");
for (type = 0; type < 3; type++) {
AICWFDBG(LOGINFO, "\n [%d] =", type);
for (ch_grp = 0; ch_grp < 3; ch_grp++) {
AICWFDBG(LOGINFO, "\t%d", txpwr_ofst2x_v3->pwrofst2x_tbl_2g4[type][ch_grp]);
}
}
AICWFDBG(LOGINFO, "\n");
}
void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss) void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss)
{ {
txpwr_loss->loss_enable_2g4 = userconfig_info.txpwr_loss.loss_enable_2g4; txpwr_loss->loss_enable_2g4 = userconfig_info.txpwr_loss.loss_enable_2g4;
@@ -2322,6 +2476,101 @@ void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss)
txpwr_loss->loss_enable_2g4, txpwr_loss->loss_value_2g4, txpwr_loss->loss_enable_2g4, txpwr_loss->loss_value_2g4,
txpwr_loss->loss_enable_5g, txpwr_loss->loss_value_5g); txpwr_loss->loss_enable_5g, txpwr_loss->loss_value_5g);
} }
s8_l get_txpwr_max(s8_l power)
{
int i=0;
if(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 ||
g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D89X2 ){
for (i = 0; i <= 11; i++){
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[i])
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[i];
}
for (i = 0; i <= 9; i++){
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[i])
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[i];
}
for (i = 0; i <= 11; i++){
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[i])
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[i];
}
for (i = 0; i <= 7; i++){
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[i])
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[i];
}
for (i = 0; i <= 9; i++){
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[i])
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[i];
}
for (i = 0; i <= 11; i++){
if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[i])
power = userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[i];
}
if ((userconfig_info.txpwr_loss.loss_enable_2g4 == 1) ||
(userconfig_info.txpwr_loss.loss_enable_5g == 1)) {
if (userconfig_info.txpwr_loss.loss_value_2g4 <
userconfig_info.txpwr_loss.loss_value_5g)
power += userconfig_info.txpwr_loss.loss_value_5g;
else
power += userconfig_info.txpwr_loss.loss_value_2g4;
}
}
else if (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81 ||
g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D80N){
for (i = 0; i <= 11; i++){
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[i])
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[i];
}
for (i = 0; i <= 9; i++){
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[i])
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[i];
}
for (i = 0; i <= 11; i++){
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[i])
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[i];
}
for (i = 4; i <= 11; i++){
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[i])
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[i];
}
for (i = 0; i <= 9; i++){
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[i])
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[i];
}
for (i = 0; i <= 11; i++){
if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[i])
power = userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[i];
}
if ((userconfig_info.txpwr_loss.loss_enable_2g4 == 1) ||
(userconfig_info.txpwr_loss.loss_enable_5g == 1)) {
if (userconfig_info.txpwr_loss.loss_value_2g4 <
userconfig_info.txpwr_loss.loss_value_5g)
power += userconfig_info.txpwr_loss.loss_value_5g;
else
power += userconfig_info.txpwr_loss.loss_value_2g4;
}
}else if(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DC || g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW){
for (i = 0; i <= 11; i++){
if(power < userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[i])
power = userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[i];
}
for (i = 0; i <= 9; i++){
if(power < userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[i])
power = userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[i];
}
for (i = 0; i <= 11; i++){
if(power < userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[i])
power = userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[i];
}
}
AICWFDBG(LOGINFO, "%s:txpwr_max:%d \r\n",__func__,power);
return power;
}
void set_txpwr_loss_ofst(s8_l value) void set_txpwr_loss_ofst(s8_l value)
{ {
userconfig_info.txpwr_loss.loss_enable_2g4 = 1; userconfig_info.txpwr_loss.loss_enable_2g4 = 1;
@@ -3115,7 +3364,7 @@ int8_t rwnx_plat_powerlimit_save(u8_l band, char *channel, u8_l bw, char *limit,
} }
void rwnx_plat_powerlimit_parsing(char *buffer, int size, char *cc) void rwnx_plat_powerlimit_parsing(char *buffer, int size)
{ {
#define LD_STAGE_EXC_MAPPING 0 #define LD_STAGE_EXC_MAPPING 0
#define LD_STAGE_TAB_DEFINE 1 #define LD_STAGE_TAB_DEFINE 1
@@ -3465,11 +3714,21 @@ static int rwnx_plat_userconfig_load(struct rwnx_hw *rwnx_hw) {
#ifdef CONFIG_POWER_LIMIT #ifdef CONFIG_POWER_LIMIT
rwnx_plat_powerlimit_load_8800dcdw(rwnx_hw, PRODUCT_ID_AIC8800DW); rwnx_plat_powerlimit_load_8800dcdw(rwnx_hw, PRODUCT_ID_AIC8800DW);
#endif #endif
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN){
rwnx_plat_userconfig_load_8800dln(rwnx_hw);
#ifdef CONFIG_POWER_LIMIT
rwnx_plat_powerlimit_load_8800dln(rwnx_hw);
#endif
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){ }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){
rwnx_plat_userconfig_load_8800d80(rwnx_hw); rwnx_plat_userconfig_load_8800d80(rwnx_hw);
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 ||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){
rwnx_plat_userconfig_load_8800d80x2(rwnx_hw); rwnx_plat_userconfig_load_8800d80x2(rwnx_hw);
}else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N){
rwnx_plat_userconfig_load_8800d80n(rwnx_hw);
#ifdef CONFIG_POWER_LIMIT
rwnx_plat_powerlimit_load_8800d80n(rwnx_hw);
#endif
} }
return 0; return 0;
+19 -1
View File
@@ -71,10 +71,12 @@ typedef struct
txpwr_lvl_conf_v3_t txpwr_lvl_v3; txpwr_lvl_conf_v3_t txpwr_lvl_v3;
txpwr_lvl_conf_v4_t txpwr_lvl_v4; txpwr_lvl_conf_v4_t txpwr_lvl_v4;
txpwr_lvl_adj_conf_t txpwr_lvl_adj; txpwr_lvl_adj_conf_t txpwr_lvl_adj;
txpwr_lvl_adj_conf_v2_t txpwr_lvl_adj_v2;
txpwr_loss_conf_t txpwr_loss; txpwr_loss_conf_t txpwr_loss;
txpwr_ofst_conf_t txpwr_ofst; txpwr_ofst_conf_t txpwr_ofst;
txpwr_ofst2x_conf_t txpwr_ofst2x; txpwr_ofst2x_conf_t txpwr_ofst2x;
txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2; txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2;
txpwr_ofst2x_conf_v3_t txpwr_ofst2x_v3;
xtal_cap_conf_t xtal_cap; xtal_cap_conf_t xtal_cap;
} userconfig_info_t; } userconfig_info_t;
@@ -85,6 +87,7 @@ typedef enum {
REGIONS_FCC, REGIONS_FCC,
REGIONS_ETSI, REGIONS_ETSI,
REGIONS_JP, REGIONS_JP,
REGIONS_KCC,
REGIONS_DEFAULT, REGIONS_DEFAULT,
} Regions_code; } Regions_code;
@@ -156,10 +159,13 @@ void get_userconfig_txpwr_lvl_v2_in_fdrv(txpwr_lvl_conf_v2_t *txpwr_lvl_v2);
void get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_conf_v3_t *txpwr_lvl_v3); void get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_conf_v3_t *txpwr_lvl_v3);
void get_userconfig_txpwr_lvl_v4_in_fdrv(txpwr_lvl_conf_v4_t *txpwr_lvl_v4); void get_userconfig_txpwr_lvl_v4_in_fdrv(txpwr_lvl_conf_v4_t *txpwr_lvl_v4);
void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj); void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj);
void get_userconfig_txpwr_lvl_adj_v2_in_fdrv(txpwr_lvl_adj_conf_v2_t *txpwr_lvl_adj_v2);
void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst); void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst);
void get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x_conf_t *txpwr_ofst2x); void get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x_conf_t *txpwr_ofst2x);
void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x_v2); void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x_v2);
void get_userconfig_txpwr_ofst2x_v3_in_fdrv(txpwr_ofst2x_conf_v3_t *txpwr_ofst2x_v3);
void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss); void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss);
s8_l get_txpwr_max(s8_l power);
void set_txpwr_loss_ofst(s8_l value); void set_txpwr_loss_ofst(s8_l value);
void rwnx_plat_userconfig_parsing(char *buffer, int size); void rwnx_plat_userconfig_parsing(char *buffer, int size);
@@ -169,7 +175,7 @@ u8 get_region_index(char * name);
#ifdef CONFIG_POWER_LIMIT #ifdef CONFIG_POWER_LIMIT
int8_t rwnx_plat_powerlimit_save(u8_l band, char *channel, u8_l bw, char *limit, char *name); int8_t rwnx_plat_powerlimit_save(u8_l band, char *channel, u8_l bw, char *limit, char *name);
void rwnx_plat_powerlimit_parsing(char *buffer, int size, char *cc); void rwnx_plat_powerlimit_parsing(char *buffer, int size);
int8_t get_powerlimit_by_freq(uint8_t band, uint16_t freq, uint8_t r_idx); int8_t get_powerlimit_by_freq(uint8_t band, uint16_t freq, uint8_t r_idx);
int8_t get_powerlimit_by_chnum(uint8_t chnum, uint8_t r_idx, uint8_t bw); int8_t get_powerlimit_by_chnum(uint8_t chnum, uint8_t r_idx, uint8_t bw);
#endif #endif
@@ -182,5 +188,17 @@ static inline unsigned int rwnx_platform_get_irq(struct rwnx_plat *rwnx_plat)
{ {
return rwnx_plat->pci_dev->irq; return rwnx_plat->pci_dev->irq;
} }
int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw, u32** buffer, const char *filename);
void rwnx_release_firmware_common(u32** buffer);
int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
char *filename);
int rwnx_plat_bin_fw_upload_2_with_version(struct rwnx_hw *rwnx_hw, u32 fw_addr,
char *filename, char *version_str, int version_size);
int rwnx_atoi2(char *value, int c_len);
int rwnx_atoi(char *value);
void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap);
void rwnx_plat_nvram_set_value(char *command, char *value);
void rwnx_plat_nvram_set_value_8800d80x2(char *command, char *value);
void rwnx_plat_userconfig_parsing_8800d80x2(char *buffer, int size);
#endif /* _RWNX_PLATFORM_H_ */ #endif /* _RWNX_PLATFORM_H_ */
+45 -49
View File
@@ -182,28 +182,27 @@ static const struct radar_types fcc_radar_types = {
}; };
#define JP_PATTERN FCC_PATTERN #define JP_PATTERN FCC_PATTERN
//JP_PATTERN(1, 2, 8, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT),
static const struct radar_detector_specs jp_radar_ref_types_riu[] = { static const struct radar_detector_specs jp_radar_ref_types_riu[] = {
JP_PATTERN(0, 0, 8, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT), JP_PATTERN(0, 0, 4, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT),
JP_PATTERN(1, 2, 8, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT), JP_PATTERN(1, 0, 4, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT),
JP_PATTERN(2, 0, 8, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT), JP_PATTERN(2, 0, 4, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT),
JP_PATTERN(3, 0, 8, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT), JP_PATTERN(3, 0, 6, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT),
JP_PATTERN(4, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT), JP_PATTERN(4, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT),
JP_PATTERN(5, 6, 20, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT), JP_PATTERN(5, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT),
JP_PATTERN(6, 10, 28, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT), JP_PATTERN(6, 48, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG),
JP_PATTERN(7, 50, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG), JP_PATTERN(7, 0, 4, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
JP_PATTERN(8, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
}; };
static const struct radar_detector_specs jp_radar_ref_types_fcu[] = { static const struct radar_detector_specs jp_radar_ref_types_fcu[] = {
JP_PATTERN(0, 0, 8, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT), JP_PATTERN(0, 0, 4, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT),
JP_PATTERN(1, 2, 6, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT), JP_PATTERN(1, 0, 4, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT),
JP_PATTERN(2, 0, 8, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT), JP_PATTERN(2, 0, 4, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT),
JP_PATTERN(3, 2, 2, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT), JP_PATTERN(3, 0, 6, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT),
JP_PATTERN(4, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT), JP_PATTERN(4, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT),
JP_PATTERN(5, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT), JP_PATTERN(5, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT),
JP_PATTERN(6, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT), JP_PATTERN(6, 48, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG),
JP_PATTERN(7, 50, 104, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG), JP_PATTERN(7, 0, 4, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
JP_PATTERN(8, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT),
}; };
static const struct radar_types jp_radar_types = { static const struct radar_types jp_radar_types = {
@@ -219,33 +218,6 @@ static const struct radar_types *dfs_domains[] = {
&jp_radar_types, &jp_radar_types,
}; };
/**
* struct pri_sequence - sequence of pulses matching one PRI
* @head: list_head
* @pri: pulse repetition interval (PRI) in usecs
* @dur: duration of sequence in usecs
* @count: number of pulses in this sequence
* @count_falses: number of not matching pulses in this sequence
* @first_ts: time stamp of first pulse in usecs
* @last_ts: time stamp of last pulse in usecs
* @deadline_ts: deadline when this sequence becomes invalid (first_ts + dur)
* @ppb_thresh: Number of pulses to validate detection
* (need for weather radar whose value depends of pri)
*/
struct pri_sequence {
struct list_head head;
u32 pri;
u32 dur;
u32 count;
u32 count_falses;
u64 first_ts;
u64 last_ts;
u64 deadline_ts;
u8 ppb_thresh;
};
/** /**
* struct pulse_elem - elements in pulse queue * struct pulse_elem - elements in pulse queue
* @ts: time stamp in usecs * @ts: time stamp in usecs
@@ -804,9 +776,9 @@ struct pri_sequence *pde_long_add_pulse(struct rwnx_radar *radar, struct pri_det
struct pri_sequence *ps; struct pri_sequence *ps;
const struct radar_detector_specs *rs = pde->rs; const struct radar_detector_specs *rs = pde->rs;
if(radar->status != RWNX_RADAR_CAC_BUSY) { //if(radar->status != RWNX_RADAR_CAC_BUSY) {
return NULL; // return NULL;
} //}
if (list_empty(&pde->sequences)) { if (list_empty(&pde->sequences)) {
/* First pulse, create a new sequence */ /* First pulse, create a new sequence */
@@ -1407,6 +1379,29 @@ static void rwnx_radar_process_pulse(struct work_struct *ws)
rm->ts[rm->idx] = dpd->last_pulse_ts + pri; rm->ts[rm->idx] = dpd->last_pulse_ts + pri;
} }
rm->idx = (rm->idx + 1) % RWNX_RADARR_DUMP_NB; rm->idx = (rm->idx + 1) % RWNX_RADARR_DUMP_NB;
if(rm->cnt == 1)
{
struct radar_detector_specs *spc;
int k;
AICWFDBG(LOGINFO, "dpd: en = %d, region = %d, ntype = %d", dpd->enabled, dpd->region, dpd->num_radar_types);
AICWFDBG(LOGINFO, "id wid.{min, max} pri.{min, max, num}, ppb, thd, tlrn, type");
for (k = 0; k < dpd->num_radar_types; k++)
{
spc =(struct radar_detector_specs *)&dpd->radar_spec[k];
AICWFDBG(LOGINFO, "%d %3d, %3d %4d %4d %d %2d %2d %d %d",
spc->type_id,
spc->width_min,
spc->width_max,
spc->pri_min,
spc->pri_max,
spc->num_pri,
spc->ppb,
spc->ppb_thresh,
spc->max_pri_tolerance,
spc->type);
}
}
} }
#endif #endif
if((radar->status != RWNX_RADAR_CAC_BUSY) && (radar->status != RWNX_RADAR_INSERVICE_BUSY)) { if((radar->status != RWNX_RADAR_CAC_BUSY) && (radar->status != RWNX_RADAR_INSERVICE_BUSY)) {
@@ -1602,6 +1597,7 @@ void rwnx_radar_start_cac(struct rwnx_radar *radar, u32 cac_time_ms,
{ {
WARN(radar->cac_vif != NULL, "CAC already in progress"); WARN(radar->cac_vif != NULL, "CAC already in progress");
radar->cac_vif = vif; radar->cac_vif = vif;
AICWFDBG(LOGINFO, "%s DFS: cac time = %u ms", __func__, cac_time_ms);
schedule_delayed_work(&radar->cac_work, msecs_to_jiffies(cac_time_ms)); schedule_delayed_work(&radar->cac_work, msecs_to_jiffies(cac_time_ms));
} }
@@ -1714,8 +1710,8 @@ int rwnx_radar_dump_pattern_detector(char *buf, size_t len,
} }
size_needed += sizeof(info); size_needed += sizeof(info);
return size_needed;
} }
return size_needed;
} }
/* */ /* */
+31
View File
@@ -32,6 +32,34 @@ enum rwnx_radar_detector {
radar to upper layer. */ radar to upper layer. */
}; };
/**
* struct pri_sequence - sequence of pulses matching one PRI
* @head: list_head
* @pri: pulse repetition interval (PRI) in usecs
* @dur: duration of sequence in usecs
* @count: number of pulses in this sequence
* @count_falses: number of not matching pulses in this sequence
* @first_ts: time stamp of first pulse in usecs
* @last_ts: time stamp of last pulse in usecs
* @deadline_ts: deadline when this sequence becomes invalid (first_ts + dur)
* @ppb_thresh: Number of pulses to validate detection
* (need for weather radar whose value depends of pri)
*/
struct pri_sequence {
struct list_head head;
u32 pri;
u32 dur;
u32 count;
u32 count_falses;
u64 first_ts;
u64 last_ts;
u64 deadline_ts;
u8 ppb_thresh;
};
#ifdef CONFIG_RWNX_RADAR #ifdef CONFIG_RWNX_RADAR
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
@@ -137,6 +165,9 @@ int rwnx_radar_dump_pattern_detector(char *buf, size_t len,
struct rwnx_radar *radar, u8 chain); struct rwnx_radar *radar, u8 chain);
int rwnx_radar_dump_radar_detected(char *buf, size_t len, int rwnx_radar_dump_radar_detected(char *buf, size_t len,
struct rwnx_radar *radar, u8 chain); struct rwnx_radar *radar, u8 chain);
struct pri_detector *pri_detector_init(struct dfs_pattern_detector *dpd,
u16 radar_type, u16 freq);
void print_radar_detect_info(struct pri_detector *pde, struct pri_sequence *ps);
#else #else
+138 -26
View File
@@ -812,6 +812,7 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
aicwf_nl_send_frame_rpt_msg(rwnx_vif, WIFI_AUTH, mgmt->sa, rxvect->rssi1); aicwf_nl_send_frame_rpt_msg(rwnx_vif, WIFI_AUTH, mgmt->sa, rxvect->rssi1);
} }
#if 0
if (ieee80211_is_probe_req(mgmt->frame_control)) { if (ieee80211_is_probe_req(mgmt->frame_control)) {
if (!rwnx_vif->ap.start) if (!rwnx_vif->ap.start)
return; return;
@@ -830,6 +831,7 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
AICWFDBG(LOGERROR, "usb probe_rsp pool full, drop %pM\n", mgmt->sa); AICWFDBG(LOGERROR, "usb probe_rsp pool full, drop %pM\n", mgmt->sa);
return; return;
} }
#endif
} }
#endif #endif
@@ -1308,7 +1310,7 @@ static void rwnx_rx_add_rtap_hdr(struct rwnx_hw* rwnx_hw,
// Check for HE frames // Check for HE frames
if (rxvect->format_mod == FORMATMOD_HE_SU) { if (rxvect->format_mod == FORMATMOD_HE_SU) {
struct ieee80211_radiotap_he he; struct ieee80211_radiotap_he he = {0};
#define HE_PREP(f, val) cpu_to_le16(FIELD_PREP(IEEE80211_RADIOTAP_HE_##f, val)) #define HE_PREP(f, val) cpu_to_le16(FIELD_PREP(IEEE80211_RADIOTAP_HE_##f, val))
#define D1_KNOWN(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_##f##_KNOWN) #define D1_KNOWN(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_##f##_KNOWN)
#define D2_KNOWN(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_##f##_KNOWN) #define D2_KNOWN(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_##f##_KNOWN)
@@ -1364,8 +1366,18 @@ static void rwnx_rx_add_rtap_hdr(struct rwnx_hw* rwnx_hw,
while ((pos - (u8 *)rtap) & 1) while ((pos - (u8 *)rtap) & 1)
pos++; pos++;
rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_HE); rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_HE);
memcpy(pos, &he, sizeof(he)); put_unaligned_le16(le16_to_cpu(he.data1), pos);
pos += sizeof(he); pos += 2;
put_unaligned_le16(le16_to_cpu(he.data2), pos);
pos += 2;
put_unaligned_le16(le16_to_cpu(he.data3), pos);
pos += 2;
put_unaligned_le16(le16_to_cpu(he.data4), pos);
pos += 2;
put_unaligned_le16(le16_to_cpu(he.data5), pos);
pos += 2;
put_unaligned_le16(le16_to_cpu(he.data6), pos);
pos += 2;
} }
// Rx Chains // Rx Chains
@@ -1833,8 +1845,7 @@ bool reord_rxframes_process(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *pr
return bPktInBuf; return bPktInBuf;
} }
void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv, void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *preorder_ctrl)
struct reord_ctrl *preorder_ctrl)
{ {
struct list_head *phead, *plist; struct list_head *phead, *plist;
struct recv_msdu *prframe; struct recv_msdu *prframe;
@@ -1927,8 +1938,6 @@ int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv,
struct reord_ctrl_info *reord_info; struct reord_ctrl_info *reord_info;
struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif; struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif;
struct ethhdr *eh = (struct ethhdr *)(skb->data); struct ethhdr *eh = (struct ethhdr *)(skb->data);
u8 *da = eh->h_dest;
u8 is_mcast = ((*da) & 0x01)? 1 : 0;
#if 0 #if 0
struct recv_msdu *pframe; struct recv_msdu *pframe;
@@ -1949,7 +1958,7 @@ int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv,
preorder_ctrl = pframe->preorder_ctrl; preorder_ctrl = pframe->preorder_ctrl;
pframe->is_amsdu = is_amsdu; pframe->is_amsdu = is_amsdu;
if ((ntohs(eh->h_proto) == ETH_P_PAE) || is_mcast) if (ntohs(eh->h_proto) == ETH_P_PAE)
return reord_single_frame_ind(rx_priv, pframe); return reord_single_frame_ind(rx_priv, pframe);
if((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) if((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
@@ -2127,7 +2136,10 @@ void remove_sec_hdr_mgmt_frame(struct hw_rxhdr *hw_rxhdr,struct sk_buff *skb)
if(!hw_rxhdr->hwvect.ga_frame){ if(!hw_rxhdr->hwvect.ga_frame){
if(((skb->data[0] & 0x0C) == 0) && (skb->data[1] & 0x40) == 0x40){ //protect management frame if(((skb->data[0] & 0x0C) == 0) && (skb->data[1] & 0x40) == 0x40){ //protect management frame
printk("frame type %x\n",skb->data[0]); printk("frame type %x\n",skb->data[0]);
if(hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_CCMP128){ if((hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_CCMP128) ||
(hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_CCMP256) ||
(hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_GCMP128) ||
(hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_GCMP256)) {
memcpy(mgmt_header,skb->data,hdr_len); memcpy(mgmt_header,skb->data,hdr_len);
skb_pull(skb,8); skb_pull(skb,8);
memcpy(skb->data,mgmt_header,hdr_len); memcpy(skb->data,mgmt_header,hdr_len);
@@ -2250,7 +2262,14 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
u8 is_amsdu = 0; u8 is_amsdu = 0;
bool resend = false, forward = true; bool resend = false, forward = true;
const struct ethhdr *eth; const struct ethhdr *eth;
#ifdef CONFIG_SUPPORT_4ADDR
u8_l b_4addr = 0;
#endif
#ifdef CONFIG_BR_SUPPORT
int vif_idx;
struct rwnx_vif *vif_itr = NULL;
struct rwnx_sta *cur_sta;
#endif
REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_RWNXDATAIND); REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_RWNXDATAIND);
hw_rxhdr = (struct hw_rxhdr *)skb->data; hw_rxhdr = (struct hw_rxhdr *)skb->data;
@@ -2333,8 +2352,8 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
#endif #endif
} }
skb_reset_tail_pointer(skb); //skb_reset_tail_pointer(skb);
skb->len = 0; //skb->len = 0;
skb_reset_tail_pointer(skb_monitor); skb_reset_tail_pointer(skb_monitor);
skb_monitor->len = 0; skb_monitor->len = 0;
skb_put(skb_monitor, frm_len); skb_put(skb_monitor, frm_len);
@@ -2389,8 +2408,26 @@ check_len_update:
rwnx_rx_vector_convert(rwnx_hw, rwnx_rx_vector_convert(rwnx_hw,
&hw_rxhdr->hwvect.rx_vect1, &hw_rxhdr->hwvect.rx_vect1,
&hw_rxhdr->hwvect.rx_vect2); &hw_rxhdr->hwvect.rx_vect2);
#ifndef CONFIG_SUPPORT_4ADDR
if (hw_rxhdr->flags_is_4addr) {
dev_err(rwnx_hw->dev, "4addr Frame received (%d), skb->len:%u\n", hw_rxhdr->flags_vif_idx, skb->len);
print_hex_dump(KERN_ERR,"4addr ",DUMP_PREFIX_NONE, 16, 1, skb->data, skb->len, false);
dev_kfree_skb(skb);
goto end;
}
#endif
skb_pull(skb, msdu_offset + 2); //+2 since sdio allign 58->60 skb_pull(skb, msdu_offset + 2); //+2 since sdio allign 58->60
#define MAC_FCTRL_MOREFRAG 0x0400 #define MAC_FCTRL_MOREFRAG 0x0400
#ifdef CONFIG_SUPPORT_4ADDR
if (hw_rxhdr->flags_is_4addr) {
hdr_len += 6;
b_4addr = 1;
}
#endif
frame_ctrl = (skb->data[1] << 8) | skb->data[0]; frame_ctrl = (skb->data[1] << 8) | skb->data[0];
seq_num = ((skb->data[22] & 0xf0) >> 4) | (skb->data[23] << 4); seq_num = ((skb->data[22] & 0xf0) >> 4) | (skb->data[23] << 4);
frag_num = (skb->data[22] & 0x0f); frag_num = (skb->data[22] & 0x0f);
@@ -2398,28 +2435,86 @@ check_len_update:
if ((skb->data[0] & 0x0f) == 0x08) { if ((skb->data[0] & 0x0f) == 0x08) {
if ((skb->data[0] & 0x80) == 0x80) {//qos data if ((skb->data[0] & 0x80) == 0x80) {//qos data
hdr_len = 26; hdr_len += 2;
#ifdef CONFIG_SUPPORT_4ADDR
tid = b_4addr ? (skb->data[30] & 0x0F) : (skb->data[24] & 0x0F);
#else
tid = skb->data[24] & 0x0F; tid = skb->data[24] & 0x0F;
#endif
is_qos = 1; is_qos = 1;
#ifdef CONFIG_SUPPORT_4ADDR
if (b_4addr) {
if (skb->data[30] & 0x80)
is_amsdu = 1;
} else {
if (skb->data[24] & 0x80) if (skb->data[24] & 0x80)
is_amsdu = 1; is_amsdu = 1;
} }
#else
if (skb->data[24] & 0x80)
is_amsdu = 1;
#endif
}
if(skb->data[1] & 0x80)// htc if(skb->data[1] & 0x80)// htc
hdr_len += 4; hdr_len += 4;
if((skb->data[1] & 0x3) == 0x1) {// to ds #ifdef CONFIG_SUPPORT_4ADDR
memcpy(ra, &skb->data[16], MAC_ADDR_LEN);//destination addr if (b_4addr) {
memcpy(ta, &skb->data[10], MAC_ADDR_LEN);//source addr if ((skb->data[1] & 0x3) != 0x3) {
} else if((skb->data[1] & 0x3) == 0x2) { //from ds printk("aicwf: 4addr DS error, to_from ds:%d\n", skb->data[1] & 0x3);
memcpy(ta, &skb->data[16], MAC_ADDR_LEN);//destination addr print_hex_dump(KERN_ERR,"rx_4addr ",DUMP_PREFIX_NONE, 16, 1, skb->data, skb->len, false);
memcpy(ra, &skb->data[4], MAC_ADDR_LEN);//BSSID
} }
memcpy(ra, &skb->data[16], MAC_ADDR_LEN);
memcpy(ta, &skb->data[24], MAC_ADDR_LEN);
printk("aicwf 4addr: da: %pM, sa: %pM\n", ra, ta);
} else {
//printk("aicwf: to_from ds:%d\n", skb->data[1] & 0x3);
if((skb->data[1] & 0x3) == 0x1) {// to ds
memcpy(ra, &skb->data[16], MAC_ADDR_LEN);
memcpy(ta, &skb->data[10], MAC_ADDR_LEN);
} else if((skb->data[1] & 0x3) == 0x2) { //from ds
memcpy(ta, &skb->data[16], MAC_ADDR_LEN);
memcpy(ra, &skb->data[4], MAC_ADDR_LEN);
}
}
#else
if((skb->data[1] & 0x3) == 0x1) {// to ds
memcpy(ra, &skb->data[16], MAC_ADDR_LEN);
memcpy(ta, &skb->data[10], MAC_ADDR_LEN);
} else if((skb->data[1] & 0x3) == 0x2) { //from ds
memcpy(ta, &skb->data[16], MAC_ADDR_LEN);
memcpy(ra, &skb->data[4], MAC_ADDR_LEN);
}
#endif
#ifdef CONFIG_BR_SUPPORT
if((skb->data[1] & 0x3) == 0x2) {
for (vif_idx = 0; vif_idx < NX_VIRT_DEV_MAX; vif_idx++) {
vif_itr = rwnx_hw->vif_table[vif_idx];
if (vif_itr && vif_itr->up && RWNX_VIF_TYPE(vif_itr) == NL80211_IFTYPE_AP) {
spin_lock_bh(&vif_itr->rwnx_hw->cb_lock);
list_for_each_entry(cur_sta, &vif_itr->ap.sta_list, list) {
if (!memcmp(cur_sta->mac_addr, ta, MAC_ADDR_LEN)) {
//printk("aicwf filter out, %pM\n", ta);
dev_kfree_skb(skb);
spin_unlock_bh(&vif_itr->rwnx_hw->cb_lock);
goto end;
}
}
spin_unlock_bh(&vif_itr->rwnx_hw->cb_lock);
}
}
}
#endif
pull_len += (hdr_len + 8); pull_len += (hdr_len + 8);
switch (hw_rxhdr->hwvect.decr_status) { switch (hw_rxhdr->hwvect.decr_status) {
case RWNX_RX_HD_DECR_CCMP128: case RWNX_RX_HD_DECR_CCMP128:
case RWNX_RX_HD_DECR_CCMP256:
case RWNX_RX_HD_DECR_GCMP128:
case RWNX_RX_HD_DECR_GCMP256:
pull_len += 8;//ccmp_header pull_len += 8;//ccmp_header
//skb_pull(&skb->data[skb->len-8], 8); //ccmp_mic_len //skb_pull(&skb->data[skb->len-8], 8); //ccmp_mic_len
memcpy(ether_type, &skb->data[hdr_len + 6 + 8], 2); memcpy(ether_type, &skb->data[hdr_len + 6 + 8], 2);
@@ -2441,17 +2536,33 @@ check_len_update:
memcpy(ether_type, &skb->data[hdr_len + 6], 2); memcpy(ether_type, &skb->data[hdr_len + 6], 2);
break; break;
} }
if((ether_type[0] == 0x8e && ether_type[1] == 0x88) || (ether_type[0] == 0x88 && ether_type[1] == 0x8e))
printk("rx eapol\n");
if (is_amsdu) {
//Check NETGEAR R7000 router's AMSDU packet format for compliance. start
AICWFDBG(LOGDEBUG, "%s is amsdu pkt pull_len:%d %x %x %x\r\n", __func__,
pull_len, skb->data[pull_len - 8],
skb->data[pull_len - 7],
skb->data[pull_len - 2]);
if (skb->data[pull_len - 8] == 0xAA &&
skb->data[pull_len - 7] == 0xAA &&
skb->data[pull_len - 2] > 0x06){
AICWFDBG(LOGERROR, "%s amsdu pkt not regular \r\n", __func__);
is_amsdu = 0;
}else{
skb_pull(skb, pull_len-8);
}
//Check NETGEAR R7000 router's AMSDU packet format for compliance. end
}
if(is_amsdu) if(is_amsdu)
hw_rxhdr->flags_is_amsdu = 1; hw_rxhdr->flags_is_amsdu = 1;
else else
hw_rxhdr->flags_is_amsdu = 0; hw_rxhdr->flags_is_amsdu = 0;
if((ether_type[0] == 0x8e && ether_type[1] == 0x88) || (ether_type[0] == 0x88 && ether_type[1] == 0x8e))
printk("rx eapol\n");
if (is_amsdu) {
skb_pull(skb, pull_len-8);
}
if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA) if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA)
sta_idx = hw_rxhdr->flags_dst_idx; sta_idx = hw_rxhdr->flags_dst_idx;
@@ -2629,6 +2740,7 @@ check_len_update:
} }
if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) { if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) {
printk("aicwf: 4addr flag error\n");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev, cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
sta->mac_addr, -1, GFP_ATOMIC); sta->mac_addr, -1, GFP_ATOMIC);
@@ -2675,7 +2787,7 @@ check_len_update:
#ifdef CONFIG_DYNAMIC_PERPWR #ifdef CONFIG_DYNAMIC_PERPWR
sta = &rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx]; sta = &rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx];
rssi_update_txpwrloss(sta, hw_rxhdr->hwvect.rx_vect1.rssi1); rssi_update_txpwrloss(sta, hw_rxhdr->hwvect.rx_vect1.rssi1, rwnx_vif);
#endif #endif
#ifdef CONFIG_BAND_STEERING #ifdef CONFIG_BAND_STEERING
(&rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx])->rssi = hw_rxhdr->hwvect.rx_vect1.rssi1; (&rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx])->rssi = hw_rxhdr->hwvect.rx_vect1.rssi1;
+14
View File
@@ -353,10 +353,15 @@ struct DHCPInfo {
u8 options[308]; /* 312 - cookie */ u8 options[308]; /* 312 - cookie */
}; };
int reord_flush_tid(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u8 tid);
bool reord_rxframes_process(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *preorder_ctrl, int bforced);
u8 rwnx_unsup_rx_vec_ind(void *pthis, void *hostid); u8 rwnx_unsup_rx_vec_ind(void *pthis, void *hostid);
u8 rwnx_rxdataind(void *pthis, void *hostid); u8 rwnx_rxdataind(void *pthis, void *hostid);
u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv); u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv);
int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv); int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv);
void rwnx_rx_data_skb_resend(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, struct sk_buff *skb);
#ifdef CONFIG_USB_MSG_IN_EP #ifdef CONFIG_USB_MSG_IN_EP
int aicwf_process_msg_rxframes(struct aicwf_rx_priv *rx_priv); int aicwf_process_msg_rxframes(struct aicwf_rx_priv *rx_priv);
#endif #endif
@@ -373,11 +378,20 @@ int reord_need_check(struct reord_ctrl *preorder_ctrl, u16 seq_num);
int reord_rxframe_enqueue(struct reord_ctrl *preorder_ctrl, struct recv_msdu *prframe); int reord_rxframe_enqueue(struct reord_ctrl *preorder_ctrl, struct recv_msdu *prframe);
void reord_timeout_worker(struct work_struct *work); void reord_timeout_worker(struct work_struct *work);
int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prframe); int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prframe);
void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *preorder_ctrl);
void remove_sec_hdr_mgmt_frame(struct hw_rxhdr *hw_rxhdr,struct sk_buff *skb);
int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 seq_num, u8 tid, u8 forward, u8 is_amsdu);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
void reord_timeout_handler (ulong data); void reord_timeout_handler (ulong data);
#else #else
void reord_timeout_handler (struct timer_list *t); void reord_timeout_handler (struct timer_list *t);
#endif #endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
void defrag_timeout_cb(ulong data);
#else
void defrag_timeout_cb(struct timer_list *t);
#endif
#endif #endif
void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx, void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx,
+9
View File
@@ -115,12 +115,21 @@ rwnx_prep_tdls_direct(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
switch (action_code) { switch (action_code) {
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
skb_put(skb, 1 + sizeof(mgmt->u.action.tdls_discover_resp));
mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token;
mgmt->u.action.tdls_discover_resp.capability =
cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code));
#else
skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp)); skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
mgmt->u.action.u.tdls_discover_resp.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES; mgmt->u.action.u.tdls_discover_resp.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
mgmt->u.action.u.tdls_discover_resp.dialog_token = dialog_token; mgmt->u.action.u.tdls_discover_resp.dialog_token = dialog_token;
mgmt->u.action.u.tdls_discover_resp.capability = mgmt->u.action.u.tdls_discover_resp.capability =
cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code)); cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code));
#endif
break; break;
default: default:
return -EINVAL; return -EINVAL;
+5 -5
View File
@@ -1833,7 +1833,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
return 0; return 0;
} }
#ifdef CONFIG_BAND_STEERING #if 0//def CONFIG_BAND_STEERING
void rwnx_probersp_work(struct work_struct *work) void rwnx_probersp_work(struct work_struct *work)
{ {
struct ap_probe_rsp *rsp = container_of(work, struct ap_probe_rsp, rsp_work); struct ap_probe_rsp *rsp = container_of(work, struct ap_probe_rsp, rsp_work);
@@ -1841,7 +1841,6 @@ void rwnx_probersp_work(struct work_struct *work)
struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw;
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
struct rwnx_bcn *bcn = &rwnx_vif->ap.bcn; struct rwnx_bcn *bcn = &rwnx_vif->ap.bcn;
unsigned int len = bcn->len;
u8_l *buf; u8_l *buf;
struct ieee80211_mgmt *mgmt; struct ieee80211_mgmt *mgmt;
bool robust; bool robust;
@@ -1852,13 +1851,13 @@ void rwnx_probersp_work(struct work_struct *work)
struct rwnx_sw_txhdr *sw_txhdr; struct rwnx_sw_txhdr *sw_txhdr;
struct txdesc_api *desc; struct txdesc_api *desc;
headroom = sizeof(struct rwnx_txhdr); headroom = sizeof(struct rwnx_txhdr);
frame_len = len; frame_len = bcn->len;
if (aicwf_band_steering_block_chk(rwnx_vif, rsp->da)) { if (aicwf_band_steering_block_chk(rwnx_vif, rsp->da)) {
AICWFDBG(LOGSTEER, "usb %s, %d, probe_rsp refuse temp %pM\n", __func__, rwnx_vif->ap.freq, rsp->da); AICWFDBG(LOGSTEER, "usb %s, %d, probe_rsp refuse temp %pM\n", __func__, rwnx_vif->ap.freq, rsp->da);
goto free_use; goto free_use;
} }
if (!bcn->head || bcn->head_len == 0 || bcn->head_len > frame_len) { if (frame_len == 0 || !bcn->head || bcn->head_len == 0 || bcn->head_len > frame_len) {
AICWFDBG(LOGSTEER, "%s bcn head NULL\n", __func__); AICWFDBG(LOGSTEER, "%s bcn head NULL\n", __func__);
goto free_use; goto free_use;
} }
@@ -2347,7 +2346,8 @@ int rwnx_txdatacfm(void *pthis, void *host_id)
/* Check status in the header. If status is null, it means that the buffer /* Check status in the header. If status is null, it means that the buffer
* was not transmitted and we have to return immediately */ * was not transmitted and we have to return immediately */
if (rwnx_txst.value == 0) { if (rwnx_txst.value == 0) {
return -1; //return -1;
rwnx_txst.tx_done = 1;
} }
#ifdef AICWF_USB_SUPPORT #ifdef AICWF_USB_SUPPORT
+4 -1
View File
@@ -17,6 +17,7 @@
#include "ipc_shared.h" #include "ipc_shared.h"
#include "rwnx_txq.h" #include "rwnx_txq.h"
#include "hal_desc.h" #include "hal_desc.h"
#include "aicwf_tcp_ack.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
#define IEEE80211_NUM_TIDS 16 #define IEEE80211_NUM_TIDS 16
@@ -197,6 +198,8 @@ void rwnx_tx_push(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr, int flags);
#ifdef CONFIG_BAND_STEERING #ifdef CONFIG_BAND_STEERING
void rwnx_probersp_work(struct work_struct *work); void rwnx_probersp_work(struct work_struct *work);
#endif #endif
#ifdef CONFIG_FILTER_TCP_ACK
int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg);
#endif
#endif /* _RWNX_TX_H_ */ #endif /* _RWNX_TX_H_ */
+1
View File
@@ -393,5 +393,6 @@ void rwnx_txq_confirm_any(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq,
void rwnx_hwq_init(struct rwnx_hw *rwnx_hw); void rwnx_hwq_init(struct rwnx_hw *rwnx_hw);
void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq); void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq);
void rwnx_hwq_process_all(struct rwnx_hw *rwnx_hw); void rwnx_hwq_process_all(struct rwnx_hw *rwnx_hw);
void rwnx_txq_flush(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq);
#endif /* _RWNX_TXQ_H_ */ #endif /* _RWNX_TXQ_H_ */
@@ -131,6 +131,7 @@ struct rwnx_ipc_rxbuf_elems {
struct sk_buff *skb[RWNX_RXBUFF_MAX]; struct sk_buff *skb[RWNX_RXBUFF_MAX];
int idx; int idx;
}; };
int rwnx_init_aic(struct rwnx_hw *rwnx_hw);
#endif /* CONFIG_RWNX_FULLMAC */ #endif /* CONFIG_RWNX_FULLMAC */
#endif /* _RWNX_IPC_UTILS_H_ */ #endif /* _RWNX_IPC_UTILS_H_ */
@@ -1,5 +1,5 @@
#define RWNX_VERS_REV "1a4b0054d2M (master)" #define RWNX_VERS_REV "1a4b0054d2M (master)"
#define RWNX_VERS_MOD "6.4.3.0" #define RWNX_VERS_MOD "6.4.3.0"
#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)" #define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)"
#define RELEASE_DATE "2025_1018_71b66e7b" #define RELEASE_DATE "2026_0123_5f7be68d"
+1
View File
@@ -39,5 +39,6 @@ extern void aicwf_usb_host_txdesc_push(struct usb_host_env_tag *env, const int q
extern void aicwf_usb_host_tx_cfm_handler(struct usb_host_env_tag *env, u32 *data); extern void aicwf_usb_host_tx_cfm_handler(struct usb_host_env_tag *env, u32 *data);
extern int aicwf_rwnx_usb_platform_init(struct aic_usb_dev *usbdev); extern int aicwf_rwnx_usb_platform_init(struct aic_usb_dev *usbdev);
volatile struct txdesc_host *aicwf_usb_host_txdesc_get(struct usb_host_env_tag *env, const int queue_idx);
#endif #endif
+15 -8
View File
@@ -7,14 +7,16 @@ CONFIG_M2D_OTA_AUTO_SUPPORT = n
CONFIG_LINK_DET_5G = y CONFIG_LINK_DET_5G = y
CONFIG_FOR_IPCAM = n CONFIG_FOR_IPCAM = n
CONFIG_USB_SUSPEND_REBOOT_TIME = n CONFIG_USB_SUSPEND_REBOOT_TIME = n
CONFIG_SUPPORT_USB_SUSP = n
CONFIG_RADAR_OR_IR_DETECT =n CONFIG_RADAR_OR_IR_DETECT =n
CONFIG_LOAD_BT_CONF = n
CONFIG_FLASH_CALRES = n
CONFIG_WOWLAN ?= n
# Need to set fw path in BOARD_KERNEL_CMDLINE # Need to set fw path in BOARD_KERNEL_CMDLINE
CONFIG_USE_FW_REQUEST ?= n CONFIG_USE_FW_REQUEST ?= n
CONFIG_PREALLOC_RX_SKB ?= n CONFIG_PREALLOC_RX_SKB ?= n
CONFIG_PREALLOC_TXQ ?= y CONFIG_PREALLOC_TXQ ?= y
CONFIG_BAND_STEERING = n CONFIG_BAND_STEERING = n
CONFIG_PRBREQ_REPORT = n
# Platform support list # Platform support list
CONFIG_PLATFORM_ROCKCHIP ?= n CONFIG_PLATFORM_ROCKCHIP ?= n
@@ -44,7 +46,11 @@ ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ
ccflags-$(CONFIG_USB_SUSPEND_REBOOT_TIME) += -DCONFIG_USB_SUSPEND_REBOOT_TIME ccflags-$(CONFIG_USB_SUSPEND_REBOOT_TIME) += -DCONFIG_USB_SUSPEND_REBOOT_TIME
ccflags-$(CONFIG_SUPPORT_USB_SUSP) += -DCONFIG_SUPPORT_USB_SUSP ccflags-$(CONFIG_SUPPORT_USB_SUSP) += -DCONFIG_SUPPORT_USB_SUSP
ccflags-$(CONFIG_RADAR_OR_IR_DETECT) += -DCONFIG_RADAR_OR_IR_DETECT ccflags-$(CONFIG_RADAR_OR_IR_DETECT) += -DCONFIG_RADAR_OR_IR_DETECT
ccflags-$(CONFIG_LOAD_BT_CONF) += -DCONFIG_LOAD_BT_CONF
ccflags-$(CONFIG_FLASH_CALRES) += -DCONFIG_FLASH_CALRES
ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING
ccflags-$(CONFIG_PRBREQ_REPORT) += -DCONFIG_PRBREQ_REPORT
ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN
obj-$(CONFIG_AIC_LOADFW_SUPPORT) := $(MODULE_NAME).o obj-$(CONFIG_AIC_LOADFW_SUPPORT) := $(MODULE_NAME).o
$(MODULE_NAME)-y := aic_bluetooth_main.o \ $(MODULE_NAME)-y := aic_bluetooth_main.o \
@@ -67,7 +73,7 @@ ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
#ARCH ?= arm #ARCH ?= arm
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- #CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
KDIR := /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/kernel KDIR := /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/kernel
ARCH ?=$(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/) ARCH ?= arm
CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
#KDIR := /home/yaya/E/Rockchip/3399/rk3399-android-10/kernel #KDIR := /home/yaya/E/Rockchip/3399/rk3399-android-10/kernel
#ARCH ?= arm64 #ARCH ?= arm64
@@ -91,12 +97,13 @@ endif
ifeq ($(CONFIG_PLATFORM_UBUNTU), y) ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU
KVER := $(or $(KVER), $(kernelver), $(KERNELRELEASE), $(shell uname -r)) KVER ?= $(shell uname -r)
KDIR ?= /lib/modules/$(KVER)/build KDIR ?= /lib/modules/$(KVER)/build
PWD ?= $(shell pwd) PWD := $(shell pwd)
MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800 MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/) SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
CROSS_COMPILE ?= ARCH ?= $(SUBARCH)
CROSS_COMPILE :=
endif endif
@@ -44,21 +44,30 @@ typedef struct {
#define USER_TX_USE_ANA_F_FLAG (0x01U << 2) #define USER_TX_USE_ANA_F_FLAG (0x01U << 2)
#define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3) #define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3)
#define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4) #define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4)
#define USER_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 #define USER_EXT_FLAGS_DEFAULT_D80 (USER_PWROFST_COVER_CALIB_FLAG)
#ifdef CONFIG_POWER_LIMIT
#define CFG_USER_CHAN_MAX_TXPWR_EN 1
#else
#define CFG_USER_CHAN_MAX_TXPWR_EN 0
#endif
#define CFG_USER_TX_USE_ANA_F 0
#ifdef CONFIG_BAND_STEERING
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 1
#else
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 0
#endif
#define CFG_USER_EXT_FLAGS_EN (CFG_PWROFST_COVER_CALIB || CFG_USER_CHAN_MAX_TXPWR_EN || CFG_USER_TX_USE_ANA_F|| CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE) #define CFG_USER_PWROFST_COVER_CALIB_EN (1)
#if (defined(CONFIG_POWER_LIMIT))
#define CFG_USER_CHAN_MAX_TXPWR_EN (1)
#else
#define CFG_USER_CHAN_MAX_TXPWR_EN (0)
#endif
#define CFG_USER_TX_USE_ANA_F_EN (0)
#if (defined(CONFIG_PRBREQ_REPORT))
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (1)
#else
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (0)
#endif
#define CFG_USER_HE_MU_EDCA_UPDATE_DISABLE (0)
#define CFG_USER_LOFT_CALIB_DISABLE_DISABLE (0)
#define CFG_USER_CAPA_CALIB_DISABLE_DISABLE (0)
#define CFG_USER_PWR_CALIB_DISABLE_DISABLE (0)
#define CFG_USER_IPA_CALIB_DISABLE_DISABLE (0)
u32 patch_tbl_d80[][2] = u32 patch_tbl_d80[][2] =
{ {
@@ -73,25 +82,47 @@ u32 patch_tbl_d80[][2] =
{0x0170, 0x0001000A},//rx aggr counter {0x0170, 0x0001000A},//rx aggr counter
#endif #endif
#if CFG_USER_EXT_FLAGS_EN {0x0188,
{0x0188, 0x00000000 (USER_EXT_FLAGS_DEFAULT_D80 |
#if CFG_PWROFST_COVER_CALIB #if CFG_USER_CHAN_MAX_TXPWR_EN
| USER_PWROFST_COVER_CALIB_FLAG USER_CHAN_MAX_TXPWR_EN_FLAG |
#endif #endif
#if CFG_USER_CHAN_MAX_TXPWR_EN #if CFG_USER_TX_USE_ANA_F_EN
| USER_CHAN_MAX_TXPWR_EN_FLAG USER_TX_USE_ANA_F_FLAG |
#endif #endif
#if CFG_USER_TX_USE_ANA_F #if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE
| USER_TX_USE_ANA_F_FLAG USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG |
#endif #endif
#if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE #if CFG_USER_HE_MU_EDCA_UPDATE_DISABLE
| USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG |
#endif #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 }, // user_ext_flags
#endif
#ifdef CONFIG_RADAR_OR_IR_DETECT #ifdef CONFIG_RADAR_OR_IR_DETECT
{0x0019c,0x00000B00}, {0x0019c,0x00000900},
#endif
#ifdef CONFIG_WOWLAN
{0x019c,0x01000000},
#ifdef ANDROID_PLATFORM
{0x01A0, 0x01000001},
#endif
#endif #endif
}; };
@@ -303,6 +334,7 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){
int syscfg_num; int syscfg_num;
int ret, cnt; int ret, cnt;
const u32 mem_addr = 0x40500000; const u32 mem_addr = 0x40500000;
const u32 cache_mem_addr = 0x40100020;
struct dbg_mem_read_cfm rd_mem_addr_cfm; struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm); ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm);
if (ret) { if (ret) {
@@ -314,6 +346,19 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){
} }
chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16); chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16);
printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id); printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id);
if (chip_mcu_id) {
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 #if 1
syscfg_num = sizeof(syscfg_tbl_8800d80) / sizeof(u32) / 2; syscfg_num = sizeof(syscfg_tbl_8800d80) / sizeof(u32) / 2;
for (cnt = 0; cnt < syscfg_num; cnt++) { for (cnt = 0; cnt < syscfg_num; cnt++) {
@@ -337,7 +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; int ret = 0;
uint32_t ext_patch_nb = patch_info->ext_patch_nb; uint32_t ext_patch_nb = patch_info->ext_patch_nb;
@@ -354,7 +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); addr = *(patch_info->ext_patch_param + (index * 2) + 1);
memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name)); memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name));
sprintf(ext_patch_file_name,"%s%d.bin", sprintf(ext_patch_file_name,"%s%d.bin",
FW_PATCH_BASE_NAME_8800D80_U02_EXT, filename,
id); id);
AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n", AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n",
__func__,ext_patch_file_name, id, addr); __func__,ext_patch_file_name, id, addr);
@@ -386,7 +431,6 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
int i = 0; int i = 0;
#if 0
if (chip_id == CHIP_REV_U01) { if (chip_id == CHIP_REV_U01) {
head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80); head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80);
} else { } else {
@@ -414,11 +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); printk("addr_adid 0x%x, addr_patch 0x%x\n", patch_info.addr_adid, patch_info.addr_patch);
#endif
if(testmode == FW_NORMAL_MODE){ if(testmode == FW_NORMAL_MODE){
if (chip_id != CHIP_REV_U01){ if (chip_id != CHIP_REV_U01){
#if 0
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80_U02)) { if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80_U02)) {
return -1; return -1;
} }
@@ -426,14 +469,13 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
return -1; return -1;
} }
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80_U02_EXT)) {
return -1; return -1;
} }
if (aicbt_patch_table_load(usb_dev, head)) { if (aicbt_patch_table_load(usb_dev, head)) {
return -1; return -1;
} }
#endif
if (IS_CHIP_ID_H()){ if (IS_CHIP_ID_H()){
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80_U02, FW_BASE_NAME_8800D80_H_U02)) if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80_U02, FW_BASE_NAME_8800D80_H_U02))
@@ -456,7 +498,6 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
return -1; return -1;
} }
}else { }else {
#if 0
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80)) { if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80)) {
return -1; return -1;
} }
@@ -472,7 +513,6 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
return -1; return -1;
} }
#endif #endif
#endif
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80, FW_BASE_NAME_8800D80)) { if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80, FW_BASE_NAME_8800D80)) {
return -1; return -1;
} }
@@ -482,7 +522,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
} }
}else if(testmode == FW_TEST_MODE){ }else if(testmode == FW_TEST_MODE){
if (chip_id != CHIP_REV_U01){ if (chip_id != CHIP_REV_U01){
#if 0
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80_U02)) { if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80_U02)) {
return -1; return -1;
} }
@@ -491,7 +531,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
return -1; return -1;
} }
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80_U02_EXT)) {
return -1; return -1;
} }
@@ -508,7 +548,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev)
return -1; return -1;
} }
} }
#endif
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80_U02, FW_RF_BASE_NAME_8800D80_U02)) { if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80_U02, FW_RF_BASE_NAME_8800D80_U02)) {
AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__); AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__);
return -1; return -1;
@@ -41,21 +41,32 @@ typedef struct {
#define USER_PWROFST_COVER_CALIB_FLAG (0x01U << 0) #define USER_PWROFST_COVER_CALIB_FLAG (0x01U << 0)
#define USER_CHAN_MAX_TXPWR_EN_FLAG (0x01U << 1) #define USER_CHAN_MAX_TXPWR_EN_FLAG (0x01U << 1)
#define USER_TX_USE_ANA_F_FLAG (0x01U << 2)
#define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3) #define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3)
#define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4) #define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4)
#define USER_RF_WITH_SAW_EN_FLAG (0x01U << 10)
#define USER_SETCH_LOFT_CALIB_EN_FLAG (0x01U << 11)
#define USER_SETCH_RXDC_CALIB_EN_FLAG (0x01U << 12)
#ifdef CONFIG_POWER_LIMIT #define USER_EXT_FLAGS_DEFAULT_D80X2 \
#define CFG_USER_CHAN_MAX_TXPWR_EN 1 (USER_PWROFST_COVER_CALIB_FLAG | \
USER_CHAN_MAX_TXPWR_EN_FLAG | \
USER_SETCH_LOFT_CALIB_EN_FLAG)
#define CFG_USER_PWROFST_COVER_CALIB_EN (1)
#if (defined(CONFIG_POWER_LIMIT))
#define CFG_USER_CHAN_MAX_TXPWR_EN (1)
#else #else
#define CFG_USER_CHAN_MAX_TXPWR_EN 0 #define CFG_USER_CHAN_MAX_TXPWR_EN (0)
#endif #endif
#define CFG_USER_TX_USE_ANA_F 0 #if (defined(CONFIG_PRBREQ_REPORT))
#ifdef CONFIG_BAND_STEERING #define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (1)
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 1
#else #else
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 0 #define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (0)
#endif #endif
#define CFG_USER_HE_MU_EDCA_UPDATE_DISABLE (0)
#define CFG_USER_RF_WITH_SAW_EN (0)
#define CFG_USER_SETCH_LOFT_CALIB_EN (1)
#define CFG_USER_SETCH_RXDC_CALIB_EN (0)
u32 patch_tbl_d80x2[][2] = u32 patch_tbl_d80x2[][2] =
{ {
@@ -71,29 +82,35 @@ u32 patch_tbl_d80x2[][2] =
{0x0228, 0x50000a00},//ss aggr {0x0228, 0x50000a00},//ss aggr
#endif #endif
#if 0 #ifdef CONFIG_FLASH_CALRES
#ifdef USE_5G {0x0234, 0x0000004F}, // cal_res_stored_in_flash_flags
{0x00b4, 0xf3010001},
#else
{0x00b4, 0xf3010000},
#endif
#ifdef CONFIG_PLATFORM_HI
{0x0170, 0x00000001},//rx aggr counter
#else
{0x0170, 0x0000000A},//rx aggr counter
#endif
#endif #endif
{0x01f0, 0x00000001 {0x01f0,
#if CFG_USER_CHAN_MAX_TXPWR_EN (USER_EXT_FLAGS_DEFAULT_D80X2 |
| USER_CHAN_MAX_TXPWR_EN_FLAG
#endif
#if CFG_USER_TX_USE_ANA_F
| USER_TX_USE_ANA_F_FLAG
#endif
#if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE #if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE
| USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG |
#endif #endif
#if CFG_USER_HE_MU_EDCA_UPDATE_DISABLE
USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG |
#endif
#if CFG_USER_RF_WITH_SAW_EN
USER_RF_WITH_SAW_EN_FLAG |
#endif
#if CFG_USER_SETCH_RXDC_CALIB_EN
USER_SETCH_RXDC_CALIB_EN_FLAG |
#endif
0) & ~(
#if !CFG_USER_PWROFST_COVER_CALIB_EN
USER_PWROFST_COVER_CALIB_FLAG |
#endif
#if !CFG_USER_CHAN_MAX_TXPWR_EN
USER_CHAN_MAX_TXPWR_EN_FLAG |
#endif
#if !CFG_USER_SETCH_LOFT_CALIB_EN
USER_SETCH_LOFT_CALIB_EN_FLAG |
#endif
0)
}, // user_ext_flags }, // user_ext_flags
}; };
@@ -301,7 +318,39 @@ int system_config_8800d80x2(struct aic_usb_dev *usb_dev){
int ret, cnt; int ret, cnt;
const u32 mem_addr = 0x40500000; const u32 mem_addr = 0x40500000;
const u32 mem_addr2 = 0x40500004; const u32 mem_addr2 = 0x40500004;
const u32 mem_addr3 = 0x40800000;
const u32 mem_mask3 = (0x03UL << 24) | (0x01UL << 6) | (0x01UL << 1);
const u32 mem_data3 = (0x02UL << 24) | (0x01UL << 6);
const u32 mem_addr4 = 0x40800014;
const u32 mem_data4 = 0x00000820;
struct dbg_mem_read_cfm rd_mem_addr_cfm; struct dbg_mem_read_cfm rd_mem_addr_cfm;
/* fix usb2.0 rx_err */
ret = rwnx_send_dbg_mem_mask_write_req(usb_dev, mem_addr3, mem_mask3, mem_data3);
if (ret) {
printk("%x mask write fail: %d\n", mem_addr3, ret);
return ret;
}
ret = rwnx_send_dbg_mem_write_req(usb_dev, mem_addr4, mem_data4);
if (ret) {
printk("%x write fail: %d\n", mem_addr4, ret);
return ret;
}
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr3, &rd_mem_addr_cfm);
if (ret) {
printk("%x rd fail: %d\n", mem_addr3, ret);
return ret;
} else {
printk("[%08x]=%08x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
}
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr4, &rd_mem_addr_cfm);
if (ret) {
printk("%x rd fail: %d\n", mem_addr4, ret);
return ret;
} else {
printk("[%08x]=%08x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
}
ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm); ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm);
if (ret) { if (ret) {
printk("%x rd fail: %d\n", mem_addr, ret); printk("%x rd fail: %d\n", mem_addr, ret);
@@ -319,7 +368,7 @@ int system_config_8800d80x2(struct aic_usb_dev *usb_dev){
} }
printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id); printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id);
#if 1
syscfg_num = sizeof(syscfg_tbl_8800d80x2) / sizeof(u32) / 2; syscfg_num = sizeof(syscfg_tbl_8800d80x2) / sizeof(u32) / 2;
for (cnt = 0; cnt < syscfg_num; cnt++) { for (cnt = 0; cnt < syscfg_num; cnt++) {
ret = rwnx_send_dbg_mem_write_req(usb_dev, syscfg_tbl_8800d80x2[cnt][0], syscfg_tbl_8800d80x2[cnt][1]); ret = rwnx_send_dbg_mem_write_req(usb_dev, syscfg_tbl_8800d80x2[cnt][0], syscfg_tbl_8800d80x2[cnt][1]);
@@ -337,13 +386,12 @@ int system_config_8800d80x2(struct aic_usb_dev *usb_dev){
return ret; return ret;
} }
} }
#endif
return 0; return 0;
} }
static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info) static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info, const char *filename)
{ {
int ret = 0; int ret = 0;
uint32_t ext_patch_nb = patch_info->ext_patch_nb; uint32_t ext_patch_nb = patch_info->ext_patch_nb;
@@ -351,16 +399,26 @@ static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_p
int index = 0; int index = 0;
uint32_t id = 0; uint32_t id = 0;
uint32_t addr = 0; uint32_t addr = 0;
uint32_t mem_w_add = 0;
uint32_t mem_w_data = 0;
if (ext_patch_nb > 0){ if (ext_patch_nb > 0){
AICWFDBG(LOGDEBUG, "[0x40480000]: 0x00040220\n");
mem_w_add = 0x40580000;
mem_w_data = 0x00040220;
AICWFDBG(LOGDEBUG, "%s addr:0x%x data:0x%x \n", __func__, mem_w_add, mem_w_data);
ret = rwnx_send_dbg_mem_write_req(usb_dev, mem_w_add, mem_w_data);
if (ret) {
printk("%x wr fail: %d\n", mem_w_add, ret);
return ret;
}
for (index = 0; index < patch_info->ext_patch_nb; index++){ for (index = 0; index < patch_info->ext_patch_nb; index++){
id = *(patch_info->ext_patch_param + (index * 2)); id = *(patch_info->ext_patch_param + (index * 2));
addr = *(patch_info->ext_patch_param + (index * 2) + 1); addr = *(patch_info->ext_patch_param + (index * 2) + 1);
memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name)); memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name));
sprintf(ext_patch_file_name,"%s%d.bin", sprintf(ext_patch_file_name,"%s%d.bin",
FW_PATCH_BASE_NAME_8800D80X2_U03_EXT, filename,
id); id);
AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n", AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n",
__func__,ext_patch_file_name, id, addr); __func__,ext_patch_file_name, id, addr);
@@ -393,6 +451,10 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
int i = 0; int i = 0;
#ifdef CONFIG_LOAD_BT_CONF
aicbt_parse_config(usb_dev, FW_BT_CONF_NAME_8800D80X2);
#endif
if (chip_id < CHIP_REV_U05) { if (chip_id < CHIP_REV_U05) {
head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80X2_U03); head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80X2_U03);
} else { } else {
@@ -480,7 +542,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
return -1; return -1;
} }
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U03_EXT)) {
return -1; return -1;
} }
@@ -515,7 +577,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80X2_U05)) { if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80X2_U05)) {
return -1; return -1;
} }
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U05_EXT)) {
return -1; return -1;
} }
if (aicbt_patch_table_load(usb_dev, head)) { if (aicbt_patch_table_load(usb_dev, head)) {
@@ -545,7 +607,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
return -1; return -1;
} }
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U03_EXT)) {
return -1; return -1;
} }
@@ -556,15 +618,6 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
mdelay(100); mdelay(100);
#endif #endif
if (chip_mcu_id) {
int ret = 0;
ret = rwnx_plat_flash_bin_upload_android(usb_dev, FLASH_BIN_ADDR_8800M80X2, FLASH_BIN_8800M80X2);
if (ret && ret!= ENOENT) {
AICWFDBG(LOGERROR,"%s flash bin download fail \r\n", __func__);
return -1;
}
}
if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, FW_RF_BASE_NAME_8800D80X2)) { if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, FW_RF_BASE_NAME_8800D80X2)) {
AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__); AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__);
return -1; return -1;
@@ -582,7 +635,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
return -1; return -1;
} }
if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U05_EXT)) {
return -1; return -1;
} }
@@ -613,7 +666,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
data & mask = "0x46 0x00" 0x00 0x00 0x00 0x00 0x00 0x00 0x00 "0x30 0xff 0xff 0x43 0x52 0x45 0x4c 0x42" data & mask = "0x46 0x00" 0x00 0x00 0x00 0x00 0x00 0x00 0x00 "0x30 0xff 0xff 0x43 0x52 0x45 0x4c 0x42"
using data & mask value condition to wakeup host_wake_bt gpio using data & mask value condition to wakeup host_wake_bt gpio
*/ */
int ret;
struct ble_wakeup_param_t* wakeup_param = (struct ble_wakeup_param_t*)kmalloc(sizeof(struct ble_wakeup_param_t), GFP_KERNEL); struct ble_wakeup_param_t* wakeup_param = (struct ble_wakeup_param_t*)kmalloc(sizeof(struct ble_wakeup_param_t), GFP_KERNEL);
uint32_t *write_blocks = (uint32_t *)wakeup_param; uint32_t *write_blocks = (uint32_t *)wakeup_param;
@@ -744,7 +797,6 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev)
} }
//rwnx_send_dbg_start_app_req(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80, HOST_START_APP_AUTO); //rwnx_send_dbg_start_app_req(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80, HOST_START_APP_AUTO);
int ret;
ret = rwnx_send_dbg_mem_write_req(usb_dev, 0x40500048, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80); ret = rwnx_send_dbg_mem_write_req(usb_dev, 0x40500048, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80);
if (ret) { if (ret) {
printk("%x write fail\n", ret); printk("%x write fail\n", ret);
@@ -4,6 +4,7 @@
#define USB_DEVICE_ID_AIC_8800D80X2 0x8D90 #define USB_DEVICE_ID_AIC_8800D80X2 0x8D90
#define USB_DEVICE_ID_AIC_8800D81X2 0x8D91 #define USB_DEVICE_ID_AIC_8800D81X2 0x8D91
#define USB_DEVICE_ID_AIC_8800D89X2 0x8D99 #define USB_DEVICE_ID_AIC_8800D89X2 0x8D99
#define USB_DEVICE_ID_AIC_8800D40X2 0x8D92
#ifdef CONFIG_FOR_IPCAM #ifdef CONFIG_FOR_IPCAM
#define FW_BASE_NAME_8800D80X2 "fmacfw_8800d80x2_ipc.bin" #define FW_BASE_NAME_8800D80X2 "fmacfw_8800d80x2_ipc.bin"
@@ -22,12 +23,14 @@
#define FW_ADID_BASE_NAME_8800D80X2_U05 "fw_adid_8800d80x2_u05.bin" #define FW_ADID_BASE_NAME_8800D80X2_U05 "fw_adid_8800d80x2_u05.bin"
#define FW_PATCH_TABLE_NAME_8800D80X2_U05 "fw_patch_table_8800d80x2_u05.bin" #define FW_PATCH_TABLE_NAME_8800D80X2_U05 "fw_patch_table_8800d80x2_u05.bin"
#define FW_BT_CONF_NAME_8800D80X2 "aicbt.conf"
#define FLASH_BIN_8800M80X2 "host_wb_8800m80x2.bin" #define FLASH_BIN_8800M80X2 "host_wb_8800m80x2.bin"
#define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt" #define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt"
#define RAM_FMAC_FW_ADDR_8800D80X2 0x120000 #define RAM_FMAC_FW_ADDR_8800D80X2 0x128000
#define RAM_FMAC_RF_FW_ADDR_8800D80X2 0x120000 #define RAM_FMAC_RF_FW_ADDR_8800D80X2 0x128000
#define FW_RAM_ADID_BASE_ADDR_8800D80X2_U03 0x003018f8 #define FW_RAM_ADID_BASE_ADDR_8800D80X2_U03 0x003018f8
#define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U03 0x0030b494 #define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U03 0x0030b494
@@ -35,7 +38,7 @@
#define FW_RAM_ADID_BASE_ADDR_8800D80X2_U05 0x003018f8 #define FW_RAM_ADID_BASE_ADDR_8800D80X2_U05 0x003018f8
#define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U05 0x0030b48c #define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U05 0x0030b48c
#define FLASH_BIN_ADDR_8800M80X2 0x8000000 #define FLASH_BIN_ADDR_8800M80X2 0x4000000
int aicwf_patch_config_8800d80x2(struct aic_usb_dev *usb_dev); int aicwf_patch_config_8800d80x2(struct aic_usb_dev *usb_dev);
+1 -1
View File
@@ -18,7 +18,7 @@
#define DATA_BUF_MAX 2048 #define DATA_BUF_MAX 2048
#define TXPKT_BLOCKSIZE 512 #define TXPKT_BLOCKSIZE 512
#define MAX_AGGR_TXPKT_LEN (1536*32) #define MAX_AGGR_TXPKT_LEN (1536*32)
#define CMD_TX_TIMEOUT 2000 #define CMD_TX_TIMEOUT 5000
#define TX_ALIGNMENT 4 #define TX_ALIGNMENT 4
#define RX_HWHRD_LEN 60 //58->60 word allined #define RX_HWHRD_LEN 60 //58->60 word allined
+175 -45
View File
@@ -20,20 +20,6 @@ extern int flash_erase_len;
int flash_write_size = 0; int flash_write_size = 0;
u32 flash_write_bin_crc = 0; u32 flash_write_bin_crc = 0;
typedef struct
{
int8_t enable;
int8_t dsss;
int8_t ofdmlowrate_2g4;
int8_t ofdm64qam_2g4;
int8_t ofdm256qam_2g4;
int8_t ofdm1024qam_2g4;
int8_t ofdmlowrate_5g;
int8_t ofdm64qam_5g;
int8_t ofdm256qam_5g;
int8_t ofdm1024qam_5g;
} txpwr_idx_conf_t;
txpwr_idx_conf_t userconfig_txpwr_idx = { txpwr_idx_conf_t userconfig_txpwr_idx = {
.enable = 1, .enable = 1,
@@ -49,17 +35,6 @@ txpwr_idx_conf_t userconfig_txpwr_idx = {
}; };
typedef struct
{
int8_t enable;
int8_t chan_1_4;
int8_t chan_5_9;
int8_t chan_10_13;
int8_t chan_36_64;
int8_t chan_100_120;
int8_t chan_122_140;
int8_t chan_142_165;
} txpwr_ofst_conf_t;
txpwr_ofst_conf_t userconfig_txpwr_ofst = { txpwr_ofst_conf_t userconfig_txpwr_ofst = {
.enable = 1, .enable = 1,
@@ -72,13 +47,6 @@ txpwr_ofst_conf_t userconfig_txpwr_ofst = {
.chan_142_165 = 0 .chan_142_165 = 0
}; };
typedef struct
{
int8_t enable;
int8_t xtal_cap;
int8_t xtal_cap_fine;
} xtal_cap_conf_t;
xtal_cap_conf_t userconfig_xtal_cap = { xtal_cap_conf_t userconfig_xtal_cap = {
.enable = 0, .enable = 0,
@@ -757,7 +725,7 @@ int rwnx_plat_flash_bin_upload_android(struct aic_usb_dev *usbdev, u32 fw_addr,
int err=0; int err=0;
const u32 mem_addr = fw_addr; const u32 mem_addr = fw_addr;
struct dbg_mem_read_cfm rd_mem_addr_cfm; struct dbg_mem_read_cfm rd_mem_addr_cfm;
u32 crc = ~0UL; u32 crc = (u32)~0UL;
/* load aic firmware */ /* load aic firmware */
size = aic_load_firmware(&dst, filename, dev); size = aic_load_firmware(&dst, filename, dev);
@@ -1285,6 +1253,149 @@ static struct aicbt_info_t aicbt_info[] = {
},//PRODUCT_ID_AIC8800D80X2 },//PRODUCT_ID_AIC8800D80X2
}; };
#ifdef CONFIG_LOAD_BT_CONF
static const char *aicbt_find_tag(const u8 *file_data, unsigned int file_size,
const char *tag_name, unsigned int tag_len)
{
unsigned int line_start = 0, tag_name_len = strlen(tag_name);
const char *comment_symbols = "#;";
RWNX_DBG(RWNX_FN_ENTRY_STR);
while (line_start < file_size) {
unsigned int line_end = line_start;
while (line_end < file_size && file_data[line_end] != '\n' && file_data[line_end] != '\r') {
line_end++;
}
if (line_end - line_start >= tag_name_len &&
!strncmp((const char*)&file_data[line_start], tag_name, tag_name_len))
{
const char *value_start = (const char*)&file_data[line_start + tag_name_len];
const char *value_end = (const char*)&file_data[line_end];
while (value_start < value_end && (*value_start == ' ' || *value_start == '=')) {
value_start++;
}
const char *comment_pos = value_start;
while (comment_pos < value_end && !strchr(comment_symbols, *comment_pos)) {
comment_pos++;
}
while (comment_pos > value_start && (*(comment_pos-1) == ' ' || *(comment_pos-1) == '\t')) {
comment_pos--;
}
if (comment_pos > value_start) {
return value_start;
}
}
line_start = line_end;
while (line_start < file_size && (file_data[line_start] == '\n' || file_data[line_start] == '\r')) {
line_start++;
}
}
return NULL;
}
void aicbt_parse_config(struct aic_usb_dev *usbdev, const char *filename)
{
struct device *dev = usbdev->dev;
u32 *dst = NULL;
int size;
const u8 *tag_ptr;
u32 tmp_val;
//char *filename = "aicbt.conf";
RWNX_DBG(RWNX_FN_ENTRY_STR);
size = aic_load_firmware((u32 **)&dst, filename, dev);
if (size <= 0) {
AICWFDBG(LOGERROR, "%s: load %s fail (%d)\n", __func__, filename, size);
return;
}
tag_ptr = aicbt_find_tag((char*)dst, size, "BTMODE=", strlen("0"));
if (tag_ptr) {
if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].btmode) != 1 ||
aicbt_info[usbdev->chipid].btmode > AICBT_BTMODE_BT_ONLY_COANT) {
aicbt_info[usbdev->chipid].btmode = AICBT_BTMODE_DEFAULT;
AICWFDBG(LOGERROR, "BTMODE invalid, use default %02X\n", AICBT_BTMODE_DEFAULT);
}
} else {
aicbt_info[usbdev->chipid].btmode = AICBT_BTMODE_DEFAULT;
}
tag_ptr = aicbt_find_tag((char*)dst, size, "BTPORT=", strlen("0"));
if (tag_ptr) {
if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].btport) != 1 ||
aicbt_info[usbdev->chipid].btport > AICBT_BTPORT_UART) {
aicbt_info[usbdev->chipid].btport = AICBT_BTPORT_DEFAULT;
}
} else {
aicbt_info[usbdev->chipid].btport = AICBT_BTPORT_DEFAULT;
}
tag_ptr = aicbt_find_tag((char*)dst, size, "UART_BAUD=", 0);
if (tag_ptr) {
if (sscanf(tag_ptr, "%u", &tmp_val) == 1) {
if(tmp_val >= AICBT_UART_BAUD_115200 && tmp_val <= AICBT_UART_BAUD_3_25M) {
aicbt_info[usbdev->chipid].uart_baud = tmp_val;
} else {
aicbt_info[usbdev->chipid].uart_baud = AICBT_UART_BAUD_DEFAULT;
AICWFDBG(LOGERROR, "UART_BAUD %u invalid, use default %d\n", tmp_val, AICBT_UART_BAUD_DEFAULT);
}
} else {
aicbt_info[usbdev->chipid].uart_baud = AICBT_UART_BAUD_DEFAULT;
}
} else {
aicbt_info[usbdev->chipid].uart_baud = AICBT_UART_BAUD_DEFAULT;
}
tag_ptr = aicbt_find_tag((char*)dst, size, "UART_FC=", strlen("0"));
if (tag_ptr) {
if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].uart_flowctrl) != 1 ||
aicbt_info[usbdev->chipid].uart_flowctrl > AICBT_UART_FLOWCTRL_ENABLE) {
aicbt_info[usbdev->chipid].uart_flowctrl = AICBT_UART_FC_DEFAULT;
}
} else {
aicbt_info[usbdev->chipid].uart_flowctrl = AICBT_UART_FC_DEFAULT;
}
tag_ptr = aicbt_find_tag((char*)dst, size, "LPM_ENABLE=", strlen("0"));
if (tag_ptr) {
if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].lpm_enable) != 1 ||
aicbt_info[usbdev->chipid].lpm_enable > 1) {
aicbt_info[usbdev->chipid].lpm_enable = AICBT_LPM_ENABLE_DEFAULT;
}
} else {
aicbt_info[usbdev->chipid].lpm_enable = AICBT_LPM_ENABLE_DEFAULT;
}
tag_ptr = aicbt_find_tag((char*)dst, size, "TXPWR_LVL=", strlen("0x6F2F"));
if (tag_ptr) {
if (sscanf(tag_ptr, "%08x", &tmp_val) == 1) {
if (tmp_val >= 0 || tmp_val <= 0X7F7F) {
aicbt_info[usbdev->chipid].txpwr_lvl = tmp_val;
} else {
aicbt_info[usbdev->chipid].txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT;
}
} else {
aicbt_info[usbdev->chipid].txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT;
}
} else {
aicbt_info[usbdev->chipid].txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT;
}
vfree(dst);
AICWFDBG(LOGINFO, "%s: btmode %d btport %d uart baud %d uart fc %d lpm %d txpwrlvl %4X\n",
__func__,
aicbt_info[usbdev->chipid].btmode,
aicbt_info[usbdev->chipid].btport,
aicbt_info[usbdev->chipid].uart_baud,
aicbt_info[usbdev->chipid].uart_flowctrl,
aicbt_info[usbdev->chipid].lpm_enable,
aicbt_info[usbdev->chipid].txpwr_lvl);
}
#endif
int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *_head) int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *_head)
{ {
struct aicbt_patch_table *head, *p; struct aicbt_patch_table *head, *p;
@@ -1307,11 +1418,12 @@ int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table
*(data + 15) = aicbt_info[usbdev->chipid].lpm_enable; *(data + 15) = aicbt_info[usbdev->chipid].lpm_enable;
*(data + 17) = aicbt_info[usbdev->chipid].txpwr_lvl; *(data + 17) = aicbt_info[usbdev->chipid].txpwr_lvl;
printk("%s bt btmode[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].btmode); printk("%s bt btmode[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].btmode);
printk("%s bt uart_baud[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_baud); printk("%s bt btport[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].btport);
printk("%s bt uart_flowctrl[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_flowctrl); printk("%s bt uart_baud[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_baud);
printk("%s bt lpm_enable[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].lpm_enable); printk("%s bt uart_flowctrl[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_flowctrl);
printk("%s bt tx_pwr[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].txpwr_lvl); printk("%s bt lpm_enable[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].lpm_enable);
printk("%s bt tx_pwr[%d]:%4X\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].txpwr_lvl);
} }
if (p->type == 0x06) { if (p->type == 0x06) {
@@ -1326,7 +1438,8 @@ int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table
data += 2; data += 2;
} }
if (p->type == AICBT_PT_PWRON) if (p->type == AICBT_PT_PWRON)
udelay(500); mdelay(100);
// udelay(500);
} }
aicbt_patch_table_free(head); aicbt_patch_table_free(head);
return 0; return 0;
@@ -1334,7 +1447,6 @@ int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table
int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t) int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t)
{ {
uint8_t *patch_info_array = (uint8_t*)patch_info;
int base_len = 0; int base_len = 0;
int memcpy_len = 0; int memcpy_len = 0;
@@ -1349,17 +1461,35 @@ int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_
patch_info->info_len = head_t->len; patch_info->info_len = head_t->len;
memcpy_len = patch_info->info_len; memcpy_len = patch_info->info_len;
} }
head_t->len = patch_info->info_len;
AICWFDBG(LOGDEBUG, "%s memcpy_len:%d \r\n", __func__, memcpy_len); AICWFDBG(LOGDEBUG, "%s memcpy_len:%d \r\n", __func__, memcpy_len);
if (patch_info->info_len == 0) if (patch_info->info_len == 0)
return 0; return 0;
memcpy(((patch_info_array) + sizeof(patch_info->info_len)), if (memcpy_len >= 1) {
head_t->data, patch_info->adid_addrinf = head_t->data[0];
memcpy_len * sizeof(uint32_t) * 2); patch_info->addr_adid = head_t->data[1];
}
if (memcpy_len >= 2) {
patch_info->patch_addrinf = head_t->data[2];
patch_info->addr_patch = head_t->data[3];
}
if (memcpy_len >= 3) {
patch_info->reset_addr = head_t->data[4];
patch_info->reset_val = head_t->data[5];
}
if (memcpy_len >= 4) {
patch_info->adid_flag_addr = head_t->data[6];
patch_info->adid_flag = head_t->data[7];
}
if (memcpy_len >= 5) {
patch_info->ext_patch_nb_addr = head_t->data[8];
patch_info->ext_patch_nb = head_t->data[9];
}
AICWFDBG(LOGDEBUG, "%s adid_addrinf:%x addr_adid:%x \r\n", __func__, AICWFDBG(LOGDEBUG, "%s adid_addrinf:%x addr_adid:%x \r\n", __func__,
((struct aicbt_patch_info_t *)patch_info_array)->adid_addrinf, patch_info->adid_addrinf,
((struct aicbt_patch_info_t *)patch_info_array)->addr_adid); patch_info->addr_adid);
if (patch_info->ext_patch_nb > 0){ if (patch_info->ext_patch_nb > 0){
int index = 0; int index = 0;
@@ -9,6 +9,53 @@ struct aicbt_patch_table {
struct aicbt_patch_table *next; struct aicbt_patch_table *next;
}; };
typedef struct
{
int8_t enable;
int8_t dsss;
int8_t ofdmlowrate_2g4;
int8_t ofdm64qam_2g4;
int8_t ofdm256qam_2g4;
int8_t ofdm1024qam_2g4;
int8_t ofdmlowrate_5g;
int8_t ofdm64qam_5g;
int8_t ofdm256qam_5g;
int8_t ofdm1024qam_5g;
} txpwr_idx_conf_t;
typedef struct
{
int8_t enable;
int8_t chan_1_4;
int8_t chan_5_9;
int8_t chan_10_13;
int8_t chan_36_64;
int8_t chan_100_120;
int8_t chan_122_140;
int8_t chan_142_165;
} txpwr_ofst_conf_t;
typedef struct
{
int8_t enable;
int8_t xtal_cap;
int8_t xtal_cap_fine;
} xtal_cap_conf_t;
u32 aic_crc32(u8 *p, u32 len, u32 crc);
void get_fw_path(char* fw_path);
void set_testmode(int val);
int get_testmode(void);
int get_hardware_info(void);
int get_adap_test(void);
int get_flash_bin_size(void);
u32 get_flash_bin_crc(void);
void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap);
void get_userconfig_txpwr_idx(txpwr_idx_conf_t *txpwr_idx);
void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst);
void rwnx_plat_userconfig_set_value(char *command, char *value);
void rwnx_plat_userconfig_parsing(char *buffer, int size);
int aic_bt_platform_init(struct aic_usb_dev *sdiodev); int aic_bt_platform_init(struct aic_usb_dev *sdiodev);
@@ -30,6 +77,9 @@ int8_t rwnx_atoi(char *value);
uint32_t rwnx_atoli(char *value); uint32_t rwnx_atoli(char *value);
int aicbt_patch_table_free(struct aicbt_patch_table *head); int aicbt_patch_table_free(struct aicbt_patch_table *head);
struct aicbt_patch_table *aicbt_patch_table_alloc(struct aic_usb_dev *usbdev, const char *filename); struct aicbt_patch_table *aicbt_patch_table_alloc(struct aic_usb_dev *usbdev, const char *filename);
#ifdef CONFIG_LOAD_BT_CONF
void aicbt_parse_config(struct aic_usb_dev *usbdev, const char *filename);
#endif
int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t); int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t);
int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *_head); int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *_head);
@@ -240,7 +240,6 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len)
struct aicwf_bus *bus = usbdev->bus_if; struct aicwf_bus *bus = usbdev->bus_if;
u8 *buffer = bus->cmd_buf; u8 *buffer = bus->cmd_buf;
u16 index = 0; u16 index = 0;
int ret = 0;
memset(buffer, 0, CMD_BUF_MAX); memset(buffer, 0, CMD_BUF_MAX);
buffer[0] = (len+4) & 0x00ff; buffer[0] = (len+4) & 0x00ff;
@@ -262,10 +261,7 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len)
index += 2; index += 2;
memcpy(&buffer[index], (u8 *)msg->param, msg->param_len); memcpy(&buffer[index], (u8 *)msg->param, msg->param_len);
ret = aicwf_bus_txmsg(bus, buffer, len + 8); aicwf_bus_txmsg(bus, buffer, len + 8);
if (ret == -EIO) {
ret = aicwf_bus_txmsg(bus, buffer, len + 8);
}
} }
static inline void *rwnx_msg_zalloc(lmac_msg_id_t const id, static inline void *rwnx_msg_zalloc(lmac_msg_id_t const id,
@@ -336,7 +332,10 @@ static int rwnx_send_msg(struct aic_usb_dev *usbdev, const void *msg_params,
} }
if(!reqcfm) if(!reqcfm)
{
kfree(cmd); kfree(cmd);
rwnx_msg_free(msg, msg_params);
}
return ret; return ret;
} }
@@ -408,7 +407,7 @@ int rwnx_send_dbg_mem_write_req(struct aic_usb_dev *usbdev, u32 mem_addr, u32 me
{ {
struct dbg_mem_write_req *mem_write_req; struct dbg_mem_write_req *mem_write_req;
// printk("%s mem_addr:%x mem_data:%x\r\n", __func__, mem_addr, mem_data); //printk("%s mem_addr:%x mem_data:%x\r\n", __func__, mem_addr, mem_data);
/* Build the DBG_MEM_WRITE_REQ message */ /* Build the DBG_MEM_WRITE_REQ message */
mem_write_req = rwnx_msg_zalloc(DBG_MEM_WRITE_REQ, TASK_DBG, DRV_TASK_ID, mem_write_req = rwnx_msg_zalloc(DBG_MEM_WRITE_REQ, TASK_DBG, DRV_TASK_ID,
@@ -1,5 +1,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include "aicwf_debug.h" #include "aicwf_debug.h"
#include "aicwf_txq_prealloc.h"
struct prealloc_txq{ struct prealloc_txq{
int prealloced; int prealloced;
@@ -1,4 +1,7 @@
#ifndef __AICWF_TXQ_PREALLOC_H
#define __AICWF_TXQ_PREALLOC_H
void *aicwf_prealloc_txq_alloc(size_t size);
void aicwf_prealloc_txq_free(void); void aicwf_prealloc_txq_free(void);
#endif
+11 -1
View File
@@ -985,7 +985,7 @@ u32 patch_tbl[][2] ={
#ifdef CONFIG_USB_SUSPEND_REBOOT_TIME #ifdef CONFIG_USB_SUSPEND_REBOOT_TIME
{0x0110, 0x03e80001}//reboot time when usb suspend,0001 enables reboot on suspend, default 0x3e8 = 1000ms reboot {0x0110, 0x03e80001}//reboot time when usb suspend,0001 enables reboot on suspend, default 0x3e8 = 1000ms reboot
#else #else
#ifdef CONFIG_SUPPORT_USB_SUSP #ifdef CONFIG_WOWLAN
//USB SUSP keep working 0x0100:enable 0x0000:disable //USB SUSP keep working 0x0100:enable 0x0000:disable
{0x0110, 0x00000100} {0x0110, 0x00000100}
#endif #endif
@@ -1367,6 +1367,14 @@ static int aicloadfw_chipmatch(struct aic_usb_dev *usb_dev, u16 vid, u16 pid){
usb_dev->chipid = PRODUCT_ID_AIC8800D89X2; usb_dev->chipid = PRODUCT_ID_AIC8800D89X2;
AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__); AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__);
return 0; return 0;
}else if(pid == USB_DEVICE_ID_AIC_8800D40X2 && vid == USB_VENDOR_ID_AIC_V2){
usb_dev->chipid = PRODUCT_ID_AIC8800D80X2;
AICWFDBG(LOGINFO, "%s USE AIC8800D40X2\r\n", __func__);
return 0;
}else if(pid == USB_DEVICE_ID_AIC_8800D81 && vid == USB_VENDOR_ID_AIC_V2){
usb_dev->chipid = PRODUCT_ID_AIC8800D81;
AICWFDBG(LOGINFO, "%s USE AIC8800D81 (368b:8d81)\r\n", __func__);
return 0;
}else{ }else{
return -1; return -1;
} }
@@ -1846,6 +1854,8 @@ static struct usb_device_id aicwf_usb_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D80X2)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D80X2)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D81X2)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D81X2)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D89X2)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D89X2)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D40X2)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D81)}, /* 368b:8d81 */
{} {}
}; };
+4 -1
View File
@@ -42,11 +42,12 @@ enum AICWF_IC{
PRODUCT_ID_AIC8800D80X2, PRODUCT_ID_AIC8800D80X2,
PRODUCT_ID_AIC8800D81X2, PRODUCT_ID_AIC8800D81X2,
PRODUCT_ID_AIC8800D89X2, PRODUCT_ID_AIC8800D89X2,
PRODUCT_ID_AIC8800D40X2,
}; };
#define AICWF_USB_RX_URBS (20) #define AICWF_USB_RX_URBS (20)
#define AICWF_USB_TX_URBS (30) #define AICWF_USB_TX_URBS (100)
#define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4) #define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4)
#define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3) #define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3)
#define AICWF_USB_MAX_PKT_SIZE (2048) #define AICWF_USB_MAX_PKT_SIZE (2048)
@@ -233,6 +234,8 @@ extern void aicwf_usb_tx_flowctrl(struct aic_usb_dev *usb_dev, bool state);
int usb_bustx_thread(void *data); int usb_bustx_thread(void *data);
int usb_busrx_thread(void *data); int usb_busrx_thread(void *data);
int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv); int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv);
int aicfw_download_fw_8800(struct aic_usb_dev *usb_dev);
int aicfw_download_fw(struct aic_usb_dev *usb_dev);
#endif /* AICWF_USB_SUPPORT */ #endif /* AICWF_USB_SUPPORT */
#endif /* _AICWF_USB_H_ */ #endif /* _AICWF_USB_H_ */
@@ -1,4 +1,4 @@
#define RWNX_VERS_REV "1a4b0054d2M (master)" #define RWNX_VERS_REV "1a4b0054d2M (master)"
#define RWNX_VERS_MOD "6.4.3.0" #define RWNX_VERS_MOD "6.4.3.0"
#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)" #define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)"
#define RELEASE_DATE "2025_0423_71b66e7b" #define RELEASE_DATE "2026_0123_5f7be68d"
+30
View File
@@ -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.
+83 -84
View File
@@ -1,118 +1,117 @@
# AIC POWERLIMIT 2024/1108/1900 # AIC POWERLIMIT 2025/0623/1700
# Max tx power reference: Linux wireless regulatory database for CRDA # Max tx power reference: Linux wireless regulatory database for CRDA
# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt # https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt
# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment # If loss_value in aic_userconfig.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment
# Table 1: # Table 1:
## 2.4G, 20M,#5# ## 2.4G, 20M,#6#
## START ## START
## SRRC FCC ETSI JP UNSET ## SRRC FCC ETSI JP KCC UNSET
CH01 15 15 15 15 15 CH01 16 14 14 16 16 15
CH02 16 16 16 16 16 CH02 16 14 14 16 16 16
CH03 16 16 16 16 16 CH03 16 14 14 16 16 16
CH04 16 16 16 16 16 CH04 16 14 14 16 16 16
CH05 16 16 16 16 16 CH05 16 14 14 16 16 16
CH06 16 16 16 16 16 CH06 16 14 14 16 16 16
CH07 16 16 16 16 16 CH07 16 14 14 16 16 16
CH08 16 16 16 16 16 CH08 16 14 14 16 16 16
CH09 16 16 16 16 16 CH09 16 14 14 16 16 16
CH10 16 16 16 16 16 CH10 16 14 14 16 16 16
CH11 16 16 16 16 16 CH11 16 14 14 16 16 16
CH12 12 12 12 12 12 CH12 15 14 14 16 16 12
CH13 12 12 12 12 12 CH13 13 14 14 16 16 12
CH14 NA NA NA 12 12 CH14 NA NA NA 16 NA 12
## END ## END
# Table 2: # Table 2:
## 2.4G, 40M,#5# ## 2.4G, 40M,#6#
## START ## START
## SRRC FCC ETSI JP UNSET ## SRRC FCC ETSI JP KCC UNSET
CH01 NA NA NA NA NA CH01 NA NA NA NA NA NA
CH02 NA NA NA NA NA CH02 NA NA NA NA NA NA
CH03 16 16 16 16 16 CH03 16 13 14 16 16 16
CH04 16 16 16 16 16 CH04 16 13 14 16 16 16
CH05 16 16 16 16 16 CH05 16 13 14 16 16 16
CH06 16 16 16 16 16 CH06 16 13 14 16 16 16
CH07 16 16 16 16 16 CH07 16 13 14 16 16 16
CH08 16 16 16 16 16 CH08 16 13 14 16 16 16
CH09 16 16 16 16 16 CH09 16 11 14 16 16 16
CH10 16 16 16 16 16 CH10 16 11 14 16 16 16
CH11 16 16 16 16 16 CH11 16 11 14 16 16 16
CH12 NA NA NA NA NA CH12 NA NA NA NA NA NA
CH13 NA NA NA NA NA CH13 NA NA NA NA NA NA
CH14 NA NA NA NA NA CH14 NA NA NA NA NA NA
## END ## END
# Table 3: # Table 3:
## 5G, 20M,#5# ## 5G, 20M,#6#
## START ## START
## SRRC FCC ETSI JP UNSET ## SRRC FCC ETSI JP KCC UNSET
# 5G Band 1 # 5G Band 1
CH36 15 16 16 16 15 CH36 15 16 16 16 16 15
CH40 15 16 16 16 15 CH40 15 16 16 16 16 15
CH44 15 16 16 16 15 CH44 15 16 16 16 16 15
CH48 15 16 16 16 15 CH48 15 16 16 16 16 15
# 5G Band 2 # 5G Band 2
CH52 15 16 16 16 15 CH52 15 16 16 16 16 15
CH56 15 16 16 16 15 CH56 15 16 16 16 16 15
CH60 15 16 16 16 15 CH60 15 16 16 16 16 15
CH64 15 16 16 16 15 CH64 15 16 16 16 16 15
# 5G Band 3 # 5G Band 3
CH100 NA 16 16 16 15 CH100 NA 16 16 16 16 15
CH104 NA 16 16 16 15 CH104 NA 16 16 16 16 15
CH108 NA 16 16 16 15 CH108 NA 16 16 16 16 15
CH112 NA 16 16 16 15 CH112 NA 16 16 16 16 15
CH116 NA 16 16 16 15 CH116 NA 16 16 16 16 15
CH120 NA 16 16 16 15 CH120 NA 16 16 16 16 15
CH124 NA 16 16 16 15 CH124 NA 16 16 16 16 15
CH128 NA 16 16 16 15 CH128 NA 16 16 16 16 15
CH132 NA 16 16 16 15 CH132 NA 16 16 16 16 15
CH136 NA 16 16 16 15 CH136 NA 16 16 16 16 15
CH140 NA 16 16 16 15 CH140 NA 16 16 16 16 15
CH144 NA NA 16 16 15 CH144 NA NA 16 16 16 15
# 5G Band 4 # 5G Band 4
CH149 16 16 11 NA 11 CH149 20 16 8 NA 20 11
CH153 16 16 11 NA 11 CH153 20 16 8 NA 20 11
CH157 16 16 11 NA 11 CH157 20 16 8 NA 20 11
CH161 16 16 11 NA 11 CH161 20 16 8 NA 20 11
CH165 16 16 11 NA 11 CH165 20 16 8 NA 20 11
## END ## END
# Table 4: # Table 4:
## 5G, 40M,#5# ## 5G, 40M,#6#
## START ## START
## SRRC FCC ETSI JP UNSET ## SRRC FCC ETSI JP KCC UNSET
# 5G Band 1 # 5G Band 1
CH38 15 16 16 16 15 CH38 15 16 16 16 20 15
CH46 15 16 16 16 15 CH46 15 16 16 16 20 15
# 5G Band 2 # 5G Band 2
CH54 15 16 16 16 15 CH54 15 16 16 16 20 15
CH62 15 16 16 16 15 CH62 15 16 16 16 20 15
# 5G Band 3 # 5G Band 3
CH102 NA 16 16 16 15 CH102 NA 16 16 16 20 15
CH110 NA 16 16 16 15 CH110 NA 16 16 16 20 15
CH118 NA 16 16 16 15 CH118 NA 16 16 16 20 15
CH126 NA 16 16 16 15 CH126 NA 16 16 16 20 15
CH134 NA 16 16 16 15 CH134 NA 16 16 16 20 15
CH142 NA 16 NA 16 15 CH142 NA 16 NA 16 20 15
# 5G Band 4 # 5G Band 4
CH151 16 16 11 NA 11 CH151 16 15 8 NA 18 11
CH159 16 16 11 NA 11 CH159 17 16 8 NA 17 11
## END ## END
# Table 5: # Table 5:
## 5G, 80M,#5# ## 5G, 80M,#6#
## START ## START
## SRRC FCC ETSI JP UNSET ## SRRC FCC ETSI JP KCC UNSET
# 5G Band 1 # 5G Band 1
CH42 15 16 16 16 15 CH42 15 16 16 16 20 15
# 5G Band 2 # 5G Band 2
CH58 15 16 16 16 15 CH58 15 16 16 16 20 15
# 5G Band 3 # 5G Band 3
CH106 NA 16 16 16 15 CH106 NA 16 16 16 20 15
CH122 NA 16 16 16 15 CH122 NA 16 16 16 20 15
CH138 NA 16 NA NA 15 CH138 NA 16 NA NA 20 15
# 5G Band 4 # 5G Band 4
CH155 16 16 11 NA 11 CH155 15 14 8 NA 16 11
## END ## END
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More