Author SHA1 Message Date
Shen Mintao bef3cc252f fix: harden cfg80211 backport ABI handling 2026-08-05 10:38:26 +08:00
Shen Mintao d9688590c2 fix: adapt cfg80211 RX helpers by API type 2026-08-02 13:09:49 +08:00
Shen Mintao 4902793c01 fix: select cfg80211 callbacks by API type 2026-07-27 10:39:06 +08:00
Shen Mintao 4bae903599 docs: finalize two-branch maintenance model 2026-07-25 19:42:46 +08:00
MinQ 51b8ab8062 Merge pull request #74 from shenmintao/test/legacy-mcu1-unified-bt-zlp
feat: unify legacy Wi-Fi Bluetooth and ZLP support
2026-07-25 19:40:47 +08:00
Shen Mintao ded6920d06 merge: sync validated Bluetooth diagnostics 2026-07-25 19:15:26 +08:00
Shen Mintao bbc1a04e59 docs: deduplicate legacy retirement notice 2026-07-25 16:07:28 +08:00
Shen Mintao e7b7599ad9 merge: sync unified Bluetooth retirement notice 2026-07-25 16:06:45 +08:00
Shen Mintao b100e7a7ec merge: sync legacy Bluetooth retirement notice 2026-07-25 16:06:35 +08:00
Shen Mintao 957b5f5a82 docs: clarify Bluetooth retirement on legacy branch 2026-07-25 16:05:16 +08:00
Shen Mintao 1358e55a0e fix: refresh Bazzite package for unified legacy branch 2026-07-25 15:54:52 +08:00
Shen Mintao 51b7b6e729 test: unify legacy Wi-Fi Bluetooth and ZLP support
# Conflicts:
#	.gitattributes
#	README.md
2026-07-25 15:54:23 +08:00
Shen Mintao 1f0c3e28ac docs: point issue 71 to maintained legacy commit 2026-07-24 14:28:47 +08:00
Shen Mintao 59e6b00abe docs: add DC/DW support to legacy MCU1 profile 2026-07-24 14:26:48 +08:00
Shen Mintao dbfbfa0c64 test: use complete V3 DC/DW profile for issue 71 2026-07-24 14:24:30 +08:00
Shen Mintao cc2a888d22 docs: promote MCU1 legacy firmware profile 2026-07-24 09:14:27 +08:00
Shen Mintao 027a7a8662 test: restore MCU1 cache fix for V3 firmware 2026-07-23 09:10:43 +08:00
Shen Mintao 7b2541e5c0 test: match D80 loader to legacy firmware 2026-07-22 16:55:44 +08:00
Shen Mintao bff42860ff test: add legacy D80 firmware for issue 58 2026-07-21 19:59:51 +08:00
63 changed files with 1203 additions and 1808 deletions
+4
View File
@@ -1,3 +1,7 @@
fw/aic8800D80/*.txt text eol=lf
fw/aic8800D80/*.bin binary
fw/aic8800DC/*.txt text eol=lf
fw/aic8800DC/*.bin binary
/.gitattributes text eol=lf /.gitattributes text eol=lf
drivers/aic8800/aic_zlp_quirk/*.c text eol=lf drivers/aic8800/aic_zlp_quirk/*.c text eol=lf
drivers/aic8800/aic_zlp_quirk/Makefile text eol=lf drivers/aic8800/aic_zlp_quirk/Makefile text eol=lf
-67
View File
@@ -1,67 +0,0 @@
# Building with OpenWrt backports
OpenWrt's target kernel and wireless stack can have different versions.
For example, [issue #94](https://github.com/shenmintao/aic8800d80/issues/94)
uses Linux **6.12.94** with **backports 6.18.26** on OpenWrt 25.12.5.
The Ubuntu build host's kernel version is not used to select these APIs.
## Package Makefile
Pass `CFG80211_VERSION=6.18.26` to the kernel make invocation for that
combination. Use the `PKG_VERSION` from your OpenWrt
`package/kernel/mac80211/Makefile`, in `major.minor.patch` format. Keep the
backports include paths and symbol versions from the same build:
```make
NOSTDINC_FLAGS := \
$(KERNEL_NOSTDINC_FLAGS) \
-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
-I$(STAGING_DIR)/usr/include/mac80211-backport \
-I$(STAGING_DIR)/usr/include/mac80211/uapi \
-I$(STAGING_DIR)/usr/include/mac80211 \
-include backport/backport.h
define Build/Compile
+$(KERNEL_MAKE) $(PKG_JOBS) \
M="$(PKG_BUILD_DIR)/drivers/aic8800" \
KBUILD_EXTRA_SYMBOLS="$(LINUX_DIR)/../symvers/mac80211.symvers" \
NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
CFG80211_VERSION=6.18.26 \
modules
endef
```
The package must depend on `kmod-cfg80211` so its headers and symbol versions
are staged before this driver is built. Keep any additional dependencies,
firmware installation rules and module packaging rules your device needs.
Update the package's pinned source revision to one containing this fix, or
apply the fix as an OpenWrt package patch, then clean and rebuild the package:
```sh
make package/kernel/aic8800d80/clean
make package/kernel/aic8800d80/compile V=sc -j1
```
Changing `CFG80211_VERSION` alone does not update the driver source or the
wireless headers. The value must match the actual wireless stack; do not set
it to the host kernel version or redefine `LINUX_VERSION_CODE`.
## Compatibility scope
The override selects the wireless API changes since Linux 6.12, including
monitor-channel callbacks, radio/link arguments, radar notifications and
newer cfg80211 callbacks. Timer, USB, memory-management and module namespace
checks continue to use the target kernel version. Older target kernels with
newer backports may need additional wireless API adaptations.
Leave `CFG80211_VERSION` unset when building against the kernel's own wireless
stack, as on a regular Ubuntu/Debian installation. The driver then uses the
kernel version as before. Hardware revision still determines whether to use
`main` or `legacy-mcu1`; a wireless API mismatch does not change that choice.
The feeds/Kconfig duplicate definitions and recursive dependencies also
reported in issue #94 belong to the OpenWrt build configuration and require
separate investigation.
See the [build regression recipe](tests/openwrt-backports/README.md) for
the tested kernel/backports combinations and a script to repeat the build.
+23 -45
View File
@@ -1,32 +1,26 @@
# AIC8800 Linux Wi-Fi and Bluetooth Driver # AIC8800 Linux Wi-Fi and Bluetooth Driver
This driver is for the AIC8800D80 chipset, supported by devices such as the Tenda U11 and AX913B. This driver supports AIC8800-family chipsets used by devices such as the Tenda U11, AX913B, and TP-Link Archer TX1U Nano.
> [!IMPORTANT] > **Legacy MCU revision 1 branch:** You are viewing `legacy-mcu1`. This branch
> **Choose the branch for your hardware revision before installing.** If the > is only for AIC8800D80 or AIC8800DC/DW devices that report
> driver log reports `chip_id=7, chip_mcu_id=1` on an AIC8800D80 or > `chip_id=7, chip_mcu_id=1`. It provides complete matched V3 firmware and
> AIC8800DC/DW device, use the > loader profiles for the D80 upload-limit failure validated in
> [`legacy-mcu1`](https://github.com/shenmintao/aic8800d80/tree/legacy-mcu1) > [issue #58](https://github.com/shenmintao/aic8800d80/issues/58) and the DC/DW
> branch. It contains the matched legacy firmware and loader profile required > V5 main-application timeout validated in
> to avoid the deterministic firmware upload timeout at `0x170400`. Use > [issue #71](https://github.com/shenmintao/aic8800d80/issues/71). Use
> `main` when `chip_mcu_id=0` or when the MCU revision is unknown. > [`main`](https://github.com/shenmintao/aic8800d80/tree/main) for newer
> `chip_mcu_id=0` hardware or when the MCU revision is unknown. See the
> [D80](tests/issue58-mcu1-legacy-fw/README.md) and
> [DC/DW](tests/issue71-mcu1-v3-profile/README.md) support notes before installing.
> >
> Hardware revision determines the firmware branch. MCU1 devices should use > After switching branches, rerun `sudo ./install.sh` and reboot; switching the
> `legacy-mcu1`, which also initializes Bluetooth for the > Git branch alone does not replace firmware already installed under
> kernel's standard `btusb` driver. After switching branches, rerun > `/lib/firmware`.
> `sudo ./install.sh` and reboot; switching the Git branch alone does not
> replace the firmware already installed under `/lib/firmware`.
Added support for devices with Vendor ID 368B (tested). 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.
> [!NOTE]
> **Maintained branches:** This repository now maintains two hardware branches:
> `main` for `chip_mcu_id=0` or an unknown MCU revision, and `legacy-mcu1` for
> `chip_mcu_id=1`. Wi-Fi, the kernel's standard `btusb` Bluetooth path, and the
> device-scoped ZLP support are integrated into both branches. The former
> separate `bluetooth` branch is retired and should no longer be used.
The same driver supports Wi-Fi-only adapters and Wi-Fi/Bluetooth combo The same driver supports Wi-Fi-only adapters and Wi-Fi/Bluetooth combo
adapters. On combo devices, `aic_load_fw` uploads the AIC firmware and the adapters. On combo devices, `aic_load_fw` uploads the AIC firmware and the
standard Linux `btusb` driver handles the Bluetooth HCI interface. The obsolete standard Linux `btusb` driver handles the Bluetooth HCI interface. The obsolete
@@ -39,38 +33,22 @@ the distribution's original `btusb.ko` installed and bound to the device. The
quirk is filtered to that VID:PID and fails closed when the required kernel quirk is filtered to that VID:PID and fails closed when the required kernel
probe support is unavailable. probe support is unavailable.
> [!NOTE]
> **Maintained branches:** This repository now maintains only `main` and
> `legacy-mcu1`. You are viewing the branch for `chip_mcu_id=1`; do not switch
> this hardware to the former separate `bluetooth` branch, which is retired.
> Wi-Fi, the kernel's standard `btusb` Bluetooth path, and the device-scoped
> `368b:8d81` ZLP support are integrated here. The ZLP module remains inactive
> on other VID:PID combinations.
### Disclaimer ### Disclaimer
I did not develop this software, The code is sourced from the Tenda U11 driver. I only made some modifications to the code to adapt it to newer kernel versions. Apart from compilation issues, I am unable to address other problems. I did not develop this software, The code is sourced from the Tenda U11 driver. I only made some modifications to the code to adapt it to newer kernel versions. Apart from compilation issues, I am unable to address other problems.
### Attention ### Attention
Before installing the driver, delete all aic8800-related folders under /lib/firmware. Using an incorrect firmware version may cause the system to freeze. Before installing the driver, delete all aic8800-related folders under /lib/firmware. Using an incorrect firmware version may cause the system to freeze.
#### Pandora 88M80 mode switching
Pandora 88M80 adapters that initially appear as USB device `1111:1111` are
automatically switched to `a69c:8d80` by sending the required `F3` then `F2`
commands. Existing users must rerun `sudo ./install.sh` to replace the installed
usb_modeswitch configuration, then unplug the adapter completely and plug it
back in.
If automatic switching does not occur, try the same sequence manually:
```bash
sudo usb_modeswitch -v 1111 -p 1111 \
-M "555342438765432100000000000010fd0000000000000000000000000000f3" \
-2 "555342438765432100000000000010fd0000000000000000000000000000f2"
```
This only addresses switching from `1111:1111` to `a69c:8d80`. If the device
has reached `a69c:8d80` but firmware startup still fails, see
[issue #79](https://github.com/shenmintao/aic8800d80/issues/79).
### Installation Steps ### Installation Steps
For OpenWrt SDK/buildroot builds, see [OpenWrt build notes](OPENWRT.md).
OpenWrt can use a newer cfg80211 backport than its target kernel; these builds
must pass the wireless stack version separately.
#### Method 1: [Quick Installation](INSTALL_SCRIPT.md) (Recommended) #### Method 1: [Quick Installation](INSTALL_SCRIPT.md) (Recommended)
#### Method 2: Manual Installation #### Method 2: Manual Installation
-1
View File
@@ -1,6 +1,5 @@
# AIC8800 USB mass-storage mode switch rules # AIC8800 USB mass-storage mode switch rules
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5722", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5723", SYMLINK+="tendaudisk", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5723", SYMLINK+="tendaudisk", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5724", SYMLINK+="ugreenax900", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5724", SYMLINK+="ugreenax900", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5725", SYMLINK+="tendaudiskv2", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5725", SYMLINK+="tendaudiskv2", RUN+="/usr/bin/eject /dev/%k"
+6 -26
View File
@@ -1,14 +1,9 @@
%global commit 3e9a02549bc98d350bff1e0fb0501f841f9d8e55 %global commit 51b7b6e72989afe4d21f52e55b70f5a4d6b21e5b
%global shortcommit %(echo %{commit} | cut -c1-7) %global shortcommit %(echo %{commit} | cut -c1-7)
%global snapdate 20260924
%global debug_package %{nil}
%{!?kver:%global kver %(uname -r)} %{!?kver:%global kver %(uname -r)}
Name: aic8800d80 Name: aic8800d80
# Versions before 2026-09-24 were bare commit hashes, which rpm does not Version: %{shortcommit}
# order by commit history. Epoch 1 sorts every snapshot version after them.
Epoch: 1
Version: 1.0.0^%{snapdate}git%{shortcommit}
Release: 1%{?dist} Release: 1%{?dist}
Summary: AIC8800 USB Wi-Fi, Bluetooth firmware, and ZLP quirk driver Summary: AIC8800 USB Wi-Fi, Bluetooth firmware, and ZLP quirk driver
@@ -22,7 +17,7 @@ BuildRequires: kernel-devel-uname-r = %{kver}
Requires: kernel-uname-r = %{kver} Requires: kernel-uname-r = %{kver}
Requires: /usr/bin/eject Requires: /usr/bin/eject
Requires: usb_modeswitch Requires: /usr/sbin/usb_modeswitch
Requires(post): /usr/sbin/depmod Requires(post): /usr/sbin/depmod
Requires(postun): /usr/sbin/depmod Requires(postun): /usr/sbin/depmod
@@ -82,24 +77,9 @@ cp -a fw/aic8800* %{buildroot}/usr/lib/firmware/
/usr/lib/firmware/aic8800* /usr/lib/firmware/aic8800*
%changelog %changelog
* Thu Sep 24 2026 Shen Mintao <shenmintao@gmail.com> - 1:1.0.0^20260924git3e9a025-1 * Sat Jul 25 2026 Shen Mintao <shenmintao@gmail.com> - 51b7b6e-1
- Version snapshots as 1.0.0^<date>git<commit> with Epoch 1. The previous - Package the unified installer and ZLP quirk with the legacy MCU1 profiles.
commit-hash versions do not sort in commit order, so rpm could treat a - Preserve the matched D80 and DC/DW firmware and loader combinations.
newer snapshot as an older package.
* Thu Sep 24 2026 Shen Mintao <shenmintao@gmail.com> - 3e9a025-1
- Build the current main branch, which adds the Linux 7.1+ TDLS discovery
response length fix, the SUN60IW2P1 USB transfer settings, OpenWrt
cfg80211 backport version handling and the 6.12 stable
set_monitor_channel() fix.
* Fri Aug 21 2026 Heyde Moura <moura.heyde@gmail.com> - e93a7d2-1
- Build the current main branch, which carries the Linux 7.2 cfg80211 and
strncpy() fixes needed to compile on Bazzite 44.
* Tue Jul 28 2026 ccyuen1 - 13baa9b-2
- Disable automatic creation of debuginfo packages to fix issue #77.
- Require usb_modeswitch as package dependency instead of file dependency to fix issue #77.
* Sat Jul 25 2026 Shen Mintao <shenmintao@gmail.com> - 13baa9b-1 * Sat Jul 25 2026 Shen Mintao <shenmintao@gmail.com> - 13baa9b-1
- Unify Wi-Fi and standard-btusb Bluetooth support in one package. - Unify Wi-Fi and standard-btusb Bluetooth support in one package.
+2
View File
@@ -61,6 +61,8 @@ endif
########################################### ###########################################
MAKEFLAGS +=-j$(shell nproc)
KERNEL_AUTOCONF := $(KDIR)/include/config/auto.conf KERNEL_AUTOCONF := $(KDIR)/include/config/auto.conf
KERNEL_CONFIG := $(KDIR)/.config KERNEL_CONFIG := $(KDIR)/.config
KERNEL_CC_IS_CLANG := $(shell if [ -r "$(KERNEL_AUTOCONF)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_AUTOCONF)"; then echo y; elif [ -r "$(KERNEL_CONFIG)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_CONFIG)"; then echo y; fi) KERNEL_CC_IS_CLANG := $(shell if [ -r "$(KERNEL_AUTOCONF)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_AUTOCONF)"; then echo y; elif [ -r "$(KERNEL_CONFIG)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_CONFIG)"; then echo y; fi)
+3 -19
View File
@@ -2,16 +2,6 @@ EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS)
EXTRA_CFLAGS += -Wno-implicit-fallthrough EXTRA_CFLAGS += -Wno-implicit-fallthrough
#EXTRA_CFLAGS += -Wno-unused-variable #EXTRA_CFLAGS += -Wno-unused-variable
# OpenWrt may build a newer cfg80211 backport on an older kernel.
# Set this to the wireless stack's version, e.g. CFG80211_VERSION=6.18.26.
ifneq ($(strip $(CFG80211_VERSION)),)
aicwf_cfg80211_version := $(subst ., ,$(CFG80211_VERSION))
ifneq ($(words $(aicwf_cfg80211_version)),3)
$(error CFG80211_VERSION must have the form major.minor.patch)
endif
ccflags-y += '-DAICWF_CFG80211_VERSION_CODE=KERNEL_VERSION($(word 1,$(aicwf_cfg80211_version)),$(word 2,$(aicwf_cfg80211_version)),$(word 3,$(aicwf_cfg80211_version)))'
endif
RWNX_VERS_NUM := 6.4.3.0 RWNX_VERS_NUM := 6.4.3.0
CONFIG_AIC8800_WLAN_SUPPORT = m CONFIG_AIC8800_WLAN_SUPPORT = m
@@ -84,11 +74,7 @@ CONFIG_VHT_FOR_OLD_KERNEL = n
CONFIG_COEX = y CONFIG_COEX = y
CONFIG_ALIGN_8BYTES = y CONFIG_ALIGN_8BYTES = y
CONFIG_TXRX_THREAD_PRIO = y CONFIG_TXRX_THREAD_PRIO = y
ifdef CONFIG_ARCH_SUN60IW2P1
CONFIG_USB_ALIGN_DATA = n
else
CONFIG_USB_ALIGN_DATA = y CONFIG_USB_ALIGN_DATA = y
endif
CONFIG_RX_TASKLET = n CONFIG_RX_TASKLET = n
CONFIG_TX_TASKLET = n CONFIG_TX_TASKLET = n
CONFIG_RX_NETIF_RECV_SKB = y CONFIG_RX_NETIF_RECV_SKB = y
@@ -102,11 +88,7 @@ CONFIG_WOWLAN ?= n
CONFIG_USB_RX_AGGR = n CONFIG_USB_RX_AGGR = n
CONFIG_USB_TX_AGGR = n CONFIG_USB_TX_AGGR = n
ifdef CONFIG_ARCH_SUN60IW2P1
CONFIG_USB_NO_TRANS_DMA_MAP = y
else
CONFIG_USB_NO_TRANS_DMA_MAP = n CONFIG_USB_NO_TRANS_DMA_MAP = n
endif
CONFIG_GPIO_WAKEUP = n CONFIG_GPIO_WAKEUP = n
CONFIG_CREATE_TRACE_POINTS = n CONFIG_CREATE_TRACE_POINTS = n
CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y
@@ -172,7 +154,7 @@ CONFIG_RWNX_BCMC ?= y
# Enable Monitor+Data interface support (need FW support) # Enable Monitor+Data interface support (need FW support)
CONFIG_RWNX_MON_DATA =n CONFIG_RWNX_MON_DATA =n
CONFIG_RWNX_MON_XMIT ?= y CONFIG_RWNX_MON_XMIT ?= n
CONFIG_RWNX_MON_RXFILTER ?= n CONFIG_RWNX_MON_RXFILTER ?= n
CONFIG_FILTER_TCP_ACK =y CONFIG_FILTER_TCP_ACK =y
@@ -367,6 +349,8 @@ ccflags-$(CONFIG_TEMP_CONTROL) += -DCONFIG_TEMP_CONTROL
ccflags-$(CONFIG_POWER_LIMIT) += -DCONFIG_POWER_LIMIT ccflags-$(CONFIG_POWER_LIMIT) += -DCONFIG_POWER_LIMIT
ccflags-$(CONFIG_EXT_FEM_8800DCDW) += -DCONFIG_EXT_FEM_8800DCDW ccflags-$(CONFIG_EXT_FEM_8800DCDW) += -DCONFIG_EXT_FEM_8800DCDW
ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN
MAKEFLAGS +=-j$(shell nproc)
# Platform support list # Platform support list
CONFIG_PLATFORM_ROCKCHIP ?= n CONFIG_PLATFORM_ROCKCHIP ?= n
CONFIG_PLATFORM_ALLWINNER ?= n CONFIG_PLATFORM_ALLWINNER ?= n
+4 -4
View File
@@ -1832,7 +1832,7 @@ void set_vendor_extension_ie(char *command){
} }
#endif//CONFIG_SET_VENDOR_EXTENSION_IE #endif//CONFIG_SET_VENDOR_EXTENSION_IE
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, struct net_device *dev, int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_chan_def *chandef); struct cfg80211_chan_def *chandef);
#else #else
@@ -1840,7 +1840,7 @@ int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef); struct cfg80211_chan_def *chandef);
#endif #endif
int rwnx_atoi2(char *value, int c_len); int rwnx_atoi2(char *value, int c_len);
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter) void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter)
#else #else
void set_mon_chan(struct rwnx_vif *vif, char *parameter) void set_mon_chan(struct rwnx_vif *vif, char *parameter)
@@ -1867,7 +1867,7 @@ void set_mon_chan(struct rwnx_vif *vif, char *parameter)
chandef->center_freq1 = chandef->chan->center_freq; chandef->center_freq1 = chandef->chan->center_freq;
chandef->center_freq2 = 0; chandef->center_freq2 = 0;
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, dev, chandef); rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, dev, chandef);
#else #else
rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, chandef); rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, chandef);
@@ -2136,7 +2136,7 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
char *set_parameter; char *set_parameter;
skip = strlen(CMD_SET_MON_FREQ) + 1; skip = strlen(CMD_SET_MON_FREQ) + 1;
set_parameter = command + skip; set_parameter = command + skip;
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
set_mon_chan(vif, net, set_parameter); set_mon_chan(vif, net, set_parameter);
#else #else
set_mon_chan(vif, set_parameter); set_mon_chan(vif, set_parameter);
+1 -1
View File
@@ -62,7 +62,7 @@ int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val);
unsigned int command_strtoul(const char *cp, char **endp, unsigned int base); unsigned int command_strtoul(const char *cp, char **endp, unsigned int base);
int str_starts(const char *str, const char *start); int str_starts(const char *str, const char *start);
int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len); int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len);
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter); void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter);
#else #else
void set_mon_chan(struct rwnx_vif *vif, char *parameter); void set_mon_chan(struct rwnx_vif *vif, char *parameter);
@@ -40,8 +40,7 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){
char *filename = FW_USERCONFIG_NAME_8800D80; char *filename = FW_USERCONFIG_NAME_8800D80;
#ifndef ANDROID_PLATFORM #ifndef ANDROID_PLATFORM
if (strlcat(aic_fw_path, "/aic8800D80", sizeof(aic_fw_path)) >= sizeof(aic_fw_path)) sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80");
return -ENAMETOOLONG;
#endif #endif
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
@@ -41,8 +41,7 @@ int rwnx_plat_userconfig_load_8800d80x2(struct rwnx_hw *rwnx_hw){
char *filename = FW_USERCONFIG_NAME_8800D80X2; char *filename = FW_USERCONFIG_NAME_8800D80X2;
#ifndef ANDROID_PLATFORM #ifndef ANDROID_PLATFORM
if (strlcat(aic_fw_path, "/aic8800D80X2", sizeof(aic_fw_path)) >= sizeof(aic_fw_path)) sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80X2");
return -ENAMETOOLONG;
#endif #endif
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
+185 -267
View File
@@ -45,6 +45,8 @@
#define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt" #define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt"
#define FW_POWERLIMIT_NAME_8800DC "aic_powerlimit_8800dc.txt" #define FW_POWERLIMIT_NAME_8800DC "aic_powerlimit_8800dc.txt"
#define FW_POWERLIMIT_NAME_8800DW "aic_powerlimit_8800dw.txt" #define FW_POWERLIMIT_NAME_8800DW "aic_powerlimit_8800dw.txt"
#define FW_USERCONFIG_NAME_8800DW_W311 "aic_userconfig_8800dw_w311.txt"
#define FW_USERCONFIG_NAME_8800DW_U2 "aic_userconfig_8800dw_u2.txt"
#ifdef CONFIG_LOAD_BT_PATCH_IN_FDRV #ifdef CONFIG_LOAD_BT_PATCH_IN_FDRV
enum aicbt_patch_table_type { enum aicbt_patch_table_type {
@@ -167,7 +169,6 @@ u32 syscfg_tbl_masked_8800dc[][3] = {
{0x700010A0, (0x1 << 11), (0x1 << 11)}, {0x700010A0, (0x1 << 11), (0x1 << 11)},
{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, {0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
{0x70001038, (0x1 << 8), (0x1 << 8)}, {0x70001038, (0x1 << 8), (0x1 << 8)},
{0x70001084, (0x3 << 13), (0x0 << 13)},
{0x70001094, (0x3 << 2), (0x0 << 2)}, {0x70001094, (0x3 << 2), (0x0 << 2)},
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
{0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)), {0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)),
@@ -185,7 +186,6 @@ u32 syscfg_tbl_masked_8800dc[][3] = {
{0x700010A0, (0x1 << 11), (0x1 << 11)}, {0x700010A0, (0x1 << 11), (0x1 << 11)},
{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, {0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
{0x70001038, (0x1 << 8), (0x1 << 8)}, {0x70001038, (0x1 << 8), (0x1 << 8)},
{0x70001084, (0x3 << 13), (0x0 << 13)},
{0x70001094, (0x3 << 2), (0x0 << 2)}, {0x70001094, (0x3 << 2), (0x0 << 2)},
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
{0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)), {0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)),
@@ -211,7 +211,6 @@ u32 syscfg_tbl_masked_8800dc_h[][3] = {
{0x700010A0, (0x1 << 11), (0x1 << 11)}, {0x700010A0, (0x1 << 11), (0x1 << 11)},
//{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, //{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))},
{0x70001038, (0x1 << 8), (0x1 << 8)}, {0x70001038, (0x1 << 8), (0x1 << 8)},
{0x70001084, (0x3 << 13), (0x0 << 13)},
{0x70001094, (0x3 << 2), (0x0 << 2)}, {0x70001094, (0x3 << 2), (0x0 << 2)},
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
#if defined(CONFIG_VRF_DCDC_MODE) #if defined(CONFIG_VRF_DCDC_MODE)
@@ -243,6 +242,7 @@ u32 syscfg_tbl_8800dc[][2] = {
u32 patch_tbl_wifisetting[][2] = u32 patch_tbl_wifisetting[][2] =
{ {
{0x0004, 0x00020010}, //wdt_reboot_type, wdt_period_sec
#if !defined(CONFIG_FPGA_VERIFICATION) #if !defined(CONFIG_FPGA_VERIFICATION)
{0x0090, 0x0013FC00}, //rx_ringbuf_start2 {0x0090, 0x0013FC00}, //rx_ringbuf_start2
#endif #endif
@@ -251,9 +251,10 @@ u32 patch_tbl_wifisetting[][2] =
{0x0120, 0x140A0100}, //usb agg tx params(total cnt, aggr cnt, out en, global out nak) {0x0120, 0x140A0100}, //usb agg tx params(total cnt, aggr cnt, out en, global out nak)
#endif //CONFIG_USB_TX_AGGR #endif //CONFIG_USB_TX_AGGR
{0x00b0, 0xAD180100}, {0x00b0, 0xAD180100},
#ifdef CONFIG_PRBREQ_REPORT #ifdef CONFIG_BAND_STEERING
{0x0138, 0x00010a00}, //apm probe resp offload en {0x0138, 0x00010a00}, //apm probe resp offload en
#endif #endif
{0x0084, 0x00000040},
}; };
u32 jump_tbl[][2] = u32 jump_tbl[][2] =
@@ -1871,104 +1872,104 @@ const uint32_t txgain_map_femkct[96] =
const uint32_t txgain_map_femkct_h[96] = const uint32_t txgain_map_femkct_h[96] =
{ {
//11b //11b
0x00ffd86c,//15 0x00ffd872,//15
0x00ffd879,//16 0x00ffd880,//16
0x00ffd96c,//17 0x00ffd972,//17
0x00ffd979,//18 0x00ffd980,//18
0x00ffd988,//19 0x00ffd990,//19
0x00ffda6c,//20 0x00ffda72,//20
0x00ffda79,//21 0x00ffda80,//21
0x00ffdb6c,//22 0x00ffdb72,//22
0x00ffdb79,//23 0x00ffdb80,//23
0x00ffdc6c,//24 0x00ffdc72,//24
0x00ffdc79,//25 0x00ffdc80,//25
0x00ffdd6c,//26 0x00ffdd72,//26
0x00ffdd79,//27 0x00ffdd80,//27
0x00ffde6c,//28 0x00ffde72,//28
0x00ffde79,//29 0x00ffde80,//29
0x00ffdf6c,//30 0x00ffdf72,//30
0x00ffd06c,//-1 0x00ffd072,//-1
0x00ffd06c,//0 0x00ffd072,//0
0x00ffd079,//1 0x00ffd080,//1
0x00ffd16c,//2 0x00ffd172,//2
0x00ffd179,//3 0x00ffd180,//3
0x00ffd26c,//4 0x00ffd272,//4
0x00ffd279,//5 0x00ffd280,//5
0x00ffd372,//6 0x00ffd379,//6
0x00ffd467,//7 0x00ffd46d,//7
0x00ffd472,//8 0x00ffd479,//8
0x00ffd56c,//9 0x00ffd572,//9
0x00ffd579,//10 0x00ffd580,//10
0x00ffd66c,//11 0x00ffd672,//11
0x00ffd679,//12 0x00ffd680,//12
0x00ffd76c,//13 0x00ffd772,//13
0x00ffd779,//14 0x00ffd780,//14
//high //high
0x00ffc879,//11 0x00ffc880,//11
0x00ffc96c,//12 0x00ffc972,//12
0x00ffc979,//13 0x00ffc980,//13
0x00ffca6c,//14 0x00ffca72,//14
0x00ffca79,//15 0x00ffca80,//15
0x00ffcb6c,//16 0x00ffcb72,//16
0x00ffcb79,//17 0x00ffcb80,//17
0x00ffcc6c,//18 0x00ffcc72,//18
0x00ffcc79,//19 0x00ffcc80,//19
0x00ffcc88,//20 0x00ffcc90,//20
0x00ffcd6c,//21 0x00ffcd72,//21
0x00ffcd79,//22 0x00ffcd80,//22
0x00ffce6c,//23 0x00ffce72,//23
0x00ffce79,//24 0x00ffce80,//24
0x00ffcf6c,//25 0x00ffcf72,//25
0x00ffcf79,//26 0x00ffcf80,//26
0x00ffc079,//-5 0x00ffc080,//-5
0x00ffc16c,//-4 0x00ffc172,//-4
0x00ffc179,//-3 0x00ffc180,//-3
0x00ffc26c,//-2 0x00ffc272,//-2
0x00ffc279,//-1 0x00ffc280,//-1
0x00ffc36c,//0 0x00ffc372,//0
0x00ffc379,//1 0x00ffc380,//1
0x00ffc46c,//2 0x00ffc472,//2
0x00ffc479,//3 0x00ffc480,//3
0x00ffc56c,//4 0x00ffc572,//4
0x00ffc579,//5 0x00ffc580,//5
0x00ffc66c,//6 0x00ffc672,//6
0x00ffc679,//7 0x00ffc680,//7
0x00ffc76c,//8 0x00ffc772,//8
0x00ffc779,//9 0x00ffc780,//9
0x00ffc86c,//10 0x00ffc872,//10
//low //low
0x00ffc879,//11 0x00ffc880,//11
0x00ffc96c,//12 0x00ffc972,//12
0x00ffc979,//13 0x00ffc980,//13
0x00ffca6c,//14 0x00ffca72,//14
0x00ffca79,//15 0x00ffca80,//15
0x00ffcb6c,//16 0x00ffcb72,//16
0x00ffcb79,//17 0x00ffcb80,//17
0x00ffcc6c,//18 0x00ffcc72,//18
0x00ffcc79,//19 0x00ffcc80,//19
0x00ffcc88,//20 0x00ffcc90,//20
0x00ffcd6c,//21 0x00ffcd72,//21
0x00ffcd79,//22 0x00ffcd80,//22
0x00ffce6c,//23 0x00ffce72,//23
0x00ffce79,//24 0x00ffce80,//24
0x00ffcf6c,//25 0x00ffcf72,//25
0x00ffcf79,//26 0x00ffcf80,//26
0x00ffc079,//-5 0x00ffc080,//-5
0x00ffc16c,//-4 0x00ffc172,//-4
0x00ffc179,//-3 0x00ffc180,//-3
0x00ffc26c,//-2 0x00ffc272,//-2
0x00ffc279,//-1 0x00ffc280,//-1
0x00ffc36c,//0 0x00ffc372,//0
0x00ffc379,//1 0x00ffc380,//1
0x00ffc46c,//2 0x00ffc472,//2
0x00ffc479,//3 0x00ffc480,//3
0x00ffc56c,//4 0x00ffc572,//4
0x00ffc579,//5 0x00ffc580,//5
0x00ffc66c,//6 0x00ffc672,//6
0x00ffc679,//7 0x00ffc680,//7
0x00ffc76c,//8 0x00ffc772,//8
0x00ffc779,//9 0x00ffc780,//9
0x00ffc86c,//10 0x00ffc872,//10
}; };
#endif #endif
@@ -2204,141 +2205,6 @@ uint32_t wifi_txgain_table_24g_1_8800dcdw_femkct[32] = {
}; };
#endif #endif
#ifdef CONFIG_5M10M
u32 wifi_rxgain_table_24g_dcdw_5m[64] = {
0x82f282d1,//index 0
0x9591a200,
0x80808419,
0x000000f0,
0x42f282d1,//index 1
0x95923400,
0x80808419,
0x000000f0,
0x22f282d1,//index 2
0x9592c600,
0x80808419,
0x000000f0,
0x02f282d1,//index 3
0x9591a200,
0x80808419,
0x000000f0,
0x06f282d1,//index 4
0x9591a200,
0x80808419,
0x000000f0,
0x0ef282d1,//index 5
0x9591a200,
0x80808419,
0x000000f0,
0x0ef282d3,//index 6
0x95923400,
0x80808419,
0x000000f0,
0x0ef282d7,//index 7
0x9595a200,
0x80808419,
0x000000f0,
0x02f282d2,//index 8
0x95951000,
0x80808419,
0x000000f0,
0x02f282f4,//index 9
0x95951000,
0x80808419,
0x000000f0,
0x02f282e6,//index 10
0x9595a200,
0x80808419,
0x000000f0,
0x02f282e6,//index 11
0x9599a200,
0x80808419,
0x000000f0,
0x02f282e6,//index 12
0x959da200,
0x80808419,
0x000000f0,
0x02f282e6,//index 13
0x959f5800,
0x80808419,
0x000000f0,
0x06f282e6,//index 14
0x959f5800,
0x80808419,
0x000000f0,
0x0ef282e6,//index 15
0x959f5800,
0x80808419,
0x000000f0
};
u32 wifi_rxgain_table_24g_dcdw_10m[64] = {
0x82f282d1,//index 0
0x9591a320,
0x80808419,
0x000000f0,
0x42f282d1,//index 1
0x95923520,
0x80808419,
0x000000f0,
0x22f282d1,//index 2
0x9592c720,
0x80808419,
0x000000f0,
0x02f282d1,//index 3
0x9591a320,
0x80808419,
0x000000f0,
0x06f282d1,//index 4
0x9591a320,
0x80808419,
0x000000f0,
0x0ef282d1,//index 5
0x9591a320,
0x80808419,
0x000000f0,
0x0ef282d3,//index 6
0x95923520,
0x80808419,
0x000000f0,
0x0ef282d7,//index 7
0x9595a320,
0x80808419,
0x000000f0,
0x02f282d2,//index 8
0x95951120,
0x80808419,
0x000000f0,
0x02f282f4,//index 9
0x95951120,
0x80808419,
0x000000f0,
0x02f282e6,//index 10
0x9595a320,
0x80808419,
0x000000f0,
0x02f282e6,//index 11
0x9599a320,
0x80808419,
0x000000f0,
0x02f282e6,//index 12
0x959da320,
0x80808419,
0x000000f0,
0x02f282e6,//index 13
0x959f5920,
0x80808419,
0x000000f0,
0x06f282e6,//index 14
0x959f5920,
0x80808419,
0x000000f0,
0x0ef282e6,//index 15
0x959f5920,
0x80808419,
0x000000f0
};
#endif
u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = { u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = {
0x82f282d1,//index 0 0x82f282d1,//index 0
0x9591a324, 0x9591a324,
@@ -3057,13 +2923,7 @@ int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_c
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32, 0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256))) if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32, 0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256)))
return -1; return -1;
#ifdef CONFIG_5M10M
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 0, (u8_l *)wifi_rxgain_table_24g_dcdw_5m, 256)))
return -1;
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 48, 0, (u8_l *)wifi_rxgain_table_24g_dcdw_10m, 256)))
return -1;
#endif
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) { if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
return -1; return -1;
} }
@@ -3178,35 +3038,61 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out)
uint32_t misc_ram_addr; uint32_t misc_ram_addr;
uint32_t ram_base_addr, ram_word_cnt; uint32_t ram_base_addr, ram_word_cnt;
uint32_t bit_mask[4]; uint32_t bit_mask[4];
uint32_t dpd_info_read_addr = 0xfe004;
uint32_t boot_argc_read_addr = 0x1220f0;
uint32_t flash_size_mem_addr = 0x40038030;
uint8_t flash_size = 0;
int i; int i;
if (valid_out) { if (valid_out) {
*valid_out = 0; *valid_out = 0;
} }
AICWFDBG(LOGINFO, "issue71: checking legacy V3 DPD result\n");
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, boot_argc_read_addr, &cfm);
if (ret) {
AICWFDBG(LOGERROR, "boot argc [0x%x] rd fail: %d\n", boot_argc_read_addr, ret);
return ret;
}
AICWFDBG(LOGINFO, "issue71: boot argc=0x%x\n", cfm.memdata);
if (cfm.memdata & 0x10) {
if (valid_out) {
*valid_out = 1;
}
AICWFDBG(LOGINFO, "issue71: boot arguments mark DPD result valid\n");
return ret;
}
if (chip_mcu_id) {
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, flash_size_mem_addr, &cfm);
if (ret) {
AICWFDBG(LOGERROR, "flash size[0x%x] rd fail: %d\n", flash_size_mem_addr, ret);
return ret;
}
flash_size = cfm.memdata & 0xff;
if (flash_size == 0x16) {
dpd_info_read_addr += 0x4300000;
} else if (flash_size == 0x15) {
dpd_info_read_addr += 0x4100000;
} else if (flash_size == 0x18) {
dpd_info_read_addr += 0x4700000;
} else {
dpd_info_read_addr += 0x4100000;
}
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, dpd_info_read_addr, &cfm);
if (ret) {
AICWFDBG(LOGERROR, "dpd info [0x%x] rd fail: %d\n", dpd_info_read_addr, ret);
return ret;
}
AICWFDBG(LOGINFO,
"issue71: flash size=0x%x, DPD info [0x%x]=0x%x\n",
flash_size, dpd_info_read_addr, cfm.memdata);
if (cfm.memdata & (1<<7)) {
if (valid_out) {
*valid_out = 1;
}
AICWFDBG(LOGINFO, "issue71: legacy V3 flash DPD result is valid\n");
}
} else {
if (testmode == FW_RFTEST_MODE) { if (testmode == FW_RFTEST_MODE) {
uint32_t vect1 = 0;
uint32_t vect2 = 0;
cfg_base = RAM_LMAC_FW_ADDR + 0x0004;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm);
if (ret) {
AICWFDBG(LOGERROR, "cfg_base:%x vcet1 rd fail: %d\n", cfg_base, ret);
return ret;
}
vect1 = cfm.memdata;
if ((vect1 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) {
AICWFDBG(LOGERROR, "vect1 invalid: %x\n", vect1);
return ret;
}
cfg_base = RAM_LMAC_FW_ADDR + 0x0008;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm);
if (ret) {
AICWFDBG(LOGERROR, "cfg_base:%x vcet2 rd fail: %d\n", cfg_base, ret);
return ret;
}
vect2 = cfm.memdata;
if ((vect2 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) {
AICWFDBG(LOGERROR, "vect2 invalid: %x\n", vect2);
return ret;
}
cfg_base = RAM_LMAC_FW_ADDR + 0x0164; cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
} }
// init misc ram // init misc ram
@@ -3235,6 +3121,7 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out)
*valid_out = 1; *valid_out = 1;
} }
} }
}
return ret; return ret;
} }
@@ -3630,7 +3517,19 @@ int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw){
int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){ int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){
int size; int size;
u32 *dst=NULL; u32 *dst=NULL;
u16 pid = le16_to_cpu(rwnx_hw->usbdev->udev->descriptor.idProduct);
char *filename = FW_USERCONFIG_NAME_8800DW; char *filename = FW_USERCONFIG_NAME_8800DW;
if (pid == USB_PRODUCT_ID_TENDA
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS3
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS5
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS6) {
filename = FW_USERCONFIG_NAME_8800DW_W311;
} else if (pid == USB_PRODUCT_ID_TENDA_U2
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS1
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS2
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS4) {
filename = FW_USERCONFIG_NAME_8800DW_U2;
}
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
@@ -3684,7 +3583,7 @@ int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id
/* Copy the file on the Embedded side */ /* Copy the file on the Embedded side */
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
rwnx_plat_powerlimit_parsing((char *)dst, size); rwnx_plat_powerlimit_parsing((char *)dst, size, country_code);
rwnx_release_firmware_common(&dst); rwnx_release_firmware_common(&dst);
@@ -3739,6 +3638,7 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){
array3_tbl_t p_syscfg_msk_tbl; array3_tbl_t p_syscfg_msk_tbl;
int ret, cnt; int ret, cnt;
const u32 mem_addr = 0x40500000; const u32 mem_addr = 0x40500000;
const u32 cache_mem_addr = 0x40100020;
struct dbg_mem_read_cfm rd_mem_addr_cfm; struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm); ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
@@ -3752,6 +3652,21 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){
chip_mcu_id = 1; chip_mcu_id = 1;
} }
if (chip_mcu_id) {
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cache_mem_addr, &rd_mem_addr_cfm);
if (ret) {
AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret);
return;
}
rd_mem_addr_cfm.memdata |= 0x01;
ret = rwnx_send_dbg_mem_write_req(rwnx_hw, cache_mem_addr, rd_mem_addr_cfm.memdata);
if (ret) {
AICWFDBG(LOGERROR, "%x write fail: %d\n", cache_mem_addr, ret);
return;
}
}
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm); ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm);
if (ret) { if (ret) {
AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret); AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret);
@@ -3759,7 +3674,10 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){
} }
chip_sub_id = (u8)(rd_mem_addr_cfm.memdata); chip_sub_id = (u8)(rd_mem_addr_cfm.memdata);
//printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata); //printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
AICWFDBG(LOGINFO, "chip_id=%x, chip_sub_id=%x\n", chip_id, chip_sub_id); AICWFDBG(LOGINFO, "chip_id=%x, chip_mcu_id=%x, chip_sub_id=%x\n",
chip_id, chip_mcu_id, chip_sub_id);
AICWFDBG(LOGINFO,
"issue71: using complete pre-SDK-V5/V3 DC/DW firmware and loader profile\n");
//Crystal provided by CPU (start) //Crystal provided by CPU (start)
+30 -6
View File
@@ -297,6 +297,18 @@ static void aicwf_usb_rx_complete(struct urb *urb)
aicwf_usb_rx_buf_put(usb_dev, usb_buf); aicwf_usb_rx_buf_put(usb_dev, usb_buf);
if(urb->status < 0){ if(urb->status < 0){
AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status); AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status);
if(g_rwnx_plat->wait_disconnect_cb == false){
g_rwnx_plat->wait_disconnect_cb = true;
if(atomic_read(&aicwf_deinit_atomic) > 0){
atomic_set(&aicwf_deinit_atomic, 0);
down(&aicwf_deinit_sem);
AICWFDBG(LOGINFO, "%s need to wait for disconnect callback \r\n", __func__);
}else{
g_rwnx_plat->wait_disconnect_cb = false;
}
}
return; return;
}else{ }else{
//schedule_work(&usb_dev->rx_urb_work); //schedule_work(&usb_dev->rx_urb_work);
@@ -373,6 +385,18 @@ static void aicwf_usb_rx_complete(struct urb *urb)
aicwf_usb_rx_buf_put(usb_dev, usb_buf); aicwf_usb_rx_buf_put(usb_dev, usb_buf);
if(urb->status < 0){ if(urb->status < 0){
AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status); AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status);
if(g_rwnx_plat->wait_disconnect_cb == false){
g_rwnx_plat->wait_disconnect_cb = true;
if(atomic_read(&aicwf_deinit_atomic) > 0){
atomic_set(&aicwf_deinit_atomic, 0);
down(&aicwf_deinit_sem);
AICWFDBG(LOGINFO, "%s need to wait for disconnect callback \r\n", __func__);
}else{
g_rwnx_plat->wait_disconnect_cb = false;
}
}
return; return;
}else{ }else{
//schedule_work(&usb_dev->rx_urb_work); //schedule_work(&usb_dev->rx_urb_work);
@@ -1955,6 +1979,10 @@ static void aicwf_usb_bus_stop(struct device *dev)
if (usb_dev->state == USB_DOWN_ST) if (usb_dev->state == USB_DOWN_ST)
return; return;
if(g_rwnx_plat && g_rwnx_plat->wait_disconnect_cb == true){
atomic_set(&aicwf_deinit_atomic, 1);
up(&aicwf_deinit_sem);
}
aicwf_usb_state_change(usb_dev, USB_DOWN_ST); aicwf_usb_state_change(usb_dev, USB_DOWN_ST);
//aicwf_usb_cancel_all_urbs(usb_dev);//AIDEN //aicwf_usb_cancel_all_urbs(usb_dev);//AIDEN
} }
@@ -2313,8 +2341,7 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid
usb_dev->chipid = PRODUCT_ID_AIC8801; usb_dev->chipid = PRODUCT_ID_AIC8801;
AICWFDBG(LOGINFO, "%s USE AIC8801\r\n", __func__); AICWFDBG(LOGINFO, "%s USE AIC8801\r\n", __func__);
return 0; return 0;
}else if(pid == USB_PRODUCT_ID_AIC8800DC || pid == USB_PRODUCT_ID_AIC8800DE }else if(pid == USB_PRODUCT_ID_AIC8800DC || pid == USB_PRODUCT_ID_TENDA
|| pid == USB_PRODUCT_ID_TENDA
|| pid == USB_PRODUCT_ID_TENDA_U2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS1 || pid == USB_PRODUCT_ID_TENDA_U2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS1
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS3 || pid == USB_PRODUCT_ID_AIC8800FC_CUS2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS3
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS4 || pid == USB_PRODUCT_ID_AIC8800FC_CUS5 || pid == USB_PRODUCT_ID_AIC8800FC_CUS4 || pid == USB_PRODUCT_ID_AIC8800FC_CUS5
@@ -2333,8 +2360,7 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS3 || pid == USB_PRODUCT_ID_AIC8800M80_CUS4 || pid == USB_PRODUCT_ID_AIC8800M80_CUS3 || pid == USB_PRODUCT_ID_AIC8800M80_CUS4
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS5 || pid == USB_PRODUCT_ID_AIC8800M80_CUS6 || pid == USB_PRODUCT_ID_AIC8800M80_CUS5 || pid == USB_PRODUCT_ID_AIC8800M80_CUS6
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS7 || pid == USB_PRODUCT_ID_AIC8800M80_CUS8 || pid == USB_PRODUCT_ID_AIC8800M80_CUS7 || pid == USB_PRODUCT_ID_AIC8800M80_CUS8
|| pid == USB_PRODUCT_ID_AIC8800D80_UGREEN || pid == USB_PRODUCT_ID_MERCURY || pid == USB_PRODUCT_ID_AIC8800D80_UGREEN || pid == USB_PRODUCT_ID_MERCURY){
|| pid == USB_PRODUCT_ID_TP){
usb_dev->chipid = PRODUCT_ID_AIC8800D81; usb_dev->chipid = PRODUCT_ID_AIC8800D81;
aicwf_usb_rx_aggr = true; aicwf_usb_rx_aggr = true;
AICWFDBG(LOGINFO, "%s USE AIC8800D81\r\n", __func__); AICWFDBG(LOGINFO, "%s USE AIC8800D81\r\n", __func__);
@@ -2644,7 +2670,6 @@ static struct usb_device_id aicwf_usb_id_table[] = {
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D81, 0xff, 0xff, 0xff)}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D81, 0xff, 0xff, 0xff)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D41, 0xff, 0xff, 0xff)}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D41, 0xff, 0xff, 0xff)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DC, 0xff, 0xff, 0xff)}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DC, 0xff, 0xff, 0xff)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DE, 0xff, 0xff, 0xff)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_TENDA_V2, USB_PRODUCT_ID_TENDA_TX1U_NANO, 0xff, 0xff, 0xff)}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_TENDA_V2, USB_PRODUCT_ID_TENDA_TX1U_NANO, 0xff, 0xff, 0xff)},
{USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DW)}, {USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DW)},
{USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800M80_CUS1)}, {USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800M80_CUS1)},
@@ -2680,7 +2705,6 @@ static struct usb_device_id aicwf_usb_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS8)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS8)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80_UGREEN)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80_UGREEN)},
{USB_DEVICE(USB_VENDOR_ID_TP, USB_PRODUCT_ID_MERCURY)}, {USB_DEVICE(USB_VENDOR_ID_TP, USB_PRODUCT_ID_MERCURY)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_TP, USB_PRODUCT_ID_TP, 0xff, 0xff, 0xff)},
#endif #endif
{} {}
}; };
-1
View File
@@ -38,7 +38,6 @@
#else #else
#define USB_PRODUCT_ID_AIC8801 0x8801 #define USB_PRODUCT_ID_AIC8801 0x8801
#define USB_PRODUCT_ID_AIC8800DC 0x88dc #define USB_PRODUCT_ID_AIC8800DC 0x88dc
#define USB_PRODUCT_ID_AIC8800DE 0x88de
#define USB_PRODUCT_ID_AIC8800DW 0x88dd #define USB_PRODUCT_ID_AIC8800DW 0x88dd
#define USB_PRODUCT_ID_AIC8800D81 0x8d81 #define USB_PRODUCT_ID_AIC8800D81 0x8d81
#define USB_PRODUCT_ID_AIC8800D41 0x8d41 #define USB_PRODUCT_ID_AIC8800D41 0x8d41
@@ -23,33 +23,6 @@
#define _RWNX_COMPAT_H_ #define _RWNX_COMPAT_H_
#include <linux/version.h> #include <linux/version.h>
/* Keep wireless API checks separate from timer, USB and other kernel APIs. */
#ifndef AICWF_CFG80211_VERSION_CODE
#define AICWF_CFG80211_VERSION_CODE LINUX_VERSION_CODE
#endif
/*
* cfg80211_ops.set_monitor_channel() gained a "struct net_device *dev"
* parameter. The change went into mainline 6.13, but it was also
* backported to the 6.12 stable series starting with 6.12.101, so a
* plain ">= 6.13.0" test misses 6.12.101 and later. Those kernels then
* compile against the old prototype, which is fatal with
* -Wincompatible-pointer-types:
*
* rwnx_main.c: error: initialization of
* 'int (*)(struct wiphy *, struct net_device *, struct cfg80211_chan_def *)'
* from incompatible pointer type
* 'int (*)(struct wiphy *, struct cfg80211_chan_def *)'
*
* Debian 13 (6.12.107) is one such kernel. The 6.12.101 threshold
* covers both the backport and mainline, and leaves 6.11 and earlier
* 6.12.x on the old prototype. Keep the check in one place so every
* consumer stays in sync.
*/
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 101)
#define AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
#error "Minimum kernel version supported is 3.10" #error "Minimum kernel version supported is 3.10"
#endif #endif
-16
View File
@@ -335,12 +335,6 @@ struct apm_probe_sta {
u8 sta_mac_addr[6]; u8 sta_mac_addr[6];
u8 vif_idx; u8 vif_idx;
u64 probe_id; u64 probe_id;
/*
* 7.3+ only: the cookie cfg80211_ops::probe_peer() was called with,
* echoed back via cfg80211_probe_status() once the probe completes.
* See rwnx_cfg80211_probe_client().
*/
u64 cookie;
struct work_struct apmprobestaWork; struct work_struct apmprobestaWork;
struct workqueue_struct *apmprobesta_wq; struct workqueue_struct *apmprobesta_wq;
}; };
@@ -681,16 +675,6 @@ struct rwnx_roc_elem {
bool mgmt_roc; bool mgmt_roc;
/* Indicate if we have switch on the RoC channel */ /* Indicate if we have switch on the RoC channel */
bool on_chan; bool on_chan;
/*
* The cookie reported to cfg80211 for this RoC, via
* cfg80211_ready_on_channel() / cfg80211_remain_on_channel_expired().
* On 7.3+, for a RoC started directly by cfg80211_ops::remain_on_channel(),
* this is the cookie cfg80211 pre-assigned; on every older kernel, and
* always for the purely-internal RoC started from inside mgmt_tx, it is
* rwnx_hw->roc_cookie_cnt at RoC-start time. See
* rwnx_cfg80211_remain_on_channel_().
*/
u64 cookie;
}; };
/* Structure containing channel survey information received from MAC */ /* Structure containing channel survey information received from MAC */
+362 -252
View File
@@ -1518,17 +1518,6 @@ static int rwnx_close(struct net_device *dev)
RWNX_DBG(RWNX_FN_ENTRY_STR); RWNX_DBG(RWNX_FN_ENTRY_STR);
/*
* A CONNECTING/DISCONNECTING state is only left when the firmware answers
* the pending request. If the bus is already down the answer can never
* arrive: rwnx_send_msg() silently drops the message and returns 0
* (rwnx_msg_tx.c), so the wait below would always run its full timeout and
* fire the spurious WARN_ON() during USB teardown. Skip the wait when the
* bus is down, using the same condition the vif_started path uses below.
*/
if (bus_if &&
(usbdev == NULL || (usbdev->bus_if->state != BUS_DOWN_ST &&
usbdev->state != USB_DOWN_ST))) {
test_counter = waiting_counter; test_counter = waiting_counter;
while(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING|| while(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING||
atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING){ atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING){
@@ -1541,7 +1530,6 @@ static int rwnx_close(struct net_device *dev)
break; break;
} }
} }
}
#if defined(AICWF_USB_SUPPORT) || defined(AICWF_SDIO_SUPPORT) #if defined(AICWF_USB_SUPPORT) || defined(AICWF_SDIO_SUPPORT)
if (rwnx_hw->scanning){ if (rwnx_hw->scanning){
@@ -1599,10 +1587,6 @@ static int rwnx_close(struct net_device *dev)
test_counter = waiting_counter; test_counter = waiting_counter;
if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED){ if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED){
rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING);
/* Same reasoning as above: with the bus down the disconnect
* confirmation cannot arrive, so do not wait for it. */
if (usbdev->bus_if->state != BUS_DOWN_ST &&
usbdev->state != USB_DOWN_ST) {
rwnx_send_sm_disconnect_req(rwnx_hw, rwnx_vif, 3); rwnx_send_sm_disconnect_req(rwnx_hw, rwnx_vif, 3);
while (atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING) { while (atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING) {
AICWFDBG(LOGDEBUG, "%s wifi is disconnecting, waiting 100ms for state to stable\r\n", __func__); AICWFDBG(LOGDEBUG, "%s wifi is disconnecting, waiting 100ms for state to stable\r\n", __func__);
@@ -1613,7 +1597,6 @@ static int rwnx_close(struct net_device *dev)
} }
} }
} }
}
#ifdef CONFIG_USE_P2P0 #ifdef CONFIG_USE_P2P0
if(!rwnx_vif->is_p2p_vif || ( rwnx_vif->is_p2p_vif && rwnx_hw->is_p2p_alive)){ if(!rwnx_vif->is_p2p_vif || ( rwnx_vif->is_p2p_vif && rwnx_hw->is_p2p_alive)){
if (rwnx_vif->is_p2p_vif) if (rwnx_vif->is_p2p_vif)
@@ -2959,7 +2942,7 @@ bool key_flag = false;
* when adding a group key. * when adding a group key.
*/ */
static int rwnx_cfg80211_add_key(struct wiphy *wiphy, static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct wireless_dev *wdev, struct wireless_dev *wdev,
#else #else
struct net_device *netdev, struct net_device *netdev,
@@ -2971,7 +2954,7 @@ static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
struct key_params *params) struct key_params *params)
{ {
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct rwnx_vif *vif = netdev_priv(wdev->netdev); struct rwnx_vif *vif = netdev_priv(wdev->netdev);
#else #else
struct rwnx_vif *vif = netdev_priv(netdev); struct rwnx_vif *vif = netdev_priv(netdev);
@@ -3083,7 +3066,7 @@ static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
* *
*/ */
static int rwnx_cfg80211_get_key(struct wiphy *wiphy, static int rwnx_cfg80211_get_key(struct wiphy *wiphy,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct wireless_dev *wdev, struct wireless_dev *wdev,
#else #else
struct net_device *netdev, struct net_device *netdev,
@@ -3107,7 +3090,7 @@ static int rwnx_cfg80211_get_key(struct wiphy *wiphy,
* and @key_index, return -ENOENT if the key doesn't exist. * and @key_index, return -ENOENT if the key doesn't exist.
*/ */
static int rwnx_cfg80211_del_key(struct wiphy *wiphy, static int rwnx_cfg80211_del_key(struct wiphy *wiphy,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct wireless_dev *wdev, struct wireless_dev *wdev,
#else #else
struct net_device *netdev, struct net_device *netdev,
@@ -3119,7 +3102,7 @@ static int rwnx_cfg80211_del_key(struct wiphy *wiphy,
u8 key_index, bool pairwise, const u8 *mac_addr) u8 key_index, bool pairwise, const u8 *mac_addr)
{ {
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct rwnx_vif *vif = netdev_priv(wdev->netdev); struct rwnx_vif *vif = netdev_priv(wdev->netdev);
#else #else
struct rwnx_vif *vif = netdev_priv(netdev); struct rwnx_vif *vif = netdev_priv(netdev);
@@ -3171,7 +3154,7 @@ static int rwnx_cfg80211_set_default_key(struct wiphy *wiphy,
* @set_default_mgmt_key: set the default management frame key on an interface * @set_default_mgmt_key: set the default management frame key on an interface
*/ */
static int rwnx_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, static int rwnx_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct wireless_dev *wdev, struct wireless_dev *wdev,
#else #else
struct net_device *netdev, struct net_device *netdev,
@@ -3266,7 +3249,7 @@ static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
key_params.seq_len = 0; key_params.seq_len = 0;
key_params.cipher = sme->crypto.cipher_group; key_params.cipher = sme->crypto.cipher_group;
rwnx_cfg80211_add_key(wiphy, rwnx_cfg80211_add_key(wiphy,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
&rwnx_vif->wdev, &rwnx_vif->wdev,
#else #else
dev, dev,
@@ -3497,7 +3480,7 @@ static int rwnx_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *d
* @add_station: Add a new station. * @add_station: Add a new station.
*/ */
static int rwnx_cfg80211_add_station(struct wiphy *wiphy, static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct wireless_dev *wdev, struct wireless_dev *wdev,
#else #else
struct net_device *dev, struct net_device *dev,
@@ -3510,7 +3493,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
struct station_parameters *params) struct station_parameters *params)
{ {
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev); struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
#else #else
struct rwnx_vif *rwnx_vif = netdev_priv(dev); struct rwnx_vif *rwnx_vif = netdev_priv(dev);
@@ -3606,7 +3589,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
sinfo.filled |= STATION_INFO_ASSOC_REQ_IES; sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
#endif #endif
cfg80211_new_sta( cfg80211_new_sta(
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
&rwnx_vif->wdev, &rwnx_vif->wdev,
#else #else
rwnx_vif->ndev, rwnx_vif->ndev,
@@ -3637,7 +3620,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
(params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "") (params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "")
netdev_info( netdev_info(
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
wdev->netdev, wdev->netdev,
#else #else
dev, dev,
@@ -3668,7 +3651,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
* @del_station: Remove a station * @del_station: Remove a station
*/ */
static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy, static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct wireless_dev *wdev, struct wireless_dev *wdev,
#else #else
struct net_device *dev, struct net_device *dev,
@@ -3683,7 +3666,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
) )
{ {
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev); struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
#else #else
struct rwnx_vif *rwnx_vif = netdev_priv(dev); struct rwnx_vif *rwnx_vif = netdev_priv(dev);
@@ -3728,7 +3711,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
if(found) { if(found) {
netdev_info( netdev_info(
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
wdev->netdev, wdev->netdev,
#else #else
dev, dev,
@@ -3748,7 +3731,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
} }
if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP || rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) { if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP || rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
cfg80211_del_sta( cfg80211_del_sta(
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
&rwnx_vif->wdev, &rwnx_vif->wdev,
#else #else
rwnx_vif->ndev, rwnx_vif->ndev,
@@ -3957,21 +3940,7 @@ void apm_probe_sta_work_process(struct work_struct *work)
spin_unlock_bh(&rwnx_vif->rwnx_hw->cb_lock); spin_unlock_bh(&rwnx_vif->rwnx_hw->cb_lock);
printk("sta %pM found = %d\n", mac, found); printk("sta %pM found = %d\n", mac, found);
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
/*
* 7.3 added an MLO link_id parameter between cookie and acked. This
* driver has no MLO support, and -1 is the documented value for
* "non-MLO" (see the cfg80211_probe_status() kerneldoc). The cookie
* source also changes here: sta_probe.cookie is the value cfg80211
* pre-assigned via probe_peer(), which now must be echoed back
* instead of the driver's own probe_id counter -- see
* rwnx_cfg80211_probe_client().
*/
if(found)
cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.cookie, -1, 1, 0, false, GFP_ATOMIC);
else
cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.cookie, -1, 0, 0, false, GFP_ATOMIC);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
if(found) if(found)
cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.probe_id, 1, 0, false, GFP_ATOMIC); cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.probe_id, 1, 0, false, GFP_ATOMIC);
else else
@@ -3993,7 +3962,7 @@ void apm_probe_sta_work_process(struct work_struct *work)
* cfg80211_check_station_change() to validate the information. * cfg80211_check_station_change() to validate the information.
*/ */
static int rwnx_cfg80211_change_station(struct wiphy *wiphy, static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct wireless_dev *wdev, struct wireless_dev *wdev,
#else #else
struct net_device *dev, struct net_device *dev,
@@ -4006,7 +3975,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
struct station_parameters *params) struct station_parameters *params)
{ {
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct rwnx_vif *vif = netdev_priv(wdev->netdev); struct rwnx_vif *vif = netdev_priv(wdev->netdev);
#else #else
struct rwnx_vif *vif = netdev_priv(dev); struct rwnx_vif *vif = netdev_priv(dev);
@@ -4019,7 +3988,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
/* Add the TDLS station */ /* Add the TDLS station */
if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
{ {
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev); struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
#else #else
struct rwnx_vif *rwnx_vif = netdev_priv(dev); struct rwnx_vif *rwnx_vif = netdev_priv(dev);
@@ -4095,7 +4064,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
(params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "") (params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "")
netdev_info( netdev_info(
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
wdev->netdev, wdev->netdev,
#else #else
dev, dev,
@@ -4384,7 +4353,7 @@ static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
/* delete any remaining STA*/ /* delete any remaining STA*/
while (!list_empty(&rwnx_vif->ap.sta_list)) { while (!list_empty(&rwnx_vif->ap.sta_list)) {
rwnx_cfg80211_del_station_compat(wiphy, rwnx_cfg80211_del_station_compat(wiphy,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
&rwnx_vif->wdev, &rwnx_vif->wdev,
#else #else
dev, dev,
@@ -4451,13 +4420,29 @@ cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1,
} }
#endif #endif
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV #define RWNX_CFG80211_OP_TYPE(_member) \
static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy, struct net_device *dev, typeof(((struct cfg80211_ops *)0)->_member)
struct cfg80211_chan_def *chandef) #define RWNX_CFG80211_OP_MATCH(_member, _type) \
#else __builtin_types_compatible_p(RWNX_CFG80211_OP_TYPE(_member), _type)
static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy, #define RWNX_CFG80211_OP_ASSERT(_member, _callback) \
struct cfg80211_chan_def *chandef) typedef char rwnx_cfg80211_##_member##_signature_must_match[ \
#endif __builtin_types_compatible_p(RWNX_CFG80211_OP_TYPE(_member), \
typeof(&(_callback))) ? 1 : -1]
typedef int (*rwnx_set_monitor_channel_legacy_t)(
struct wiphy *wiphy, struct cfg80211_chan_def *chandef);
typedef int (*rwnx_set_monitor_channel_dev_t)(
struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_chan_def *chandef);
typedef char rwnx_set_monitor_channel_signature_must_be_supported[
(RWNX_CFG80211_OP_MATCH(set_monitor_channel,
rwnx_set_monitor_channel_legacy_t) ||
RWNX_CFG80211_OP_MATCH(set_monitor_channel,
rwnx_set_monitor_channel_dev_t)) ? 1 : -1];
static int rwnx_cfg80211_set_monitor_channel_common(
struct wiphy *wiphy, struct cfg80211_chan_def *chandef)
{ {
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
struct rwnx_vif *rwnx_vif; struct rwnx_vif *rwnx_vif;
@@ -4510,38 +4495,50 @@ static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy,
return 0; return 0;
} }
static int rwnx_cfg80211_set_monitor_channel_legacy(
struct wiphy *wiphy, struct cfg80211_chan_def *chandef)
{
return rwnx_cfg80211_set_monitor_channel_common(wiphy, chandef);
}
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV static int rwnx_cfg80211_set_monitor_channel_dev(
struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_chan_def *chandef)
{
(void)dev;
return rwnx_cfg80211_set_monitor_channel_common(wiphy, chandef);
}
#define RWNX_CFG80211_SET_MONITOR_CHANNEL_CB \
__builtin_choose_expr( \
RWNX_CFG80211_OP_MATCH(set_monitor_channel, \
rwnx_set_monitor_channel_dev_t), \
rwnx_cfg80211_set_monitor_channel_dev, \
rwnx_cfg80211_set_monitor_channel_legacy)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
struct net_device *dev, struct net_device *dev,
struct cfg80211_chan_def *chandef) struct cfg80211_chan_def *chandef)
{ {
return rwnx_cfg80211_set_monitor_channel(wiphy, dev, chandef); (void)dev;
return rwnx_cfg80211_set_monitor_channel_common(wiphy, chandef);
} }
#else #else
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef) struct cfg80211_chan_def *chandef)
{ {
return rwnx_cfg80211_set_monitor_channel(wiphy, chandef); return rwnx_cfg80211_set_monitor_channel_common(wiphy, chandef);
} }
#endif #endif
/** /**
* @probe_peer: probe an associated client. Before 7.3 the driver returns a * @probe_client: probe an associated client, must return a cookie that it
* cookie of its own and passes the same value to cfg80211_probe_status() * later passes to cfg80211_probe_status().
* later; from 7.3 the cookie is assigned by cfg80211, passed in, and must
* be echoed back unchanged. Renamed from @probe_client upstream; kept as
* rwnx_cfg80211_probe_client() here since only the cfg80211_ops field
* name changed, not this driver's own naming.
*/ */
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
const u8 *peer, u64 cookie)
#else
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev, int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
const u8 *peer, u64 *cookie) const u8 *peer, u64 *cookie)
#endif
{ {
//struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); //struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
struct rwnx_vif *vif = netdev_priv(dev); struct rwnx_vif *vif = netdev_priv(dev);
@@ -4565,22 +4562,10 @@ int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
memcpy(vif->sta_probe.sta_mac_addr, peer, 6); memcpy(vif->sta_probe.sta_mac_addr, peer, 6);
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
/*
* 7.3 made this an input parameter: cfg80211 pre-assigns the cookie
* before calling us instead of us inventing one and returning it. Save
* it before queueing the work: the worker may run on another CPU as
* soon as it is queued, and it echoes this value back via
* cfg80211_probe_status() once the probe completes.
*/
vif->sta_probe.cookie = cookie;
#else
*cookie = vif->sta_probe.probe_id;
#endif
queue_work(vif->sta_probe.apmprobesta_wq, &vif->sta_probe.apmprobestaWork); queue_work(vif->sta_probe.apmprobesta_wq, &vif->sta_probe.apmprobestaWork);
*cookie = vif->sta_probe.probe_id;
return 0; return 0;
} }
@@ -4605,15 +4590,45 @@ void rwnx_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
* have changed. The actual parameter values are available in * have changed. The actual parameter values are available in
* struct wiphy. If returning an error, no value should be changed. * struct wiphy. If returning an error, no value should be changed.
*/ */
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) typedef int (*rwnx_set_wiphy_params_legacy_t)(struct wiphy *wiphy,
static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, u32 changed) u32 changed);
#else typedef int (*rwnx_set_wiphy_params_radio_t)(struct wiphy *wiphy,
static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) int radio_idx, u32 changed);
#endif
typedef char rwnx_set_wiphy_params_signature_must_be_supported[
(RWNX_CFG80211_OP_MATCH(set_wiphy_params,
rwnx_set_wiphy_params_legacy_t) ||
RWNX_CFG80211_OP_MATCH(set_wiphy_params,
rwnx_set_wiphy_params_radio_t)) ? 1 : -1];
static int rwnx_cfg80211_set_wiphy_params_common(struct wiphy *wiphy,
u32 changed)
{ {
(void)wiphy;
(void)changed;
return 0; return 0;
} }
static int rwnx_cfg80211_set_wiphy_params_legacy(struct wiphy *wiphy,
u32 changed)
{
return rwnx_cfg80211_set_wiphy_params_common(wiphy, changed);
}
static int rwnx_cfg80211_set_wiphy_params_radio(struct wiphy *wiphy,
int radio_idx, u32 changed)
{
(void)radio_idx;
return rwnx_cfg80211_set_wiphy_params_common(wiphy, changed);
}
#define RWNX_CFG80211_SET_WIPHY_PARAMS_CB \
__builtin_choose_expr( \
RWNX_CFG80211_OP_MATCH(set_wiphy_params, \
rwnx_set_wiphy_params_radio_t), \
rwnx_cfg80211_set_wiphy_params_radio, \
rwnx_cfg80211_set_wiphy_params_legacy)
/** /**
* @set_tx_power: set the transmit power according to the parameters, * @set_tx_power: set the transmit power according to the parameters,
@@ -4622,18 +4637,25 @@ static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
* always be %NULL unless the driver supports per-vif TX power * always be %NULL unless the driver supports per-vif TX power
* (as advertised by the nl80211 feature flag.) * (as advertised by the nl80211 feature flag.)
*/ */
static int rwnx_cfg80211_set_tx_power(struct wiphy *wiphy, typedef int (*rwnx_set_tx_power_no_wdev_t)(
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) struct wiphy *wiphy, enum nl80211_tx_power_setting type, int mbm);
struct wireless_dev *wdev, typedef int (*rwnx_set_tx_power_wdev_t)(
#endif struct wiphy *wiphy, struct wireless_dev *wdev,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) enum nl80211_tx_power_setting type, int mbm);
int radio_idx, typedef int (*rwnx_set_tx_power_radio_t)(
#endif struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
enum nl80211_tx_power_setting type, int mbm);
typedef char rwnx_set_tx_power_signature_must_be_supported[
(RWNX_CFG80211_OP_MATCH(set_tx_power, rwnx_set_tx_power_no_wdev_t) ||
RWNX_CFG80211_OP_MATCH(set_tx_power, rwnx_set_tx_power_wdev_t) ||
RWNX_CFG80211_OP_MATCH(set_tx_power,
rwnx_set_tx_power_radio_t)) ? 1 : -1];
static int rwnx_cfg80211_set_tx_power_common(
struct wiphy *wiphy, struct wireless_dev *wdev,
enum nl80211_tx_power_setting type, int mbm) enum nl80211_tx_power_setting type, int mbm)
{ {
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
struct wireless_dev *wdev = NULL;
#endif
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
struct rwnx_vif *vif; struct rwnx_vif *vif;
s8 pwr; s8 pwr;
@@ -4659,31 +4681,112 @@ int radio_idx,
return res; return res;
} }
static int rwnx_cfg80211_get_tx_power(struct wiphy *wiphy, static int rwnx_cfg80211_set_tx_power_no_wdev(
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) struct wiphy *wiphy, enum nl80211_tx_power_setting type, int mbm)
struct wireless_dev *wdev,
#endif
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
int radio_idx,
#endif
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 14, 0)
unsigned int link_id,
#endif
int *mbm)
{ {
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) return rwnx_cfg80211_set_tx_power_common(wiphy, NULL, type, mbm);
struct wireless_dev *wdev = NULL;
#endif
//struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
//struct rwnx_vif *vif;
s8 pwr = 0;
int res = 0;
*mbm = get_txpwr_max(pwr);
return res;
} }
static int rwnx_cfg80211_set_tx_power_wdev(
struct wiphy *wiphy, struct wireless_dev *wdev,
enum nl80211_tx_power_setting type, int mbm)
{
return rwnx_cfg80211_set_tx_power_common(wiphy, wdev, type, mbm);
}
static int rwnx_cfg80211_set_tx_power_radio(
struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
enum nl80211_tx_power_setting type, int mbm)
{
(void)radio_idx;
return rwnx_cfg80211_set_tx_power_common(wiphy, wdev, type, mbm);
}
#define RWNX_CFG80211_SET_TX_POWER_CB \
__builtin_choose_expr( \
RWNX_CFG80211_OP_MATCH(set_tx_power, rwnx_set_tx_power_radio_t), \
rwnx_cfg80211_set_tx_power_radio, \
__builtin_choose_expr( \
RWNX_CFG80211_OP_MATCH(set_tx_power, rwnx_set_tx_power_wdev_t), \
rwnx_cfg80211_set_tx_power_wdev, \
rwnx_cfg80211_set_tx_power_no_wdev))
typedef int (*rwnx_get_tx_power_no_wdev_t)(struct wiphy *wiphy, int *dbm);
typedef int (*rwnx_get_tx_power_wdev_t)(struct wiphy *wiphy,
struct wireless_dev *wdev, int *dbm);
typedef int (*rwnx_get_tx_power_link_t)(struct wiphy *wiphy,
struct wireless_dev *wdev,
unsigned int link_id, int *dbm);
typedef int (*rwnx_get_tx_power_radio_link_t)(
struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
unsigned int link_id, int *dbm);
typedef char rwnx_get_tx_power_signature_must_be_supported[
(RWNX_CFG80211_OP_MATCH(get_tx_power, rwnx_get_tx_power_no_wdev_t) ||
RWNX_CFG80211_OP_MATCH(get_tx_power, rwnx_get_tx_power_wdev_t) ||
RWNX_CFG80211_OP_MATCH(get_tx_power, rwnx_get_tx_power_link_t) ||
RWNX_CFG80211_OP_MATCH(get_tx_power,
rwnx_get_tx_power_radio_link_t)) ? 1 : -1];
static int rwnx_cfg80211_get_tx_power_common(struct wiphy *wiphy,
struct wireless_dev *wdev,
int *dbm)
{
s8 pwr = 0;
(void)wiphy;
(void)wdev;
if (!dbm)
return -EINVAL;
*dbm = get_txpwr_max(pwr);
return 0;
}
static int rwnx_cfg80211_get_tx_power_no_wdev(struct wiphy *wiphy, int *dbm)
{
return rwnx_cfg80211_get_tx_power_common(wiphy, NULL, dbm);
}
static int rwnx_cfg80211_get_tx_power_wdev(struct wiphy *wiphy,
struct wireless_dev *wdev,
int *dbm)
{
return rwnx_cfg80211_get_tx_power_common(wiphy, wdev, dbm);
}
static int rwnx_cfg80211_get_tx_power_link(struct wiphy *wiphy,
struct wireless_dev *wdev,
unsigned int link_id, int *dbm)
{
(void)link_id;
return rwnx_cfg80211_get_tx_power_common(wiphy, wdev, dbm);
}
static int rwnx_cfg80211_get_tx_power_radio_link(
struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
unsigned int link_id, int *dbm)
{
(void)radio_idx;
(void)link_id;
return rwnx_cfg80211_get_tx_power_common(wiphy, wdev, dbm);
}
#define RWNX_CFG80211_GET_TX_POWER_CB \
__builtin_choose_expr( \
RWNX_CFG80211_OP_MATCH(get_tx_power, \
rwnx_get_tx_power_radio_link_t), \
rwnx_cfg80211_get_tx_power_radio_link, \
__builtin_choose_expr( \
RWNX_CFG80211_OP_MATCH(get_tx_power, \
rwnx_get_tx_power_link_t), \
rwnx_cfg80211_get_tx_power_link, \
__builtin_choose_expr( \
RWNX_CFG80211_OP_MATCH(get_tx_power, \
rwnx_get_tx_power_wdev_t), \
rwnx_cfg80211_get_tx_power_wdev, \
rwnx_cfg80211_get_tx_power_no_wdev)))
/** /**
* @set_power_mgmt: set the power save to one of those two modes: * @set_power_mgmt: set the power save to one of those two modes:
* Power-save off * Power-save off
@@ -4780,7 +4883,6 @@ rwnx_cfg80211_remain_on_channel_(struct wiphy *wiphy,
struct wireless_dev *wdev = &rwnx_vif->wdev; struct wireless_dev *wdev = &rwnx_vif->wdev;
#endif #endif
struct rwnx_roc_elem *roc_elem; struct rwnx_roc_elem *roc_elem;
u64 roc_cookie;
struct mm_add_if_cfm add_if_cfm; struct mm_add_if_cfm add_if_cfm;
struct mm_remain_on_channel_cfm roc_cfm; struct mm_remain_on_channel_cfm roc_cfm;
int error; int error;
@@ -4872,34 +4974,6 @@ rwnx_cfg80211_remain_on_channel_(struct wiphy *wiphy,
/* Initialize the OFFCHAN TX queue to allow off-channel transmissions */ /* Initialize the OFFCHAN TX queue to allow off-channel transmissions */
rwnx_txq_offchan_init(rwnx_vif); rwnx_txq_offchan_init(rwnx_vif);
/*
* Decide the cookie before the element is published and the request
* sent: the RX path can deliver the channel-switch indication and
* call cfg80211_ready_on_channel() with roc_elem->cookie before this
* thread resumes, so it must already be the final value by then.
* Taking one snapshot here also keeps that value and the one reported
* back to the caller below identical: rwnx_send_roc() sleeps, and the
* RoC expiry handler increments roc_cookie_cnt, so re-reading the
* counter afterwards could return a different value than the one
* already reported to cfg80211.
*/
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
/*
* mgmt_roc_flag is false only for the direct cfg80211
* .remain_on_channel call path (see rwnx_cfg80211_remain_on_channel()
* below), where on 7.3+ *cookie already holds the value cfg80211
* pre-assigned and must be honored rather than overwritten. The
* purely-internal RoC this function also serves (started from
* inside mgmt_tx, mgmt_roc_flag true) never goes through that
* cfg80211 op, so there is no pre-assigned value to honor there --
* keep inventing one, exactly as on every older kernel.
*/
roc_cookie = mgmt_roc_flag ? (u64)(rwnx_hw->roc_cookie_cnt) : *cookie;
#else
roc_cookie = (u64)(rwnx_hw->roc_cookie_cnt);
#endif
roc_elem->cookie = roc_cookie;
/* Forward the information to the FMAC */ /* Forward the information to the FMAC */
rwnx_hw->roc_elem = roc_elem; rwnx_hw->roc_elem = roc_elem;
error = rwnx_send_roc(rwnx_hw, rwnx_vif, chan, duration, &roc_cfm); error = rwnx_send_roc(rwnx_hw, rwnx_vif, chan, duration, &roc_cfm);
@@ -4908,12 +4982,7 @@ rwnx_cfg80211_remain_on_channel_(struct wiphy *wiphy,
if (error == 0) { if (error == 0) {
/* Set the cookie value */ /* Set the cookie value */
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0) *cookie = (u64)(rwnx_hw->roc_cookie_cnt);
if (mgmt_roc_flag)
*cookie = roc_cookie;
#else
*cookie = roc_cookie;
#endif
if(roc_cfm.status) { if(roc_cfm.status) {
// failed to roc // failed to roc
rwnx_hw->roc_elem = NULL; rwnx_hw->roc_elem = NULL;
@@ -4943,42 +5012,8 @@ rwnx_cfg80211_remain_on_channel(struct wiphy *wiphy,
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
enum nl80211_channel_type channel_type, enum nl80211_channel_type channel_type,
#endif #endif
unsigned int duration, unsigned int duration, u64 *cookie)
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
/*
* 7.3 made this cookie an input parameter: cfg80211
* pre-assigns it before calling us instead of us
* inventing one and returning it. See
* rwnx_cfg80211_remain_on_channel_(). rx_addr is
* unused for the reason given in the 7.2 arm below:
* it is always NULL for this driver.
*/
u64 cookie, const u8 *rx_addr
#elif AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 2, 0)
/*
* 7.2 added an optional receive address filter for the off-channel
* period. cfg80211 refuses a non-NULL one unless the driver sets
* NL80211_EXT_FEATURE_ROC_ADDR_FILTER, which this one does not, so it
* is always NULL here. mac80211 ignores it in the same way.
*/
u64 *cookie, const u8 *rx_addr
#else
u64 *cookie
#endif
)
{ {
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
/*
* 7.3 passes the cookie by value, while the shared helper still takes a
* pointer because its internal caller invents one. Only the argument
* differs, so pick it here and leave the call itself alone.
*/
u64 local_cookie = cookie;
u64 *cookie_ptr = &local_cookie;
#else
u64 *cookie_ptr = cookie;
#endif
return rwnx_cfg80211_remain_on_channel_(wiphy, return rwnx_cfg80211_remain_on_channel_(wiphy,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
wdev, wdev,
@@ -4989,7 +5024,7 @@ rwnx_cfg80211_remain_on_channel(struct wiphy *wiphy,
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
channel_type, channel_type,
#endif #endif
duration, cookie_ptr, false); duration, cookie, false);
} }
/** /**
@@ -5119,11 +5154,7 @@ static int rwnx_cfg80211_get_channel(struct wiphy *wiphy,
if (rwnx_vif->vif_index == rwnx_hw->monitor_vif) if (rwnx_vif->vif_index == rwnx_hw->monitor_vif)
{ {
//retrieve channel from firmware //retrieve channel from firmware
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV rwnx_cfg80211_set_monitor_channel_common(wiphy, NULL);
rwnx_cfg80211_set_monitor_channel(wiphy, wdev->netdev, NULL);
#else
rwnx_cfg80211_set_monitor_channel(wiphy, NULL);
#endif
} }
//Check if channel context is valid //Check if channel context is valid
@@ -5167,17 +5198,7 @@ struct ieee80211_channel *rwnx_cfg80211_get_channel(struct wiphy *wiphy)
/** /**
* @mgmt_tx: Transmit a management frame. * @mgmt_tx: Transmit a management frame.
*/ */
#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
struct cfg80211_mgmt_tx_params *params,
/*
* 7.3 made this cookie an input parameter: cfg80211
* pre-assigns it before calling us instead of us
* inventing one and returning it. See
* rwnx_start_mgmt_xmit().
*/
u64 cookie)
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
struct cfg80211_mgmt_tx_params *params, struct cfg80211_mgmt_tx_params *params,
u64 *cookie) u64 *cookie)
@@ -5192,7 +5213,7 @@ static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
bool dont_wait_for_ack, bool dont_wait_for_ack,
#endif #endif
u64 *cookie) u64 *cookie)
#endif /* AICWF_CFG80211_VERSION_CODE >= 7.3 / LINUX_VERSION_CODE >= 3.14 */ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
{ {
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
@@ -5279,8 +5300,7 @@ static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
return -EINVAL; return -EINVAL;
} }
} else { } else {
/* The internal RoC's own cookie; deliberately not the mgmt_tx one. */ u64 cookie;
u64 roc_cookie;
int error; int error;
AICWFDBG(LOGINFO, "mgmt rx remain on chan\n"); AICWFDBG(LOGINFO, "mgmt rx remain on chan\n");
@@ -5288,13 +5308,13 @@ static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
/* Start a ROC procedure for 30ms */ /* Start a ROC procedure for 30ms */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
error = rwnx_cfg80211_remain_on_channel_(wiphy, wdev, channel, error = rwnx_cfg80211_remain_on_channel_(wiphy, wdev, channel,
30, &roc_cookie, true); 30, &cookie, true);
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) #elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
error = rwnx_cfg80211_remain_on_channel_(wiphy, wdev, channel, NL80211_CHAN_NO_HT, error = rwnx_cfg80211_remain_on_channel_(wiphy, wdev, channel, NL80211_CHAN_NO_HT,
30, &roc_cookie, true); 30, &cookie, true);
#else #else
error = rwnx_cfg80211_remain_on_channel_(wiphy, dev, channel, NL80211_CHAN_NO_HT, error = rwnx_cfg80211_remain_on_channel_(wiphy, dev, channel, NL80211_CHAN_NO_HT,
30, &roc_cookie, true); 30, &cookie, true);
#endif #endif
if (error) { if (error) {
@@ -5311,32 +5331,38 @@ static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
#endif #endif
send_frame: send_frame:
#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
{ return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, params, offchan, cookie);
u64 local_cookie = cookie;
return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, params, offchan, &local_cookie, true);
}
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, params, offchan, cookie, false);
#else #else
return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, channel, offchan, wait, buf, len, no_cck, dont_wait_for_ack, cookie, false); return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, channel, offchan, wait, buf, len, no_cck, dont_wait_for_ack, cookie);
#endif /* AICWF_CFG80211_VERSION_CODE >= 7.3 / LINUX_VERSION_CODE >= 3.14 */ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
} }
/** /**
* @start_radar_detection: Start radar detection in the driver. * @start_radar_detection: Start radar detection in the driver.
*/ */
static typedef int (*rwnx_start_radar_detection_legacy_t)(
int rwnx_cfg80211_start_radar_detection(struct wiphy *wiphy, struct wiphy *wiphy, struct net_device *dev,
struct net_device *dev, struct cfg80211_chan_def *chandef);
struct cfg80211_chan_def *chandef typedef int (*rwnx_start_radar_detection_cac_t)(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) struct wiphy *wiphy, struct net_device *dev,
, u32 cac_time_ms struct cfg80211_chan_def *chandef, u32 cac_time_ms);
#endif typedef int (*rwnx_start_radar_detection_link_t)(
#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)) struct wiphy *wiphy, struct net_device *dev,
, int link_id struct cfg80211_chan_def *chandef, u32 cac_time_ms, int link_id);
#endif
) typedef char rwnx_start_radar_detection_signature_must_be_supported[
(RWNX_CFG80211_OP_MATCH(start_radar_detection,
rwnx_start_radar_detection_legacy_t) ||
RWNX_CFG80211_OP_MATCH(start_radar_detection,
rwnx_start_radar_detection_cac_t) ||
RWNX_CFG80211_OP_MATCH(start_radar_detection,
rwnx_start_radar_detection_link_t)) ? 1 : -1];
static int rwnx_cfg80211_start_radar_detection_common(
struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_chan_def *chandef, u32 cac_time_ms,
bool start_cac_timer)
{ {
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
struct rwnx_vif *rwnx_vif = netdev_priv(dev); struct rwnx_vif *rwnx_vif = netdev_priv(dev);
@@ -5344,9 +5370,8 @@ int rwnx_cfg80211_start_radar_detection(struct wiphy *wiphy,
printk("%s\n", __func__); printk("%s\n", __func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) if (start_cac_timer)
rwnx_radar_start_cac(&rwnx_hw->radar, cac_time_ms, rwnx_vif); rwnx_radar_start_cac(&rwnx_hw->radar, cac_time_ms, rwnx_vif);
#endif
rwnx_send_apm_start_cac_req(rwnx_hw, rwnx_vif, chandef, &cfm); rwnx_send_apm_start_cac_req(rwnx_hw, rwnx_vif, chandef, &cfm);
if (cfm.status == CO_OK) { if (cfm.status == CO_OK) {
@@ -5364,6 +5389,42 @@ int rwnx_cfg80211_start_radar_detection(struct wiphy *wiphy,
return 0; return 0;
} }
static int rwnx_cfg80211_start_radar_detection_legacy(
struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_chan_def *chandef)
{
return rwnx_cfg80211_start_radar_detection_common(
wiphy, dev, chandef, 0, false);
}
static int rwnx_cfg80211_start_radar_detection_cac(
struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_chan_def *chandef, u32 cac_time_ms)
{
return rwnx_cfg80211_start_radar_detection_common(
wiphy, dev, chandef, cac_time_ms, true);
}
static int rwnx_cfg80211_start_radar_detection_link(
struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_chan_def *chandef, u32 cac_time_ms, int link_id)
{
(void)link_id;
return rwnx_cfg80211_start_radar_detection_common(
wiphy, dev, chandef, cac_time_ms, true);
}
#define RWNX_CFG80211_START_RADAR_DETECTION_CB \
__builtin_choose_expr( \
RWNX_CFG80211_OP_MATCH(start_radar_detection, \
rwnx_start_radar_detection_link_t), \
rwnx_cfg80211_start_radar_detection_link, \
__builtin_choose_expr( \
RWNX_CFG80211_OP_MATCH(start_radar_detection, \
rwnx_start_radar_detection_cac_t), \
rwnx_cfg80211_start_radar_detection_cac, \
rwnx_cfg80211_start_radar_detection_legacy))
/** /**
* @update_ft_ies: Provide updated Fast BSS Transition information to the * @update_ft_ies: Provide updated Fast BSS Transition information to the
* driver. If the SME is in the driver/firmware, this information can be * driver. If the SME is in the driver/firmware, this information can be
@@ -6117,7 +6178,7 @@ int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif,
* @get_station: get station information for the station identified by @mac * @get_station: get station information for the station identified by @mac
*/ */
static int rwnx_cfg80211_get_station(struct wiphy *wiphy, static int rwnx_cfg80211_get_station(struct wiphy *wiphy,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct wireless_dev *wdev, struct wireless_dev *wdev,
#else #else
struct net_device *dev, struct net_device *dev,
@@ -6129,7 +6190,7 @@ static int rwnx_cfg80211_get_station(struct wiphy *wiphy,
#endif #endif
struct station_info *sinfo) struct station_info *sinfo)
{ {
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct rwnx_vif *vif = netdev_priv(wdev->netdev); struct rwnx_vif *vif = netdev_priv(wdev->netdev);
#else #else
struct rwnx_vif *vif = netdev_priv(dev); struct rwnx_vif *vif = netdev_priv(dev);
@@ -6167,14 +6228,14 @@ static int rwnx_cfg80211_get_station(struct wiphy *wiphy,
* @dump_station: dump station callback -- resume dump at index @idx * @dump_station: dump station callback -- resume dump at index @idx
*/ */
static int rwnx_cfg80211_dump_station(struct wiphy *wiphy, static int rwnx_cfg80211_dump_station(struct wiphy *wiphy,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct wireless_dev *wdev, struct wireless_dev *wdev,
#else #else
struct net_device *dev, struct net_device *dev,
#endif #endif
int idx, u8 *mac, struct station_info *sinfo) int idx, u8 *mac, struct station_info *sinfo)
{ {
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev); struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
#else #else
struct rwnx_vif *rwnx_vif = netdev_priv(dev); struct rwnx_vif *rwnx_vif = netdev_priv(dev);
@@ -6656,6 +6717,59 @@ static int rwnx_cfg80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
return 0; return 0;
} }
/*
* Keep every direct cfg80211_ops assignment as a hard compile-time check.
* OpenWrt can backport cfg80211 APIs without changing LINUX_VERSION_CODE, and
* an incompatible callback must remain a build failure even when warnings are
* relaxed by an external package.
*/
RWNX_CFG80211_OP_ASSERT(add_virtual_intf, rwnx_cfg80211_add_iface);
RWNX_CFG80211_OP_ASSERT(del_virtual_intf, rwnx_cfg80211_del_iface);
RWNX_CFG80211_OP_ASSERT(change_virtual_intf, rwnx_cfg80211_change_iface);
RWNX_CFG80211_OP_ASSERT(start_p2p_device, rwnx_cfgp2p_start_p2p_device);
RWNX_CFG80211_OP_ASSERT(stop_p2p_device, rwnx_cfgp2p_stop_p2p_device);
RWNX_CFG80211_OP_ASSERT(scan, rwnx_cfg80211_scan);
RWNX_CFG80211_OP_ASSERT(connect, rwnx_cfg80211_connect);
RWNX_CFG80211_OP_ASSERT(disconnect, rwnx_cfg80211_disconnect);
RWNX_CFG80211_OP_ASSERT(add_key, rwnx_cfg80211_add_key);
RWNX_CFG80211_OP_ASSERT(get_key, rwnx_cfg80211_get_key);
RWNX_CFG80211_OP_ASSERT(del_key, rwnx_cfg80211_del_key);
RWNX_CFG80211_OP_ASSERT(set_default_key, rwnx_cfg80211_set_default_key);
RWNX_CFG80211_OP_ASSERT(set_default_mgmt_key,
rwnx_cfg80211_set_default_mgmt_key);
RWNX_CFG80211_OP_ASSERT(add_station, rwnx_cfg80211_add_station);
RWNX_CFG80211_OP_ASSERT(del_station, rwnx_cfg80211_del_station_compat);
RWNX_CFG80211_OP_ASSERT(change_station, rwnx_cfg80211_change_station);
RWNX_CFG80211_OP_ASSERT(mgmt_tx, rwnx_cfg80211_mgmt_tx);
RWNX_CFG80211_OP_ASSERT(start_ap, rwnx_cfg80211_start_ap);
RWNX_CFG80211_OP_ASSERT(change_beacon, rwnx_cfg80211_change_beacon);
RWNX_CFG80211_OP_ASSERT(stop_ap, rwnx_cfg80211_stop_ap);
RWNX_CFG80211_OP_ASSERT(probe_client, rwnx_cfg80211_probe_client);
RWNX_CFG80211_OP_ASSERT(set_txq_params, rwnx_cfg80211_set_txq_params);
RWNX_CFG80211_OP_ASSERT(set_power_mgmt, rwnx_cfg80211_set_power_mgmt);
RWNX_CFG80211_OP_ASSERT(get_station, rwnx_cfg80211_get_station);
RWNX_CFG80211_OP_ASSERT(remain_on_channel,
rwnx_cfg80211_remain_on_channel);
RWNX_CFG80211_OP_ASSERT(cancel_remain_on_channel,
rwnx_cfg80211_cancel_remain_on_channel);
RWNX_CFG80211_OP_ASSERT(dump_survey, rwnx_cfg80211_dump_survey);
RWNX_CFG80211_OP_ASSERT(get_channel, rwnx_cfg80211_get_channel);
RWNX_CFG80211_OP_ASSERT(update_ft_ies, rwnx_cfg80211_update_ft_ies);
RWNX_CFG80211_OP_ASSERT(set_cqm_rssi_config,
rwnx_cfg80211_set_cqm_rssi_config);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
RWNX_CFG80211_OP_ASSERT(channel_switch, rwnx_cfg80211_channel_switch);
#endif
RWNX_CFG80211_OP_ASSERT(change_bss, rwnx_cfg80211_change_bss);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || \
defined(CONFIG_WPA3_FOR_OLD_KERNEL)
RWNX_CFG80211_OP_ASSERT(external_auth, rwnx_cfg80211_external_auth);
#endif
#ifdef CONFIG_SCHED_SCAN
RWNX_CFG80211_OP_ASSERT(sched_scan_start, rwnx_cfg80211_sched_scan_start);
RWNX_CFG80211_OP_ASSERT(sched_scan_stop, rwnx_cfg80211_sched_scan_stop);
#endif
static struct cfg80211_ops rwnx_cfg80211_ops = { static struct cfg80211_ops rwnx_cfg80211_ops = {
.add_virtual_intf = rwnx_cfg80211_add_iface, .add_virtual_intf = rwnx_cfg80211_add_iface,
.del_virtual_intf = rwnx_cfg80211_del_iface, .del_virtual_intf = rwnx_cfg80211_del_iface,
@@ -6677,24 +6791,20 @@ static struct cfg80211_ops rwnx_cfg80211_ops = {
.start_ap = rwnx_cfg80211_start_ap, .start_ap = rwnx_cfg80211_start_ap,
.change_beacon = rwnx_cfg80211_change_beacon, .change_beacon = rwnx_cfg80211_change_beacon,
.stop_ap = rwnx_cfg80211_stop_ap, .stop_ap = rwnx_cfg80211_stop_ap,
.set_monitor_channel = rwnx_cfg80211_set_monitor_channel, .set_monitor_channel = RWNX_CFG80211_SET_MONITOR_CHANNEL_CB,
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
.probe_peer = rwnx_cfg80211_probe_client,
#else
.probe_client = rwnx_cfg80211_probe_client, .probe_client = rwnx_cfg80211_probe_client,
#endif
// .mgmt_frame_register = rwnx_cfg80211_mgmt_frame_register, // .mgmt_frame_register = rwnx_cfg80211_mgmt_frame_register,
.set_wiphy_params = rwnx_cfg80211_set_wiphy_params, .set_wiphy_params = RWNX_CFG80211_SET_WIPHY_PARAMS_CB,
.set_txq_params = rwnx_cfg80211_set_txq_params, .set_txq_params = rwnx_cfg80211_set_txq_params,
.set_tx_power = rwnx_cfg80211_set_tx_power, .set_tx_power = RWNX_CFG80211_SET_TX_POWER_CB,
.get_tx_power = rwnx_cfg80211_get_tx_power, .get_tx_power = RWNX_CFG80211_GET_TX_POWER_CB,
.set_power_mgmt = rwnx_cfg80211_set_power_mgmt, .set_power_mgmt = rwnx_cfg80211_set_power_mgmt,
.get_station = rwnx_cfg80211_get_station, .get_station = rwnx_cfg80211_get_station,
.remain_on_channel = rwnx_cfg80211_remain_on_channel, .remain_on_channel = rwnx_cfg80211_remain_on_channel,
.cancel_remain_on_channel = rwnx_cfg80211_cancel_remain_on_channel, .cancel_remain_on_channel = rwnx_cfg80211_cancel_remain_on_channel,
.dump_survey = rwnx_cfg80211_dump_survey, .dump_survey = rwnx_cfg80211_dump_survey,
.get_channel = rwnx_cfg80211_get_channel, .get_channel = rwnx_cfg80211_get_channel,
.start_radar_detection = rwnx_cfg80211_start_radar_detection, .start_radar_detection = RWNX_CFG80211_START_RADAR_DETECTION_CB,
.update_ft_ies = rwnx_cfg80211_update_ft_ies, .update_ft_ies = rwnx_cfg80211_update_ft_ies,
.set_cqm_rssi_config = rwnx_cfg80211_set_cqm_rssi_config, .set_cqm_rssi_config = rwnx_cfg80211_set_cqm_rssi_config,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+1 -6
View File
@@ -91,7 +91,7 @@ void aicwf_p2p_alive_timeout(struct timer_list *t);
int rwnx_send_check_p2p(struct cfg80211_scan_request *param); int rwnx_send_check_p2p(struct cfg80211_scan_request *param);
void apm_staloss_work_process(struct work_struct *work); void apm_staloss_work_process(struct work_struct *work);
void apm_probe_sta_work_process(struct work_struct *work); void apm_probe_sta_work_process(struct work_struct *work);
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
struct net_device *dev, struct net_device *dev,
struct cfg80211_chan_def *chandef); struct cfg80211_chan_def *chandef);
@@ -99,13 +99,8 @@ int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef); struct cfg80211_chan_def *chandef);
#endif #endif
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
const u8 *peer, u64 cookie);
#else
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev, int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
const u8 *peer, u64 *cookie); const u8 *peer, u64 *cookie);
#endif
void rwnx_cfg80211_mgmt_frame_register(struct wiphy *wiphy, void rwnx_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
struct net_device *dev, struct net_device *dev,
+6 -8
View File
@@ -123,13 +123,13 @@ static inline int rwnx_rx_chan_switch_ind(struct rwnx_hw *rwnx_hw,
if (!roc_elem->mgmt_roc) { if (!roc_elem->mgmt_roc) {
/* Inform the host that we have switch on the indicated off-channel */ /* Inform the host that we have switch on the indicated off-channel */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
cfg80211_ready_on_channel(roc_elem->wdev->netdev, roc_elem->cookie, cfg80211_ready_on_channel(roc_elem->wdev->netdev, (u64)(rwnx_hw->roc_cookie_cnt),
roc_elem->chan, NL80211_CHAN_HT20, roc_elem->duration, GFP_ATOMIC); roc_elem->chan, NL80211_CHAN_HT20, roc_elem->duration, GFP_ATOMIC);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) #elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
cfg80211_ready_on_channel(roc_elem->wdev, roc_elem->cookie, cfg80211_ready_on_channel(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
roc_elem->chan, NL80211_CHAN_HT20, roc_elem->duration, GFP_ATOMIC); roc_elem->chan, NL80211_CHAN_HT20, roc_elem->duration, GFP_ATOMIC);
#else #else
cfg80211_ready_on_channel(roc_elem->wdev, roc_elem->cookie, cfg80211_ready_on_channel(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
roc_elem->chan, roc_elem->duration, GFP_ATOMIC); roc_elem->chan, roc_elem->duration, GFP_ATOMIC);
#endif #endif
} }
@@ -245,13 +245,13 @@ static inline int rwnx_rx_remain_on_channel_exp_ind(struct rwnx_hw *rwnx_hw,
/* Inform the host that off-channel period has expired */ /* Inform the host that off-channel period has expired */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
cfg80211_remain_on_channel_expired(roc_elem->wdev->netdev, roc_elem->cookie, cfg80211_remain_on_channel_expired(roc_elem->wdev->netdev, (u64)(rwnx_hw->roc_cookie_cnt),
roc_elem->chan, NL80211_CHAN_HT20, GFP_ATOMIC); roc_elem->chan, NL80211_CHAN_HT20, GFP_ATOMIC);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) #elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
cfg80211_remain_on_channel_expired(roc_elem->wdev, roc_elem->cookie, cfg80211_remain_on_channel_expired(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
roc_elem->chan, NL80211_CHAN_HT20, GFP_ATOMIC); roc_elem->chan, NL80211_CHAN_HT20, GFP_ATOMIC);
#else #else
cfg80211_remain_on_channel_expired(roc_elem->wdev, roc_elem->cookie, cfg80211_remain_on_channel_expired(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
roc_elem->chan, GFP_ATOMIC); roc_elem->chan, GFP_ATOMIC);
#endif #endif
} }
@@ -825,9 +825,7 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw,
#endif #endif
} }
#ifdef CONFIG_USE_WIRELESS_EXT
putbss: putbss:
#endif
if (bss != NULL) if (bss != NULL)
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
cfg80211_put_bss(bss); cfg80211_put_bss(bss);
+1 -7
View File
@@ -4849,13 +4849,7 @@ int rwnx_send_dbg_trigger_req(struct rwnx_hw *rwnx_hw, char *msg)
return -ENOMEM; return -ENOMEM;
/* Set parameters for the MM_DBG_TRIGGER_REQ message */ /* Set parameters for the MM_DBG_TRIGGER_REQ message */
/* strncpy(req->error, msg, sizeof(req->error));
* strncpy() is gone in 7.2. req->error is a fixed 64-byte field of a
* firmware message that is not NUL-terminated, and the message came
* from kzalloc(), so copying at most the field size is all strncpy()
* did here.
*/
memcpy(req->error, msg, strnlen(msg, sizeof(req->error)));
/* Send the MM_DBG_TRIGGER_REQ message to LMAC FW */ /* Send the MM_DBG_TRIGGER_REQ message to LMAC FW */
return rwnx_send_msg(rwnx_hw, req, 0, -1, NULL); return rwnx_send_msg(rwnx_hw, req, 0, -1, NULL);
+3 -6
View File
@@ -1669,8 +1669,7 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC ||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){ rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){
#ifndef ANDROID_PLATFORM #ifndef ANDROID_PLATFORM
if (strlcat(aic_fw_path, "/aic8800DC", sizeof(aic_fw_path)) >= sizeof(aic_fw_path)) sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800DC");
return -ENAMETOOLONG;
#endif #endif
AICWFDBG(LOGINFO, "testmode=%d\n", testmode); AICWFDBG(LOGINFO, "testmode=%d\n", testmode);
if (chip_sub_id == 0) { if (chip_sub_id == 0) {
@@ -1809,8 +1808,7 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
} }
} else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) { } else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) {
#ifndef ANDROID_PLATFORM #ifndef ANDROID_PLATFORM
if (strlcat(aic_fw_path, "/aic8800D80N", sizeof(aic_fw_path)) >= sizeof(aic_fw_path)) sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80N");
return -ENAMETOOLONG;
#endif #endif
if (testmode == FW_NORMAL_MODE) { if (testmode == FW_NORMAL_MODE) {
ret = aicwf_plat_patch_load_8800d80n(rwnx_hw); ret = aicwf_plat_patch_load_8800d80n(rwnx_hw);
@@ -1840,8 +1838,7 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
} }
else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN) { else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN) {
#ifndef ANDROID_PLATFORM #ifndef ANDROID_PLATFORM
if (strlcat(aic_fw_path, "/aic8800DLN", sizeof(aic_fw_path)) >= sizeof(aic_fw_path)) sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800DLN");
return -ENAMETOOLONG;
#endif #endif
if (testmode == FW_NORMAL_MODE) { if (testmode == FW_NORMAL_MODE) {
aicwf_patch_config_8800dln(rwnx_hw); aicwf_patch_config_8800dln(rwnx_hw);
+48 -15
View File
@@ -22,6 +22,52 @@
#include "rwnx_events.h" #include "rwnx_events.h"
#include "rwnx_compat.h" #include "rwnx_compat.h"
#ifdef CONFIG_RWNX_FULLMAC
/* OpenWrt can backport cfg80211 helpers without changing LINUX_VERSION_CODE. */
typedef void (*rwnx_cfg80211_cac_event_no_chandef_t)(
struct net_device *netdev, enum nl80211_radar_event event, gfp_t gfp);
typedef void (*rwnx_cfg80211_cac_event_chandef_t)(
struct net_device *netdev, const struct cfg80211_chan_def *chandef,
enum nl80211_radar_event event, gfp_t gfp);
typedef void (*rwnx_cfg80211_cac_event_link_t)(
struct net_device *netdev, const struct cfg80211_chan_def *chandef,
enum nl80211_radar_event event, gfp_t gfp, unsigned int link_id);
#define RWNX_CFG80211_CAC_EVENT_MATCH(_type) \
__builtin_types_compatible_p(typeof(&cfg80211_cac_event), _type)
typedef char rwnx_cfg80211_cac_event_signature_must_be_supported[
(RWNX_CFG80211_CAC_EVENT_MATCH(
rwnx_cfg80211_cac_event_no_chandef_t) ||
RWNX_CFG80211_CAC_EVENT_MATCH(rwnx_cfg80211_cac_event_chandef_t) ||
RWNX_CFG80211_CAC_EVENT_MATCH(rwnx_cfg80211_cac_event_link_t)) ? 1 : -1];
static void rwnx_cfg80211_cac_event_compat(
struct net_device *netdev, const struct cfg80211_chan_def *chandef,
enum nl80211_radar_event event, gfp_t gfp)
{
union {
typeof(&cfg80211_cac_event) actual;
rwnx_cfg80211_cac_event_no_chandef_t no_chandef;
rwnx_cfg80211_cac_event_chandef_t chandef;
rwnx_cfg80211_cac_event_link_t link;
} helper = { .actual = &cfg80211_cac_event };
if (RWNX_CFG80211_CAC_EVENT_MATCH(
rwnx_cfg80211_cac_event_no_chandef_t)) {
helper.no_chandef(netdev, event, gfp);
return;
}
if (RWNX_CFG80211_CAC_EVENT_MATCH(rwnx_cfg80211_cac_event_link_t)) {
helper.link(netdev, chandef, event, gfp, 0);
return;
}
helper.chandef(netdev, chandef, event, gfp);
}
#endif
/* /*
* tolerated deviation of radar time stamp in usecs on both sides * tolerated deviation of radar time stamp in usecs on both sides
* TODO: this might need to be HW-dependent * TODO: this might need to be HW-dependent
@@ -1471,15 +1517,8 @@ static void rwnx_radar_cac_work(struct work_struct *ws)
} }
ctxt = &rwnx_hw->chanctx_table[radar->cac_vif->ch_index]; ctxt = &rwnx_hw->chanctx_table[radar->cac_vif->ch_index];
cfg80211_cac_event(radar->cac_vif->ndev, rwnx_cfg80211_cac_event_compat(radar->cac_vif->ndev, &ctxt->chan_def,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
&ctxt->chan_def,
#endif
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0);
#else
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
#endif
rwnx_send_apm_stop_cac_req(rwnx_hw, radar->cac_vif); rwnx_send_apm_stop_cac_req(rwnx_hw, radar->cac_vif);
rwnx_chanctx_unlink(radar->cac_vif); rwnx_chanctx_unlink(radar->cac_vif);
@@ -1613,15 +1652,9 @@ void rwnx_radar_cancel_cac(struct rwnx_radar *radar)
struct rwnx_chanctx *ctxt; struct rwnx_chanctx *ctxt;
ctxt = &rwnx_hw->chanctx_table[radar->cac_vif->ch_index]; ctxt = &rwnx_hw->chanctx_table[radar->cac_vif->ch_index];
rwnx_send_apm_stop_cac_req(rwnx_hw, radar->cac_vif); rwnx_send_apm_stop_cac_req(rwnx_hw, radar->cac_vif);
cfg80211_cac_event(radar->cac_vif->ndev, rwnx_cfg80211_cac_event_compat(radar->cac_vif->ndev,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
&ctxt->chan_def, &ctxt->chan_def,
#endif
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0);
#else
NL80211_RADAR_CAC_ABORTED, GFP_KERNEL); NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
#endif
rwnx_chanctx_unlink(radar->cac_vif); rwnx_chanctx_unlink(radar->cac_vif);
} }
+58 -28
View File
@@ -34,6 +34,60 @@
#define IEEE80211_MAX_CHAINS 4 #define IEEE80211_MAX_CHAINS 4
#endif #endif
/* OpenWrt can backport these helpers without changing LINUX_VERSION_CODE. */
typedef bool (*rwnx_cfg80211_rx_frame_legacy_t)(struct net_device *dev,
const u8 *addr, gfp_t gfp);
typedef bool (*rwnx_cfg80211_rx_frame_link_t)(struct net_device *dev,
const u8 *addr, int link_id,
gfp_t gfp);
#define RWNX_CFG80211_HELPER_MATCH(_helper, _type) \
__builtin_types_compatible_p(typeof(&(_helper)), _type)
typedef char rwnx_cfg80211_rx_spurious_frame_signature_must_be_supported[
(RWNX_CFG80211_HELPER_MATCH(cfg80211_rx_spurious_frame,
rwnx_cfg80211_rx_frame_legacy_t) ||
RWNX_CFG80211_HELPER_MATCH(cfg80211_rx_spurious_frame,
rwnx_cfg80211_rx_frame_link_t)) ? 1 : -1];
typedef char rwnx_cfg80211_rx_unexpected_4addr_frame_signature_must_be_supported[
(RWNX_CFG80211_HELPER_MATCH(cfg80211_rx_unexpected_4addr_frame,
rwnx_cfg80211_rx_frame_legacy_t) ||
RWNX_CFG80211_HELPER_MATCH(cfg80211_rx_unexpected_4addr_frame,
rwnx_cfg80211_rx_frame_link_t)) ? 1 : -1];
static bool rwnx_cfg80211_rx_spurious_frame_compat(struct net_device *dev,
const u8 *addr, gfp_t gfp)
{
union {
typeof(&cfg80211_rx_spurious_frame) actual;
rwnx_cfg80211_rx_frame_legacy_t legacy;
rwnx_cfg80211_rx_frame_link_t link;
} helper = { .actual = &cfg80211_rx_spurious_frame };
if (RWNX_CFG80211_HELPER_MATCH(cfg80211_rx_spurious_frame,
rwnx_cfg80211_rx_frame_link_t))
return helper.link(dev, addr, -1, gfp);
return helper.legacy(dev, addr, gfp);
}
static bool rwnx_cfg80211_rx_unexpected_4addr_frame_compat(
struct net_device *dev, const u8 *addr, gfp_t gfp)
{
union {
typeof(&cfg80211_rx_unexpected_4addr_frame) actual;
rwnx_cfg80211_rx_frame_legacy_t legacy;
rwnx_cfg80211_rx_frame_link_t link;
} helper = { .actual = &cfg80211_rx_unexpected_4addr_frame };
if (RWNX_CFG80211_HELPER_MATCH(cfg80211_rx_unexpected_4addr_frame,
rwnx_cfg80211_rx_frame_link_t))
return helper.link(dev, addr, -1, gfp);
return helper.legacy(dev, addr, gfp);
}
u8 dhcped = 0; u8 dhcped = 0;
u16 tx_legrates_lut_rate[] = { u16 tx_legrates_lut_rate[] = {
@@ -2283,11 +2337,6 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
if(hw_rxhdr->flags_upload) if(hw_rxhdr->flags_upload)
status |= RX_STAT_FORWARD; status |= RX_STAT_FORWARD;
#ifndef CONFIG_RWNX_MON_DATA
if (status & RX_STAT_MONITOR)
status &= ~RX_STAT_FORWARD;
#endif
/* Check if we need to delete the buffer */ /* Check if we need to delete the buffer */
if (status & RX_STAT_DELETE) { if (status & RX_STAT_DELETE) {
/* Remove the SK buffer from the rxbuf_elems table */ /* Remove the SK buffer from the rxbuf_elems table */
@@ -2350,24 +2399,13 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
} else { } else {
#ifdef CONFIG_RWNX_MON_DATA #ifdef CONFIG_RWNX_MON_DATA
skb_monitor = skb_copy_expand(skb, rtap_len, 0, GFP_ATOMIC); skb_monitor = skb_copy_expand(skb, rtap_len, 0, GFP_ATOMIC);
if (skb_monitor) {
skb_monitor->data += (msdu_offset + 2); //sdio/usb word allign skb_monitor->data += (msdu_offset + 2); //sdio/usb word allign
//Save frame length //Save frame length
frm_len = le32_to_cpu(hw_rxhdr->hwvect.len); frm_len = le32_to_cpu(hw_rxhdr->hwvect.len);
}
#endif #endif
} }
if (!skb_monitor) {
if (status == RX_STAT_MONITOR) {
dev_kfree_skb(skb);
goto end;
}
goto check_len_update;
}
//skb_reset_tail_pointer(skb); //skb_reset_tail_pointer(skb);
//skb->len = 0; //skb->len = 0;
skb_reset_tail_pointer(skb_monitor); skb_reset_tail_pointer(skb_monitor);
@@ -2410,11 +2448,8 @@ check_len_update:
hdr = (struct ieee80211_hdr *)(skb->data + msdu_offset); hdr = (struct ieee80211_hdr *)(skb->data + msdu_offset);
rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx); rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx);
if (rwnx_vif) { if (rwnx_vif) {
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) rwnx_cfg80211_rx_spurious_frame_compat(rwnx_vif->ndev,
cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, -1, GFP_ATOMIC); hdr->addr2, GFP_ATOMIC);
#else
cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC);
#endif
} }
goto end; goto end;
} }
@@ -2757,13 +2792,8 @@ check_len_update:
if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) { if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) {
printk("aicwf: 4addr flag error\n"); printk("aicwf: 4addr flag error\n");
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) rwnx_cfg80211_rx_unexpected_4addr_frame_compat(
cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev, rwnx_vif->ndev, sta->mac_addr, GFP_ATOMIC);
sta->mac_addr, -1, GFP_ATOMIC);
#else
cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
sta->mac_addr, GFP_ATOMIC);
#endif
} }
} }
+4 -4
View File
@@ -115,8 +115,8 @@ rwnx_prep_tdls_direct(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
switch (action_code) { switch (action_code) {
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
skb_put(skb, 2 + sizeof(mgmt->u.action.tdls_discover_resp)); skb_put(skb, 1 + sizeof(mgmt->u.action.tdls_discover_resp));
mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES; mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token; mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token;
@@ -775,9 +775,9 @@ rwnx_tdls_send_mgmt_packet_data(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_v
params.len = skb->len; params.len = skb->len;
params.buf = skb->data; params.buf = skb->data;
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, &params, false, &cookie, false); ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, &params, false, &cookie);
#else #else
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, NULL, false, 0, skb->data, skb->len, false, false, &cookie, false); ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, NULL, false, 0, skb->data, skb->len, false, false, &cookie);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
return ret; return ret;
+23 -55
View File
@@ -1325,7 +1325,6 @@ int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg)
sw_txhdr->rwnx_sta = sta; sw_txhdr->rwnx_sta = sta;
sw_txhdr->rwnx_vif = rwnx_vif; sw_txhdr->rwnx_vif = rwnx_vif;
sw_txhdr->skb = skb; sw_txhdr->skb = skb;
sw_txhdr->cookie = (unsigned long)skb;
sw_txhdr->headroom = headroom; sw_txhdr->headroom = headroom;
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr); sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
@@ -1542,7 +1541,6 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev)
sw_txhdr->rwnx_sta = sta; sw_txhdr->rwnx_sta = sta;
sw_txhdr->rwnx_vif = rwnx_vif; sw_txhdr->rwnx_vif = rwnx_vif;
sw_txhdr->skb = skb; sw_txhdr->skb = skb;
sw_txhdr->cookie = (unsigned long)skb;
sw_txhdr->headroom = headroom; sw_txhdr->headroom = headroom;
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr); sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
@@ -1632,12 +1630,7 @@ free:
* @params: Mgmt frame parameters * @params: Mgmt frame parameters
* @offchan: Indicate whether the frame must be send via the offchan TXQ. * @offchan: Indicate whether the frame must be send via the offchan TXQ.
* (is is redundant with params->offchan ?) * (is is redundant with params->offchan ?)
* @cookie: on return, the value cfg80211_mgmt_tx_status() will report for * @cookie: updated with a unique value to identify the frame with upper layer
* this frame: invented here (the skb pointer) unless
* @use_given_cookie is set, in which case *@cookie is kept.
* @use_given_cookie: *@cookie already holds the cookie cfg80211 assigned
* (7.3+, the direct .mgmt_tx path only); honour it instead of
* inventing one. Every other caller passes false.
* *
*/ */
@@ -1645,7 +1638,7 @@ free:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta, int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
struct cfg80211_mgmt_tx_params *params, bool offchan, struct cfg80211_mgmt_tx_params *params, bool offchan,
u64 *cookie, bool use_given_cookie) u64 *cookie)
#else #else
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta, int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
struct ieee80211_channel *channel, bool offchan, struct ieee80211_channel *channel, bool offchan,
@@ -1656,7 +1649,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
bool dont_wait_for_ack, bool dont_wait_for_ack,
#endif #endif
u64 *cookie, bool use_given_cookie) u64 *cookie)
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
{ {
struct rwnx_hw *rwnx_hw = vif->rwnx_hw; struct rwnx_hw *rwnx_hw = vif->rwnx_hw;
@@ -1710,17 +1703,6 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
return -ENOMEM; return -ENOMEM;
} }
/*
* use_given_cookie is true only for the direct cfg80211 .mgmt_tx call
* path on 7.3+, where *cookie already holds the value cfg80211
* pre-assigned and must be echoed back via cfg80211_mgmt_tx_status()
* later -- see rwnx_cfg80211_mgmt_tx(). TDLS's internal reuse of this
* function (use_given_cookie == false) never goes through that cfg80211
* op, so it still gets an invented, locally-unique cookie exactly as
* before this fix, and on every kernel older than 7.3 every caller
* passes use_given_cookie == false, also leaving this unchanged.
*/
if (!use_given_cookie)
*cookie = (unsigned long)skb; *cookie = (unsigned long)skb;
/* /*
@@ -1791,7 +1773,6 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
sw_txhdr->rwnx_sta = sta; sw_txhdr->rwnx_sta = sta;
sw_txhdr->rwnx_vif = vif; sw_txhdr->rwnx_vif = vif;
sw_txhdr->skb = skb; sw_txhdr->skb = skb;
sw_txhdr->cookie = *cookie;
sw_txhdr->headroom = headroom; sw_txhdr->headroom = headroom;
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr); sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
#ifdef CONFIG_RWNX_AMSDUS_TX #ifdef CONFIG_RWNX_AMSDUS_TX
@@ -1943,7 +1924,6 @@ void rwnx_probersp_work(struct work_struct *work)
sw_txhdr->rwnx_sta = sta; sw_txhdr->rwnx_sta = sta;
sw_txhdr->rwnx_vif = rwnx_vif; sw_txhdr->rwnx_vif = rwnx_vif;
sw_txhdr->skb = skb; sw_txhdr->skb = skb;
sw_txhdr->cookie = (unsigned long)skb;
sw_txhdr->headroom = headroom; sw_txhdr->headroom = headroom;
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr); sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
#ifdef CONFIG_RWNX_AMSDUS_TX #ifdef CONFIG_RWNX_AMSDUS_TX
@@ -2011,7 +1991,7 @@ free_use:
netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev) netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
int rtap_len, ret, idx; int rtap_len, ret, idx, tmp_len;
struct ieee80211_radiotap_header *rtap_hdr; // net/ieee80211_radiotap.h struct ieee80211_radiotap_header *rtap_hdr; // net/ieee80211_radiotap.h
struct ieee80211_radiotap_iterator iterator; // net/cfg80211.h struct ieee80211_radiotap_iterator iterator; // net/cfg80211.h
u8_l *rtap_buf = (u8_l *)skb->data; u8_l *rtap_buf = (u8_l *)skb->data;
@@ -2032,29 +2012,9 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
bool offchan = false; bool offchan = false;
int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX; int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX;
frame_len = skb->len;
if (unlikely(skb->len < sizeof(*rtap_hdr))) {
AICWFDBG(LOGERROR, "%s radiotap header is truncated\n", __func__);
goto free_tag;
}
rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf); rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf);
if (unlikely(rtap_hdr->it_version)) {
AICWFDBG(LOGERROR, "%s itv \r\n", __func__);
goto free_tag;
}
rtap_len = ieee80211_get_radiotap_len(rtap_buf);//max_length rtap_len = ieee80211_get_radiotap_len(rtap_buf);//max_length
if (unlikely(rtap_len < sizeof(*rtap_hdr))) { frame_len = skb->len;
AICWFDBG(LOGERROR, "%s rtap_len < sizeof(struct ieee80211_radiotap_header) \r\n", __func__);
goto free_tag;
}
if (unlikely(skb->len < rtap_len)) {
AICWFDBG(LOGERROR, "%s skb->len < rtap_len \r\n", __func__);
goto free_tag;
}
AICWFDBG(LOGINFO, "rwnx_start_monitor_if_xmit, skb_len=%d, rtap_len=%d\n", skb->len, rtap_len); AICWFDBG(LOGINFO, "rwnx_start_monitor_if_xmit, skb_len=%d, rtap_len=%d\n", skb->len, rtap_len);
//rwnx_data_dump((char*)__func__, skb->data, skb->len); //rwnx_data_dump((char*)__func__, skb->data, skb->len);
@@ -2063,6 +2023,23 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){
nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC; nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC;
} }
if (unlikely(rtap_hdr->it_version)){
AICWFDBG(LOGERROR, "%s itv \r\n", __func__);
goto free_tag;
}
if (unlikely(skb->len < rtap_len)){
AICWFDBG(LOGERROR, "%s skb->len < rtap_len \r\n", __func__);
goto free_tag;
}
if (unlikely(rtap_len < sizeof(struct ieee80211_radiotap_header))){
AICWFDBG(LOGERROR, "%s rtap_len < sizeof(struct ieee80211_radiotap_header) \r\n", __func__);
goto free_tag;
}
frame_len -= rtap_len; frame_len -= rtap_len;
pframe = rtap_buf + rtap_len; pframe = rtap_buf + rtap_len;
@@ -2298,15 +2275,6 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
sw_txhdr->rwnx_sta = sta; sw_txhdr->rwnx_sta = sta;
sw_txhdr->rwnx_vif = vif; sw_txhdr->rwnx_vif = vif;
sw_txhdr->skb = skb_mgmt; sw_txhdr->skb = skb_mgmt;
/*
* Injected frames are flagged TXU_CNTRL_MGMT below and complete through
* the same path as management frames, which reports sw_txhdr->cookie to
* cfg80211_mgmt_tx_status(). There is no cfg80211-assigned cookie for an
* injected frame, so this is the skb-derived value that path reported
* before the field existed. Not gated on 7.3: this path runs on every
* kernel with CONFIG_RWNX_MON_XMIT.
*/
sw_txhdr->cookie = (unsigned long)skb_mgmt;
sw_txhdr->headroom = headroom; sw_txhdr->headroom = headroom;
sw_txhdr->map_len = skb_mgmt->len - offsetof(struct rwnx_txhdr, hw_hdr); sw_txhdr->map_len = skb_mgmt->len - offsetof(struct rwnx_txhdr, hw_hdr);
sw_txhdr->raw_frame = 1; sw_txhdr->raw_frame = 1;
@@ -2418,7 +2386,7 @@ int rwnx_txdatacfm(void *pthis, void *host_id)
#endif #endif
/* Confirm transmission to CFG80211 */ /* Confirm transmission to CFG80211 */
cfg80211_mgmt_tx_status(&sw_txhdr->rwnx_vif->wdev, cfg80211_mgmt_tx_status(&sw_txhdr->rwnx_vif->wdev,
sw_txhdr->cookie, (unsigned long)skb,
(skb->data + sw_txhdr->headroom), (skb->data + sw_txhdr->headroom),
sw_txhdr->frame_len, sw_txhdr->frame_len,
rwnx_txst.acknowledged, rwnx_txst.acknowledged,
+3 -15
View File
@@ -130,17 +130,6 @@ struct rwnx_sw_txhdr {
#endif #endif
u32 need_cfm; u32 need_cfm;
struct sk_buff *skb; struct sk_buff *skb;
/*
* The cookie cfg80211_mgmt_tx_status() reports for this frame. sw_txhdr
* comes from a kmem_cache and is never zeroed, so every allocation site
* sets this: (unsigned long)skb, which is what the completion path
* reported before the field existed, except in rwnx_start_mgmt_xmit(),
* which stores the cfg80211-assigned cookie it was handed on 7.3+ (see
* use_given_cookie there). Only frames flagged TXU_CNTRL_MGMT are ever
* reported, but the field is initialised unconditionally so that filter
* is not what keeps it safe.
*/
u64 cookie;
size_t map_len; size_t map_len;
dma_addr_t dma_addr; dma_addr_t dma_addr;
@@ -169,7 +158,7 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta, int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
struct cfg80211_mgmt_tx_params *params, bool offchan, struct cfg80211_mgmt_tx_params *params, bool offchan,
u64 *cookie, bool use_given_cookie); u64 *cookie);
#else #else
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta, int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
struct ieee80211_channel *channel, bool offchan, struct ieee80211_channel *channel, bool offchan,
@@ -180,11 +169,10 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
bool dont_wait_for_ack, bool dont_wait_for_ack,
#endif #endif
u64 *cookie, bool use_given_cookie); u64 *cookie);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
#ifdef CONFIG_RWNX_MON_XMIT #ifdef CONFIG_RWNX_MON_XMIT
netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, int rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev);
struct net_device *dev);
#endif #endif
int rwnx_txdatacfm(void *pthis, void *host_id); int rwnx_txdatacfm(void *pthis, void *host_id);
+13 -111
View File
@@ -39,36 +39,14 @@ typedef struct {
#define AIC_PATCH_OFST(mem) ((size_t) &((aic_patch_t *)0)->mem) #define AIC_PATCH_OFST(mem) ((size_t) &((aic_patch_t *)0)->mem)
#define AIC_PATCH_ADDR(mem) ((u32) (aic_patch_str_base + AIC_PATCH_OFST(mem))) #define AIC_PATCH_ADDR(mem) ((u32) (aic_patch_str_base + AIC_PATCH_OFST(mem)))
#define USER_PWROFST_COVER_CALIB_FLAG (0x01U << 0) /*
#define USER_CHAN_MAX_TXPWR_EN_FLAG (0x01U << 1) * Issue #58 legacy-loader test.
#define USER_TX_USE_ANA_F_FLAG (0x01U << 2) *
#define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3) * Keep this table aligned with the SDK V3 D80 firmware imported from Radxa
#define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4) * commit 254d47e6a131dbed5ba32131972f4719f3e1c7fe. Newer loader patches use
#define USER_LOFT_CALIB_DISABLE_FLAG (0x01U << 6) * different RX aggregation settings and a user_ext_flags field that is not
#define USER_CAPA_CALIB_DISABLE_FLAG (0x01U << 7) * part of this firmware generation.
#define USER_PWR_CALIB_DISABLE_FLAG (0x01U << 8) */
#define USER_IPA_CALIB_DISABLE_FLAG (0x01U << 13)
#define USER_EXT_FLAGS_DEFAULT_D80 (USER_PWROFST_COVER_CALIB_FLAG)
#define CFG_USER_PWROFST_COVER_CALIB_EN (1)
#if (defined(CONFIG_POWER_LIMIT))
#define CFG_USER_CHAN_MAX_TXPWR_EN (1)
#else
#define CFG_USER_CHAN_MAX_TXPWR_EN (0)
#endif
#define CFG_USER_TX_USE_ANA_F_EN (0)
#if (defined(CONFIG_PRBREQ_REPORT))
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (1)
#else
#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (0)
#endif
#define CFG_USER_HE_MU_EDCA_UPDATE_DISABLE (0)
#define CFG_USER_LOFT_CALIB_DISABLE_DISABLE (0)
#define CFG_USER_CAPA_CALIB_DISABLE_DISABLE (0)
#define CFG_USER_PWR_CALIB_DISABLE_DISABLE (0)
#define CFG_USER_IPA_CALIB_DISABLE_DISABLE (0)
u32 patch_tbl_d80[][2] = u32 patch_tbl_d80[][2] =
{ {
#ifdef USE_5G #ifdef USE_5G
@@ -76,54 +54,7 @@ u32 patch_tbl_d80[][2] =
#else #else
{0x00b4, 0xf3010000}, {0x00b4, 0xf3010000},
#endif #endif
#ifdef CONFIG_PLATFORM_HI {0x0170, 0x00000002},//rx aggr counter
{0x0170, 0x00010001},//rx aggr counter
#else
{0x0170, 0x0001000A},//rx aggr counter
#endif
{0x0188,
(USER_EXT_FLAGS_DEFAULT_D80 |
#if CFG_USER_CHAN_MAX_TXPWR_EN
USER_CHAN_MAX_TXPWR_EN_FLAG |
#endif
#if CFG_USER_TX_USE_ANA_F_EN
USER_TX_USE_ANA_F_FLAG |
#endif
#if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE
USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG |
#endif
#if CFG_USER_HE_MU_EDCA_UPDATE_DISABLE
USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG |
#endif
#if CFG_USER_LOFT_CALIB_DISABLE_DISABLE
USER_LOFT_CALIB_DISABLE_FLAG |
#endif
#if CFG_USER_CAPA_CALIB_DISABLE_DISABLE
USER_CAPA_CALIB_DISABLE_FLAG |
#endif
#if CFG_USER_PWR_CALIB_DISABLE_DISABLE
USER_PWR_CALIB_DISABLE_FLAG |
#endif
#if CFG_USER_IPA_CALIB_DISABLE_DISABLE
USER_IPA_CALIB_DISABLE_FLAG |
#endif
0) & ~(
#if !CFG_USER_PWROFST_COVER_CALIB_EN
USER_PWROFST_COVER_CALIB_FLAG |
#endif
0)
}, // user_ext_flags
#ifdef CONFIG_RADAR_OR_IR_DETECT
{0x0019c,0x00000900},
#endif
#ifdef CONFIG_WOWLAN
{0x019c,0x01000000},
#ifdef ANDROID_PLATFORM
{0x01A0, 0x01000001},
#endif
#endif
}; };
//adap test //adap test
@@ -144,16 +75,11 @@ u32 syscfg_tbl_8800d80[][2] = {
extern int adap_test; extern int adap_test;
#define NEW_PATCH_BUFFER_MAP 1
int aicwf_patch_config_8800d80(struct aic_usb_dev *usb_dev) int aicwf_patch_config_8800d80(struct aic_usb_dev *usb_dev)
{ {
u32 rd_patch_addr; u32 rd_patch_addr;
u32 aic_patch_addr; u32 aic_patch_addr;
u32 config_base, aic_patch_str_base; u32 config_base, aic_patch_str_base;
#if (NEW_PATCH_BUFFER_MAP)
u32 patch_buff_addr, patch_buff_base, rd_version_addr, rd_version_val;
#endif
uint32_t start_addr = 0x001D7000; uint32_t start_addr = 0x001D7000;
u32 patch_addr = start_addr; u32 patch_addr = start_addr;
u32 patch_cnt = sizeof(patch_tbl_d80) / 4 / 2; u32 patch_cnt = sizeof(patch_tbl_d80) / 4 / 2;
@@ -190,32 +116,6 @@ int aicwf_patch_config_8800d80(struct aic_usb_dev *usb_dev)
AICWFDBG(LOGERROR, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata); AICWFDBG(LOGERROR, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata);
aic_patch_str_base = rd_patch_addr_cfm.memdata; aic_patch_str_base = rd_patch_addr_cfm.memdata;
#if (NEW_PATCH_BUFFER_MAP)
if (chip_id == CHIP_REV_U01) {
rd_version_addr = RAM_FMAC_FW_ADDR_8800D80 + 0x01C;
} else {
rd_version_addr = RAM_FMAC_FW_ADDR_8800D80_U02 + 0x01C;
}
if ((ret = rwnx_send_dbg_mem_read_req(usb_dev, rd_version_addr, &rd_patch_addr_cfm))) {
AICWFDBG(LOGERROR, "version val[0x%x] rd fail: %d\n", rd_version_addr, ret);
return ret;
}
rd_version_val = rd_patch_addr_cfm.memdata;
AICWFDBG(LOGINFO, "rd_version_val=%08X\n", rd_version_val);
usb_dev->fw_version_uint = rd_version_val;
if (rd_version_val > 0x06090100) {
patch_buff_addr = rd_patch_addr + 12;
ret = rwnx_send_dbg_mem_read_req(usb_dev, patch_buff_addr, &rd_patch_addr_cfm);
if (ret) {
AICWFDBG(LOGERROR, "patch buf rd fail\n");
return ret;
}
AICWFDBG(LOGINFO, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata);
patch_buff_base = rd_patch_addr_cfm.memdata;
patch_addr = start_addr = patch_buff_base;
}
#endif
if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(magic_num), AIC_PATCH_MAGIG_NUM))) { if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(magic_num), AIC_PATCH_MAGIG_NUM))) {
AICWFDBG(LOGERROR, "maigic_num[0x%x] write fail: %d\n", AIC_PATCH_ADDR(magic_num), ret); AICWFDBG(LOGERROR, "maigic_num[0x%x] write fail: %d\n", AIC_PATCH_ADDR(magic_num), ret);
return ret; return ret;
@@ -346,10 +246,11 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){
} }
chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16); chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16);
printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id); printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id);
if (chip_mcu_id) { printk("AIC8800D80 legacy: using Radxa SDK V3 loader profile\n");
if (chip_mcu_id == 1) {
ret = rwnx_send_dbg_mem_read_req(usb_dev, cache_mem_addr, &rd_mem_addr_cfm); ret = rwnx_send_dbg_mem_read_req(usb_dev, cache_mem_addr, &rd_mem_addr_cfm);
if (ret) { if (ret) {
printk("%x rd fail: %d\n", mem_addr, ret); printk("%x rd fail: %d\n", cache_mem_addr, ret);
return ret; return ret;
} }
rd_mem_addr_cfm.memdata |= 0x01; rd_mem_addr_cfm.memdata |= 0x01;
@@ -358,6 +259,7 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){
printk("%x write fail: %d\n", cache_mem_addr, ret); printk("%x write fail: %d\n", cache_mem_addr, ret);
return ret; return ret;
} }
printk("AIC8800D80 MCU1: enabled Bluetooth cache fix\n");
} }
#if 1 #if 1
syscfg_num = sizeof(syscfg_tbl_8800d80) / sizeof(u32) / 2; syscfg_num = sizeof(syscfg_tbl_8800d80) / sizeof(u32) / 2;
@@ -149,11 +149,7 @@ static int usb_submit_urb_pre_handler(struct kprobe *p, struct pt_regs *regs)
(void)p; (void)p;
#if defined(CONFIG_ARM)
urb = (struct urb *)regs->ARM_r0;
#else
urb = (struct urb *)regs_get_kernel_argument(regs, 0); urb = (struct urb *)regs_get_kernel_argument(regs, 0);
#endif
if (is_bluetooth_acl_endpoint(urb)) if (is_bluetooth_acl_endpoint(urb))
enable_zlp(urb); enable_zlp(urb);
-117
View File
@@ -1,117 +0,0 @@
# AIC POWERLIMIT 2025/0623/1700
# Max tx power reference: Linux wireless regulatory database for CRDA
# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt
# If loss_value in aic_userconfig.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment
# Table 1:
## 2.4G, 20M,#6#
## START
## SRRC FCC ETSI JP KCC UNSET
CH01 16 14 14 16 16 15
CH02 16 14 14 16 16 16
CH03 16 14 14 16 16 16
CH04 16 14 14 16 16 16
CH05 16 14 14 16 16 16
CH06 16 14 14 16 16 16
CH07 16 14 14 16 16 16
CH08 16 14 14 16 16 16
CH09 16 14 14 16 16 16
CH10 16 14 14 16 16 16
CH11 16 14 14 16 16 16
CH12 15 14 14 16 16 12
CH13 13 14 14 16 16 12
CH14 NA NA NA 16 NA 12
## END
# Table 2:
## 2.4G, 40M,#6#
## START
## SRRC FCC ETSI JP KCC UNSET
CH01 NA NA NA NA NA NA
CH02 NA NA NA NA NA NA
CH03 16 13 14 16 16 16
CH04 16 13 14 16 16 16
CH05 16 13 14 16 16 16
CH06 16 13 14 16 16 16
CH07 16 13 14 16 16 16
CH08 16 13 14 16 16 16
CH09 16 11 14 16 16 16
CH10 16 11 14 16 16 16
CH11 16 11 14 16 16 16
CH12 NA NA NA NA NA NA
CH13 NA NA NA NA NA NA
CH14 NA NA NA NA NA NA
## END
# Table 3:
## 5G, 20M,#6#
## START
## SRRC FCC ETSI JP KCC UNSET
# 5G Band 1
CH36 15 16 16 16 16 15
CH40 15 16 16 16 16 15
CH44 15 16 16 16 16 15
CH48 15 16 16 16 16 15
# 5G Band 2
CH52 15 16 16 16 16 15
CH56 15 16 16 16 16 15
CH60 15 16 16 16 16 15
CH64 15 16 16 16 16 15
# 5G Band 3
CH100 NA 16 16 16 16 15
CH104 NA 16 16 16 16 15
CH108 NA 16 16 16 16 15
CH112 NA 16 16 16 16 15
CH116 NA 16 16 16 16 15
CH120 NA 16 16 16 16 15
CH124 NA 16 16 16 16 15
CH128 NA 16 16 16 16 15
CH132 NA 16 16 16 16 15
CH136 NA 16 16 16 16 15
CH140 NA 16 16 16 16 15
CH144 NA NA 16 16 16 15
# 5G Band 4
CH149 20 16 8 NA 20 11
CH153 20 16 8 NA 20 11
CH157 20 16 8 NA 20 11
CH161 20 16 8 NA 20 11
CH165 20 16 8 NA 20 11
## END
# Table 4:
## 5G, 40M,#6#
## START
## SRRC FCC ETSI JP KCC UNSET
# 5G Band 1
CH38 15 16 16 16 20 15
CH46 15 16 16 16 20 15
# 5G Band 2
CH54 15 16 16 16 20 15
CH62 15 16 16 16 20 15
# 5G Band 3
CH102 NA 16 16 16 20 15
CH110 NA 16 16 16 20 15
CH118 NA 16 16 16 20 15
CH126 NA 16 16 16 20 15
CH134 NA 16 16 16 20 15
CH142 NA 16 NA 16 20 15
# 5G Band 4
CH151 16 15 8 NA 18 11
CH159 17 16 8 NA 17 11
## END
# Table 5:
## 5G, 80M,#6#
## START
## SRRC FCC ETSI JP KCC UNSET
# 5G Band 1
CH42 15 16 16 16 20 15
# 5G Band 2
CH58 15 16 16 16 20 15
# 5G Band 3
CH106 NA 16 16 16 20 15
CH122 NA 16 16 16 20 15
CH138 NA 16 NA NA 20 15
# 5G Band 4
CH155 15 14 8 NA 16 11
## END
+2 -16
View File
@@ -67,23 +67,9 @@ lvl_11ax_mcs9_5g=13
lvl_11ax_mcs10_5g=12 lvl_11ax_mcs10_5g=12
lvl_11ax_mcs11_5g=12 lvl_11ax_mcs11_5g=12
# txpwr_lvl_adj
lvl_adj_enable=0
lvl_adj_2g4_chan_1_4=0
lvl_adj_2g4_chan_5_9=0
lvl_adj_2g4_chan_10_13=0
lvl_adj_5g_chan_42=0
lvl_adj_5g_chan_58=0
lvl_adj_5g_chan_106=0
lvl_adj_5g_chan_122=0
lvl_adj_5g_chan_138=0
lvl_adj_5g_chan_155=0
# txpwr_loss # txpwr_loss
loss_enable_2g4=0 loss_enable=0
loss_value_2g4=2 loss_value=2
loss_enable_5g=0
loss_value_5g=5
# txpwr_ofst # txpwr_ofst
ofst_enable=0 ofst_enable=0
@@ -1,124 +0,0 @@
# AIC USERCONFIG 2022/0803/1707
# txpwr_lvl
enable=1
lvl_11b_11ag_1m_2g4=20
lvl_11b_11ag_2m_2g4=20
lvl_11b_11ag_5m5_2g4=20
lvl_11b_11ag_11m_2g4=20
lvl_11b_11ag_6m_2g4=20
lvl_11b_11ag_9m_2g4=20
lvl_11b_11ag_12m_2g4=20
lvl_11b_11ag_18m_2g4=20
lvl_11b_11ag_24m_2g4=20
lvl_11b_11ag_36m_2g4=19
lvl_11b_11ag_48m_2g4=18
lvl_11b_11ag_54m_2g4=17
lvl_11n_11ac_mcs0_2g4=20
lvl_11n_11ac_mcs1_2g4=20
lvl_11n_11ac_mcs2_2g4=20
lvl_11n_11ac_mcs3_2g4=20
lvl_11n_11ac_mcs4_2g4=20
lvl_11n_11ac_mcs5_2g4=19
lvl_11n_11ac_mcs6_2g4=18
lvl_11n_11ac_mcs7_2g4=17
lvl_11n_11ac_mcs8_2g4=17
lvl_11n_11ac_mcs9_2g4=16
lvl_11ax_mcs0_2g4=20
lvl_11ax_mcs1_2g4=20
lvl_11ax_mcs2_2g4=20
lvl_11ax_mcs3_2g4=20
lvl_11ax_mcs4_2g4=20
lvl_11ax_mcs5_2g4=19
lvl_11ax_mcs6_2g4=18
lvl_11ax_mcs7_2g4=17
lvl_11ax_mcs8_2g4=17
lvl_11ax_mcs9_2g4=16
lvl_11ax_mcs10_2g4=15
lvl_11ax_mcs11_2g4=15
lvl_11a_6m_5g=19
lvl_11a_9m_5g=19
lvl_11a_12m_5g=19
lvl_11a_18m_5g=18
lvl_11a_24m_5g=18
lvl_11a_36m_5g=18
lvl_11a_48m_5g=18
lvl_11a_54m_5g=18
lvl_11n_11ac_mcs0_5g=19
lvl_11n_11ac_mcs1_5g=19
lvl_11n_11ac_mcs2_5g=19
lvl_11n_11ac_mcs3_5g=18
lvl_11n_11ac_mcs4_5g=18
lvl_11n_11ac_mcs5_5g=18
lvl_11n_11ac_mcs6_5g=18
lvl_11n_11ac_mcs7_5g=17
lvl_11n_11ac_mcs8_5g=15
lvl_11n_11ac_mcs9_5g=15
lvl_11ax_mcs0_5g=19
lvl_11ax_mcs1_5g=19
lvl_11ax_mcs2_5g=19
lvl_11ax_mcs3_5g=18
lvl_11ax_mcs4_5g=18
lvl_11ax_mcs5_5g=18
lvl_11ax_mcs6_5g=18
lvl_11ax_mcs7_5g=17
lvl_11ax_mcs8_5g=15
lvl_11ax_mcs9_5g=15
lvl_11ax_mcs10_5g=13
lvl_11ax_mcs11_5g=13
# txpwr_lvl_adj
lvl_adj_enable=0
lvl_adj_2g4_chan_1_4=0
lvl_adj_2g4_chan_5_9=0
lvl_adj_2g4_chan_10_13=0
lvl_adj_5g_chan_42=0
lvl_adj_5g_chan_58=0
lvl_adj_5g_chan_106=0
lvl_adj_5g_chan_122=0
lvl_adj_5g_chan_138=0
lvl_adj_5g_chan_155=0
# txpwr_loss
loss_enable_2g4=0
loss_value_2g4=2
loss_enable_5g=0
loss_value_5g=5
# txpwr_ofst
ofst_enable=0
ofst_2g4_11b_chan_1_4=0
ofst_2g4_11b_chan_5_9=0
ofst_2g4_11b_chan_10_13=0
ofst_2g4_ofdm_highrate_chan_1_4=0
ofst_2g4_ofdm_highrate_chan_5_9=0
ofst_2g4_ofdm_highrate_chan_10_13=0
ofst_2g4_ofdm_lowrate_chan_1_4=0
ofst_2g4_ofdm_lowrate_chan_5_9=0
ofst_2g4_ofdm_lowrate_chan_10_13=0
ofst_5g_ofdm_lowrate_chan_42=0
ofst_5g_ofdm_lowrate_chan_58=0
ofst_5g_ofdm_lowrate_chan_106=0
ofst_5g_ofdm_lowrate_chan_122=0
ofst_5g_ofdm_lowrate_chan_138=0
ofst_5g_ofdm_lowrate_chan_155=0
ofst_5g_ofdm_highrate_chan_42=0
ofst_5g_ofdm_highrate_chan_58=0
ofst_5g_ofdm_highrate_chan_106=0
ofst_5g_ofdm_highrate_chan_122=0
ofst_5g_ofdm_highrate_chan_138=0
ofst_5g_ofdm_highrate_chan_155=0
ofst_5g_ofdm_midrate_chan_42=0
ofst_5g_ofdm_midrate_chan_58=0
ofst_5g_ofdm_midrate_chan_106=0
ofst_5g_ofdm_midrate_chan_122=0
ofst_5g_ofdm_midrate_chan_138=0
ofst_5g_ofdm_midrate_chan_155=0
# xtal cap
xtal_enable=0
xtal_cap=24
xtal_cap_fine=31
@@ -1,124 +0,0 @@
# AIC USERCONFIG 2022/0803/1707
# txpwr_lvl
enable=1
lvl_11b_11ag_1m_2g4=18
lvl_11b_11ag_2m_2g4=18
lvl_11b_11ag_5m5_2g4=18
lvl_11b_11ag_11m_2g4=18
lvl_11b_11ag_6m_2g4=18
lvl_11b_11ag_9m_2g4=18
lvl_11b_11ag_12m_2g4=18
lvl_11b_11ag_18m_2g4=18
lvl_11b_11ag_24m_2g4=18
lvl_11b_11ag_36m_2g4=18
lvl_11b_11ag_48m_2g4=18
lvl_11b_11ag_54m_2g4=17
lvl_11n_11ac_mcs0_2g4=20
lvl_11n_11ac_mcs1_2g4=20
lvl_11n_11ac_mcs2_2g4=20
lvl_11n_11ac_mcs3_2g4=20
lvl_11n_11ac_mcs4_2g4=20
lvl_11n_11ac_mcs5_2g4=19
lvl_11n_11ac_mcs6_2g4=18
lvl_11n_11ac_mcs7_2g4=18
lvl_11n_11ac_mcs8_2g4=17
lvl_11n_11ac_mcs9_2g4=16
lvl_11ax_mcs0_2g4=20
lvl_11ax_mcs1_2g4=20
lvl_11ax_mcs2_2g4=20
lvl_11ax_mcs3_2g4=20
lvl_11ax_mcs4_2g4=20
lvl_11ax_mcs5_2g4=19
lvl_11ax_mcs6_2g4=18
lvl_11ax_mcs7_2g4=18
lvl_11ax_mcs8_2g4=17
lvl_11ax_mcs9_2g4=17
lvl_11ax_mcs10_2g4=16
lvl_11ax_mcs11_2g4=16
lvl_11a_6m_5g=18
lvl_11a_9m_5g=18
lvl_11a_12m_5g=18
lvl_11a_18m_5g=18
lvl_11a_24m_5g=18
lvl_11a_36m_5g=18
lvl_11a_48m_5g=18
lvl_11a_54m_5g=18
lvl_11n_11ac_mcs0_5g=20
lvl_11n_11ac_mcs1_5g=19
lvl_11n_11ac_mcs2_5g=19
lvl_11n_11ac_mcs3_5g=18
lvl_11n_11ac_mcs4_5g=18
lvl_11n_11ac_mcs5_5g=18
lvl_11n_11ac_mcs6_5g=18
lvl_11n_11ac_mcs7_5g=17
lvl_11n_11ac_mcs8_5g=16
lvl_11n_11ac_mcs9_5g=16
lvl_11ax_mcs0_5g=20
lvl_11ax_mcs1_5g=19
lvl_11ax_mcs2_5g=19
lvl_11ax_mcs3_5g=18
lvl_11ax_mcs4_5g=18
lvl_11ax_mcs5_5g=18
lvl_11ax_mcs6_5g=18
lvl_11ax_mcs7_5g=17
lvl_11ax_mcs8_5g=16
lvl_11ax_mcs9_5g=16
lvl_11ax_mcs10_5g=15
lvl_11ax_mcs11_5g=15
# txpwr_lvl_adj
lvl_adj_enable=0
lvl_adj_2g4_chan_1_4=0
lvl_adj_2g4_chan_5_9=0
lvl_adj_2g4_chan_10_13=0
lvl_adj_5g_chan_42=0
lvl_adj_5g_chan_58=0
lvl_adj_5g_chan_106=0
lvl_adj_5g_chan_122=0
lvl_adj_5g_chan_138=0
lvl_adj_5g_chan_155=0
# txpwr_loss
loss_enable_2g4=0
loss_value_2g4=2
loss_enable_5g=0
loss_value_5g=5
# txpwr_ofst
ofst_enable=0
ofst_2g4_11b_chan_1_4=0
ofst_2g4_11b_chan_5_9=0
ofst_2g4_11b_chan_10_13=0
ofst_2g4_ofdm_highrate_chan_1_4=0
ofst_2g4_ofdm_highrate_chan_5_9=0
ofst_2g4_ofdm_highrate_chan_10_13=0
ofst_2g4_ofdm_lowrate_chan_1_4=0
ofst_2g4_ofdm_lowrate_chan_5_9=0
ofst_2g4_ofdm_lowrate_chan_10_13=0
ofst_5g_ofdm_lowrate_chan_42=0
ofst_5g_ofdm_lowrate_chan_58=0
ofst_5g_ofdm_lowrate_chan_106=0
ofst_5g_ofdm_lowrate_chan_122=0
ofst_5g_ofdm_lowrate_chan_138=0
ofst_5g_ofdm_lowrate_chan_155=0
ofst_5g_ofdm_highrate_chan_42=0
ofst_5g_ofdm_highrate_chan_58=0
ofst_5g_ofdm_highrate_chan_106=0
ofst_5g_ofdm_highrate_chan_122=0
ofst_5g_ofdm_highrate_chan_138=0
ofst_5g_ofdm_highrate_chan_155=0
ofst_5g_ofdm_midrate_chan_42=0
ofst_5g_ofdm_midrate_chan_58=0
ofst_5g_ofdm_midrate_chan_106=0
ofst_5g_ofdm_midrate_chan_122=0
ofst_5g_ofdm_midrate_chan_138=0
ofst_5g_ofdm_midrate_chan_155=0
# xtal cap
xtal_enable=0
xtal_cap=24
xtal_cap_fine=31
@@ -1,124 +0,0 @@
# AIC USERCONFIG 2022/0803/1707
# txpwr_lvl
enable=1
lvl_11b_11ag_1m_2g4=20
lvl_11b_11ag_2m_2g4=20
lvl_11b_11ag_5m5_2g4=20
lvl_11b_11ag_11m_2g4=20
lvl_11b_11ag_6m_2g4=20
lvl_11b_11ag_9m_2g4=20
lvl_11b_11ag_12m_2g4=20
lvl_11b_11ag_18m_2g4=20
lvl_11b_11ag_24m_2g4=20
lvl_11b_11ag_36m_2g4=19
lvl_11b_11ag_48m_2g4=18
lvl_11b_11ag_54m_2g4=17
lvl_11n_11ac_mcs0_2g4=20
lvl_11n_11ac_mcs1_2g4=20
lvl_11n_11ac_mcs2_2g4=20
lvl_11n_11ac_mcs3_2g4=20
lvl_11n_11ac_mcs4_2g4=20
lvl_11n_11ac_mcs5_2g4=19
lvl_11n_11ac_mcs6_2g4=18
lvl_11n_11ac_mcs7_2g4=17
lvl_11n_11ac_mcs8_2g4=17
lvl_11n_11ac_mcs9_2g4=16
lvl_11ax_mcs0_2g4=20
lvl_11ax_mcs1_2g4=20
lvl_11ax_mcs2_2g4=20
lvl_11ax_mcs3_2g4=20
lvl_11ax_mcs4_2g4=20
lvl_11ax_mcs5_2g4=19
lvl_11ax_mcs6_2g4=18
lvl_11ax_mcs7_2g4=17
lvl_11ax_mcs8_2g4=17
lvl_11ax_mcs9_2g4=16
lvl_11ax_mcs10_2g4=15
lvl_11ax_mcs11_2g4=15
lvl_11a_6m_5g=19
lvl_11a_9m_5g=19
lvl_11a_12m_5g=19
lvl_11a_18m_5g=18
lvl_11a_24m_5g=18
lvl_11a_36m_5g=18
lvl_11a_48m_5g=18
lvl_11a_54m_5g=18
lvl_11n_11ac_mcs0_5g=19
lvl_11n_11ac_mcs1_5g=19
lvl_11n_11ac_mcs2_5g=19
lvl_11n_11ac_mcs3_5g=18
lvl_11n_11ac_mcs4_5g=18
lvl_11n_11ac_mcs5_5g=18
lvl_11n_11ac_mcs6_5g=18
lvl_11n_11ac_mcs7_5g=17
lvl_11n_11ac_mcs8_5g=15
lvl_11n_11ac_mcs9_5g=15
lvl_11ax_mcs0_5g=19
lvl_11ax_mcs1_5g=19
lvl_11ax_mcs2_5g=19
lvl_11ax_mcs3_5g=18
lvl_11ax_mcs4_5g=18
lvl_11ax_mcs5_5g=18
lvl_11ax_mcs6_5g=18
lvl_11ax_mcs7_5g=17
lvl_11ax_mcs8_5g=15
lvl_11ax_mcs9_5g=15
lvl_11ax_mcs10_5g=14
lvl_11ax_mcs11_5g=14
# txpwr_lvl_adj
lvl_adj_enable=0
lvl_adj_2g4_chan_1_4=0
lvl_adj_2g4_chan_5_9=0
lvl_adj_2g4_chan_10_13=0
lvl_adj_5g_chan_42=0
lvl_adj_5g_chan_58=0
lvl_adj_5g_chan_106=0
lvl_adj_5g_chan_122=0
lvl_adj_5g_chan_138=0
lvl_adj_5g_chan_155=0
# txpwr_loss
loss_enable_2g4=0
loss_value_2g4=2
loss_enable_5g=0
loss_value_5g=5
# txpwr_ofst
ofst_enable=0
ofst_2g4_11b_chan_1_4=0
ofst_2g4_11b_chan_5_9=0
ofst_2g4_11b_chan_10_13=0
ofst_2g4_ofdm_highrate_chan_1_4=0
ofst_2g4_ofdm_highrate_chan_5_9=0
ofst_2g4_ofdm_highrate_chan_10_13=0
ofst_2g4_ofdm_lowrate_chan_1_4=0
ofst_2g4_ofdm_lowrate_chan_5_9=0
ofst_2g4_ofdm_lowrate_chan_10_13=0
ofst_5g_ofdm_lowrate_chan_42=0
ofst_5g_ofdm_lowrate_chan_58=0
ofst_5g_ofdm_lowrate_chan_106=0
ofst_5g_ofdm_lowrate_chan_122=0
ofst_5g_ofdm_lowrate_chan_138=0
ofst_5g_ofdm_lowrate_chan_155=0
ofst_5g_ofdm_highrate_chan_42=0
ofst_5g_ofdm_highrate_chan_58=0
ofst_5g_ofdm_highrate_chan_106=0
ofst_5g_ofdm_highrate_chan_122=0
ofst_5g_ofdm_highrate_chan_138=0
ofst_5g_ofdm_highrate_chan_155=0
ofst_5g_ofdm_midrate_chan_42=0
ofst_5g_ofdm_midrate_chan_58=0
ofst_5g_ofdm_midrate_chan_106=0
ofst_5g_ofdm_midrate_chan_122=0
ofst_5g_ofdm_midrate_chan_138=0
ofst_5g_ofdm_midrate_chan_155=0
# xtal cap
xtal_enable=0
xtal_cap=24
xtal_cap_fine=31
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+83 -83
View File
@@ -1,117 +1,117 @@
# AIC POWERLIMIT 2025/0623/1700 # AIC POWERLIMIT 2024/1108/1900
# Max tx power reference: Linux wireless regulatory database for CRDA # Max tx power reference: Linux wireless regulatory database for CRDA
# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt # https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt
# If loss_value in aic_userconfig.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment # If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment
# Table 1: # Table 1:
## 2.4G, 20M,#6# ## 2.4G, 20M,#5#
## START ## START
## SRRC FCC ETSI JP KCC UNSET ## SRRC FCC ETSI JP UNSET
CH01 16 14 14 16 16 15 CH01 15 15 15 15 15
CH02 16 14 14 16 16 16 CH02 16 16 16 16 16
CH03 16 14 14 16 16 16 CH03 16 16 16 16 16
CH04 16 14 14 16 16 16 CH04 16 16 16 16 16
CH05 16 14 14 16 16 16 CH05 16 16 16 16 16
CH06 16 14 14 16 16 16 CH06 16 16 16 16 16
CH07 16 14 14 16 16 16 CH07 16 16 16 16 16
CH08 16 14 14 16 16 16 CH08 16 16 16 16 16
CH09 16 14 14 16 16 16 CH09 16 16 16 16 16
CH10 16 14 14 16 16 16 CH10 16 16 16 16 16
CH11 16 14 14 16 16 16 CH11 16 16 16 16 16
CH12 15 14 14 16 16 12 CH12 12 12 12 12 12
CH13 13 14 14 16 16 12 CH13 12 12 12 12 12
CH14 NA NA NA 16 NA 12 CH14 NA NA NA 12 12
## END ## END
# Table 2: # Table 2:
## 2.4G, 40M,#6# ## 2.4G, 40M,#5#
## START ## START
## SRRC FCC ETSI JP KCC UNSET ## SRRC FCC ETSI JP UNSET
CH01 NA NA NA NA NA NA CH01 NA NA NA NA NA
CH02 NA NA NA NA NA NA CH02 NA NA NA NA NA
CH03 16 13 14 16 16 16 CH03 16 16 16 16 16
CH04 16 13 14 16 16 16 CH04 16 16 16 16 16
CH05 16 13 14 16 16 16 CH05 16 16 16 16 16
CH06 16 13 14 16 16 16 CH06 16 16 16 16 16
CH07 16 13 14 16 16 16 CH07 16 16 16 16 16
CH08 16 13 14 16 16 16 CH08 16 16 16 16 16
CH09 16 11 14 16 16 16 CH09 16 16 16 16 16
CH10 16 11 14 16 16 16 CH10 16 16 16 16 16
CH11 16 11 14 16 16 16 CH11 16 16 16 16 16
CH12 NA NA NA NA NA NA CH12 NA NA NA NA NA
CH13 NA NA NA NA NA NA CH13 NA NA NA NA NA
CH14 NA NA NA NA NA NA CH14 NA NA NA NA NA
## END ## END
# Table 3: # Table 3:
## 5G, 20M,#6# ## 5G, 20M,#5#
## START ## START
## SRRC FCC ETSI JP KCC UNSET ## SRRC FCC ETSI JP UNSET
# 5G Band 1 # 5G Band 1
CH36 15 16 16 16 16 15 CH36 15 16 16 16 15
CH40 15 16 16 16 16 15 CH40 15 16 16 16 15
CH44 15 16 16 16 16 15 CH44 15 16 16 16 15
CH48 15 16 16 16 16 15 CH48 15 16 16 16 15
# 5G Band 2 # 5G Band 2
CH52 15 16 16 16 16 15 CH52 15 16 16 16 15
CH56 15 16 16 16 16 15 CH56 15 16 16 16 15
CH60 15 16 16 16 16 15 CH60 15 16 16 16 15
CH64 15 16 16 16 16 15 CH64 15 16 16 16 15
# 5G Band 3 # 5G Band 3
CH100 NA 16 16 16 16 15 CH100 NA 16 16 16 15
CH104 NA 16 16 16 16 15 CH104 NA 16 16 16 15
CH108 NA 16 16 16 16 15 CH108 NA 16 16 16 15
CH112 NA 16 16 16 16 15 CH112 NA 16 16 16 15
CH116 NA 16 16 16 16 15 CH116 NA 16 16 16 15
CH120 NA 16 16 16 16 15 CH120 NA 16 16 16 15
CH124 NA 16 16 16 16 15 CH124 NA 16 16 16 15
CH128 NA 16 16 16 16 15 CH128 NA 16 16 16 15
CH132 NA 16 16 16 16 15 CH132 NA 16 16 16 15
CH136 NA 16 16 16 16 15 CH136 NA 16 16 16 15
CH140 NA 16 16 16 16 15 CH140 NA 16 16 16 15
CH144 NA NA 16 16 16 15 CH144 NA NA 16 16 15
# 5G Band 4 # 5G Band 4
CH149 20 16 8 NA 20 11 CH149 16 16 11 NA 11
CH153 20 16 8 NA 20 11 CH153 16 16 11 NA 11
CH157 20 16 8 NA 20 11 CH157 16 16 11 NA 11
CH161 20 16 8 NA 20 11 CH161 16 16 11 NA 11
CH165 20 16 8 NA 20 11 CH165 16 16 11 NA 11
## END ## END
# Table 4: # Table 4:
## 5G, 40M,#6# ## 5G, 40M,#5#
## START ## START
## SRRC FCC ETSI JP KCC UNSET ## SRRC FCC ETSI JP UNSET
# 5G Band 1 # 5G Band 1
CH38 15 16 16 16 20 15 CH38 15 16 16 16 15
CH46 15 16 16 16 20 15 CH46 15 16 16 16 15
# 5G Band 2 # 5G Band 2
CH54 15 16 16 16 20 15 CH54 15 16 16 16 15
CH62 15 16 16 16 20 15 CH62 15 16 16 16 15
# 5G Band 3 # 5G Band 3
CH102 NA 16 16 16 20 15 CH102 NA 16 16 16 15
CH110 NA 16 16 16 20 15 CH110 NA 16 16 16 15
CH118 NA 16 16 16 20 15 CH118 NA 16 16 16 15
CH126 NA 16 16 16 20 15 CH126 NA 16 16 16 15
CH134 NA 16 16 16 20 15 CH134 NA 16 16 16 15
CH142 NA 16 NA 16 20 15 CH142 NA 16 NA 16 15
# 5G Band 4 # 5G Band 4
CH151 16 15 8 NA 18 11 CH151 16 16 11 NA 11
CH159 17 16 8 NA 17 11 CH159 16 16 11 NA 11
## END ## END
# Table 5: # Table 5:
## 5G, 80M,#6# ## 5G, 80M,#5#
## START ## START
## SRRC FCC ETSI JP KCC UNSET ## SRRC FCC ETSI JP UNSET
# 5G Band 1 # 5G Band 1
CH42 15 16 16 16 20 15 CH42 15 16 16 16 15
# 5G Band 2 # 5G Band 2
CH58 15 16 16 16 20 15 CH58 15 16 16 16 15
# 5G Band 3 # 5G Band 3
CH106 NA 16 16 16 20 15 CH106 NA 16 16 16 15
CH122 NA 16 16 16 20 15 CH122 NA 16 16 16 15
CH138 NA 16 NA NA 20 15 CH138 NA 16 NA NA 15
# 5G Band 4 # 5G Band 4
CH155 15 14 8 NA 16 11 CH155 16 16 11 NA 11
## END ## END
+83 -83
View File
@@ -1,117 +1,117 @@
# AIC POWERLIMIT 2025/0623/1700 # AIC POWERLIMIT 2024/1108/1900
# Max tx power reference: Linux wireless regulatory database for CRDA # Max tx power reference: Linux wireless regulatory database for CRDA
# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt # https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt
# If loss_value in aic_userconfig.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment # If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment
# Table 1: # Table 1:
## 2.4G, 20M,#6# ## 2.4G, 20M,#5#
## START ## START
## SRRC FCC ETSI JP KCC UNSET ## SRRC FCC ETSI JP UNSET
CH01 16 14 14 16 16 15 CH01 15 15 15 15 15
CH02 16 14 14 16 16 16 CH02 16 16 16 16 16
CH03 16 14 14 16 16 16 CH03 16 16 16 16 16
CH04 16 14 14 16 16 16 CH04 16 16 16 16 16
CH05 16 14 14 16 16 16 CH05 16 16 16 16 16
CH06 16 14 14 16 16 16 CH06 16 16 16 16 16
CH07 16 14 14 16 16 16 CH07 16 16 16 16 16
CH08 16 14 14 16 16 16 CH08 16 16 16 16 16
CH09 16 14 14 16 16 16 CH09 16 16 16 16 16
CH10 16 14 14 16 16 16 CH10 16 16 16 16 16
CH11 16 14 14 16 16 16 CH11 16 16 16 16 16
CH12 15 14 14 16 16 12 CH12 12 12 12 12 12
CH13 13 14 14 16 16 12 CH13 12 12 12 12 12
CH14 NA NA NA 16 NA 12 CH14 NA NA NA 12 12
## END ## END
# Table 2: # Table 2:
## 2.4G, 40M,#6# ## 2.4G, 40M,#5#
## START ## START
## SRRC FCC ETSI JP KCC UNSET ## SRRC FCC ETSI JP UNSET
CH01 NA NA NA NA NA NA CH01 NA NA NA NA NA
CH02 NA NA NA NA NA NA CH02 NA NA NA NA NA
CH03 16 13 14 16 16 16 CH03 16 16 16 16 16
CH04 16 13 14 16 16 16 CH04 16 16 16 16 16
CH05 16 13 14 16 16 16 CH05 16 16 16 16 16
CH06 16 13 14 16 16 16 CH06 16 16 16 16 16
CH07 16 13 14 16 16 16 CH07 16 16 16 16 16
CH08 16 13 14 16 16 16 CH08 16 16 16 16 16
CH09 16 11 14 16 16 16 CH09 16 16 16 16 16
CH10 16 11 14 16 16 16 CH10 16 16 16 16 16
CH11 16 11 14 16 16 16 CH11 16 16 16 16 16
CH12 NA NA NA NA NA NA CH12 NA NA NA NA NA
CH13 NA NA NA NA NA NA CH13 NA NA NA NA NA
CH14 NA NA NA NA NA NA CH14 NA NA NA NA NA
## END ## END
# Table 3: # Table 3:
## 5G, 20M,#6# ## 5G, 20M,#5#
## START ## START
## SRRC FCC ETSI JP KCC UNSET ## SRRC FCC ETSI JP UNSET
# 5G Band 1 # 5G Band 1
CH36 15 16 16 16 16 15 CH36 15 16 16 16 15
CH40 15 16 16 16 16 15 CH40 15 16 16 16 15
CH44 15 16 16 16 16 15 CH44 15 16 16 16 15
CH48 15 16 16 16 16 15 CH48 15 16 16 16 15
# 5G Band 2 # 5G Band 2
CH52 15 16 16 16 16 15 CH52 15 16 16 16 15
CH56 15 16 16 16 16 15 CH56 15 16 16 16 15
CH60 15 16 16 16 16 15 CH60 15 16 16 16 15
CH64 15 16 16 16 16 15 CH64 15 16 16 16 15
# 5G Band 3 # 5G Band 3
CH100 NA 16 16 16 16 15 CH100 NA 16 16 16 15
CH104 NA 16 16 16 16 15 CH104 NA 16 16 16 15
CH108 NA 16 16 16 16 15 CH108 NA 16 16 16 15
CH112 NA 16 16 16 16 15 CH112 NA 16 16 16 15
CH116 NA 16 16 16 16 15 CH116 NA 16 16 16 15
CH120 NA 16 16 16 16 15 CH120 NA 16 16 16 15
CH124 NA 16 16 16 16 15 CH124 NA 16 16 16 15
CH128 NA 16 16 16 16 15 CH128 NA 16 16 16 15
CH132 NA 16 16 16 16 15 CH132 NA 16 16 16 15
CH136 NA 16 16 16 16 15 CH136 NA 16 16 16 15
CH140 NA 16 16 16 16 15 CH140 NA 16 16 16 15
CH144 NA NA 16 16 16 15 CH144 NA NA 16 16 15
# 5G Band 4 # 5G Band 4
CH149 20 16 8 NA 20 11 CH149 16 16 11 NA 11
CH153 20 16 8 NA 20 11 CH153 16 16 11 NA 11
CH157 20 16 8 NA 20 11 CH157 16 16 11 NA 11
CH161 20 16 8 NA 20 11 CH161 16 16 11 NA 11
CH165 20 16 8 NA 20 11 CH165 16 16 11 NA 11
## END ## END
# Table 4: # Table 4:
## 5G, 40M,#6# ## 5G, 40M,#5#
## START ## START
## SRRC FCC ETSI JP KCC UNSET ## SRRC FCC ETSI JP UNSET
# 5G Band 1 # 5G Band 1
CH38 15 16 16 16 20 15 CH38 15 16 16 16 15
CH46 15 16 16 16 20 15 CH46 15 16 16 16 15
# 5G Band 2 # 5G Band 2
CH54 15 16 16 16 20 15 CH54 15 16 16 16 15
CH62 15 16 16 16 20 15 CH62 15 16 16 16 15
# 5G Band 3 # 5G Band 3
CH102 NA 16 16 16 20 15 CH102 NA 16 16 16 15
CH110 NA 16 16 16 20 15 CH110 NA 16 16 16 15
CH118 NA 16 16 16 20 15 CH118 NA 16 16 16 15
CH126 NA 16 16 16 20 15 CH126 NA 16 16 16 15
CH134 NA 16 16 16 20 15 CH134 NA 16 16 16 15
CH142 NA 16 NA 16 20 15 CH142 NA 16 NA 16 15
# 5G Band 4 # 5G Band 4
CH151 16 15 8 NA 18 11 CH151 16 16 11 NA 11
CH159 17 16 8 NA 17 11 CH159 16 16 11 NA 11
## END ## END
# Table 5: # Table 5:
## 5G, 80M,#6# ## 5G, 80M,#5#
## START ## START
## SRRC FCC ETSI JP KCC UNSET ## SRRC FCC ETSI JP UNSET
# 5G Band 1 # 5G Band 1
CH42 15 16 16 16 20 15 CH42 15 16 16 16 15
# 5G Band 2 # 5G Band 2
CH58 15 16 16 16 20 15 CH58 15 16 16 16 15
# 5G Band 3 # 5G Band 3
CH106 NA 16 16 16 20 15 CH106 NA 16 16 16 15
CH122 NA 16 16 16 20 15 CH122 NA 16 16 16 15
CH138 NA 16 NA NA 20 15 CH138 NA 16 NA NA 15
# 5G Band 4 # 5G Band 4
CH155 15 14 8 NA 16 11 CH155 16 16 11 NA 11
## END ## END
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+121
View File
@@ -0,0 +1,121 @@
# AIC8800D80 legacy MCU revision 1 support
The `legacy-mcu1` branch is the maintained compatibility profile for the older
AIC8800D80 MCU revision tracked in
[issue #58](https://github.com/shenmintao/aic8800d80/issues/58), with related
reports in issues #14, #64, and #65. It is intended only for devices that log:
```text
chip_id=7, chip_mcu_id=1
```
Affected adapters have been observed entering through `a69c:572f` or a similar
mass-storage ID, changing to `a69c:8d80` for firmware loading, and failing when
the SDK V5 FMAC upload reaches address `0x170400`.
## Root cause
The affected MCU revision cannot accept the complete SDK V5 FMAC image in its
available upload window. With an upload base of `0x120000`, the deterministic
failure at `0x170400` gives a limit of about `0x50400` (328,704) bytes.
| Firmware | Size | End address (exclusive) | Relative to `0x170400` |
| --- | ---: | ---: | ---: |
| SDK V5 FMAC on `main` | 358,072 bytes | `0x1776B8` | 29,368 bytes over |
| SDK V3 FMAC on this branch | 327,037 bytes | `0x16FD7D` | 1,667 bytes free |
Replacing only the FMAC image is not sufficient. Earlier mixed-firmware tests
could enumerate but failed to provide a usable radio. This branch therefore
uses the complete matching AIC8800D80 firmware set from Radxa SDK V3, fixed at
upstream commit
[`254d47e6a131dbed5ba32131972f4719f3e1c7fe`](https://github.com/radxa-pkg/aic8800/commit/254d47e6a131dbed5ba32131972f4719f3e1c7fe),
together with its matching FMAC patch table and fixed patch-buffer layout.
For `chip_mcu_id=1`, the loader also reads register `0x40100020`, sets bit 0,
and writes it back before firmware upload. This is the MCU1 Bluetooth cache fix
identified in [PR #35](https://github.com/shenmintao/aic8800d80/pull/35).
Bluetooth continues to use the kernel's standard `btusb` driver; this branch
does not contain or install `aic_btusb`.
Firmware and loader paths for D80N, D80X2, and other variants are unchanged.
The same branch now also carries the separately validated legacy DC/DW profile
documented in the [issue #71 support notes](../issue71-mcu1-v3-profile/README.md).
## Hardware validation
The final profile was validated on a Steren COM-8231+ reporting
`chip_id=7, chip_mcu_id=1`. Test commit
[`027a7a8`](https://github.com/shenmintao/aic8800d80/commit/027a7a8)
demonstrated all of the following:
- the 327,037-byte FMAC uploads completely without `cmd timed-out` or
`bin upload fail: 170400`;
- the adapter completes `a69c:572f -> a69c:8d80 -> a69c:8d81` enumeration;
- 2.4 GHz and 5 GHz Wi-Fi scan, association, DHCP, and traffic work;
- USB interfaces 0 and 1 bind to system `btusb`, while interface 2 binds to
`aic8800_fdrv`;
- the earlier HCI Reset timeout `Opcode 0x0c03 failed: -110` is gone;
- Bluetooth scan and a real connection both succeed.
## Install
From an existing clone:
```bash
git fetch origin
git switch legacy-mcu1
git pull --ff-only
sudo ./install.sh
sudo reboot
```
The installer replaces the installed AIC firmware. Switching Git branches
without rerunning `install.sh` does not change the active firmware.
The expected V3 FMAC can be confirmed with:
```bash
stat -c '%s bytes' /lib/firmware/aic8800D80/fmacfw_8800d80_u02.bin
sha256sum /lib/firmware/aic8800D80/fmacfw_8800d80_u02.bin
```
Expected output:
```text
327037 bytes
1ec680c2b63dcaa0e5d33c5fb6d1857d030f8145c05c385e243760388a61a0da
```
## Verify
After reboot or a physical disconnect/reconnect, check the complete device:
```bash
sudo dmesg | grep -iE 'AIC8800D80|chip_id|chip_mcu_id|fmacfw|bin upload|cmd timed-out|Bluetooth|0x0c03|error -110'
lsusb -t
iw dev
bluetoothctl list
```
The initialization log should contain:
```text
AIC8800D80 legacy: using Radxa SDK V3 loader profile
AIC8800D80 MCU1: enabled Bluetooth cache fix
```
`lsusb -t` should show Bluetooth interfaces using `btusb` and the Wi-Fi
interface using `aic8800_fdrv`. Verify traffic through the AIC network interface
rather than an onboard Wi-Fi adapter or phone/RNDIS connection.
## Return to current firmware
Newer `chip_mcu_id=0` hardware should use `main`. Reinstall after switching so
that the V5 firmware is restored under `/lib/firmware`:
```bash
git switch main
git pull --ff-only
sudo ./install.sh
sudo reboot
```
+77
View File
@@ -0,0 +1,77 @@
# AIC8800DC/DW legacy MCU revision 1 support
The `legacy-mcu1` branch is the maintained compatibility profile for older
AIC8800DC/DW devices tracked in
[issue #71](https://github.com/shenmintao/aic8800d80/issues/71). It follows the
same method as the successful issue #58 D80 profile: use a complete, matched
legacy firmware and loader rather than mixing firmware generations.
The branch keeps the current USB transport, cfg80211 integration, device IDs,
DKMS installer, and modern-kernel compatibility. For AIC8800DC/DW it restores
the complete firmware directory and matching loader from immediately before
SDK V5 commit `d66e5cb`. That loader includes the MCU1 cache fix and flash DPD
validation used by the reporter's previously working driver.
The first issue #71 test proved that the DPD result stored in flash was valid,
but the V5 main application still timed out at `DBG_START_APP_REQ`. Test commit
[`dbfbfa0`](https://github.com/shenmintao/aic8800d80/commit/dbfbfa0) restored the
complete profile matching the reporter's known-good firmware hashes, after
which the reporter confirmed that the TX1U Nano worked.
## Install
```bash
git fetch origin
git switch legacy-mcu1
git pull --ff-only
sudo ./install.sh
sudo poweroff
```
After shutdown, unplug the TX1U Nano or remove host power for at least 10
seconds before reconnecting and booting.
## Verify
```bash
git rev-parse --short HEAD
md5sum /lib/firmware/aic8800DC/fmacfw_patch_8800dc_u02.bin
md5sum /lib/firmware/aic8800DC/fmacfw_patch_tbl_8800dc_u02.bin
lsusb
lsusb -t
iw dev
sudo journalctl -k -b --no-pager | tee issue71-v3-profile.log
sudo journalctl -k -b --no-pager | grep -iE 'issue71|chip_id|chip_mcu_id|chip_sub_id|DPD|calib|patch.*tbl|start app|firmware version|interface|wlan|timed-out|err_lmac'
```
Expected firmware values and log markers include:
```text
bfd8ea1d174242e7ec823813b6c5d849 fmacfw_patch_8800dc_u02.bin
7b5fde609392c2e6c2c5874838dda718 fmacfw_patch_tbl_8800dc_u02.bin
chip_id=7, chip_mcu_id=1, chip_sub_id=1
issue71: using complete pre-SDK-V5/V3 DC/DW firmware and loader profile
issue71: legacy V3 flash DPD result is valid
misc ram valid, skip calib process
FMACFW_PATCH_TBL_8800DC_U02_DESCRIBE_BASE = 187c00
Start app: 00150000, 5
Firmware Version: ...
New interface create wlan0
```
There should be no command timeout, `err_lmac_reqs`, or failed USB probe after
the main application starts.
Confirm scanning, association, DHCP, gateway and Internet reachability, real
traffic, and clean initialization after a USB unplug/replug cycle.
## Roll back
```bash
git switch main
git pull --ff-only
sudo ./install.sh
sudo poweroff
```
Cold-power-cycle the adapter again before booting the rollback result.
-44
View File
@@ -1,44 +0,0 @@
# OpenWrt backports build regression
This checks complete module compilation and MODPOST against real kernel and
wireless-stack headers. It requires an already prepared SDK/buildroot with
cfg80211/mac80211 headers and `mac80211.symvers` staged. It does not install
packages or load modules.
For the x86_64 SDK used in issue #94:
```sh
sdk=/path/to/openwrt-sdk
kernel="$sdk/build_dir/target-x86_64_musl/linux-x86_64/linux-6.12.94"
export STAGING_DIR="$sdk/staging_dir/target-x86_64_musl"
export PATH="$sdk/staging_dir/toolchain-x86_64_gcc-14.3.0_musl/bin:$PATH"
bash tests/openwrt-backports/build.sh \
"$kernel" "$STAGING_DIR/usr/include" \
"$kernel/../symvers/mac80211.symvers" 6.18.26 \
ARCH=x86_64 CROSS_COMPILE=x86_64-openwrt-linux-musl-
```
The script copies the current driver into a fresh temporary directory and
checks that all three `.ko` files are produced. Additional make arguments
can select a compiler or architecture. Use matching headers, configuration
and symbol versions throughout; changing only the version argument is not
a substitute for the matching wireless stack.
## Verified on 2026-09-17
- OpenWrt 25.12.5 x86_64 SDK: Linux 6.12.94, GCC 14.3.0, backports 6.18.26
with the mac80211 patches from OpenWrt revision `f5dae5ece4` applied:
all three modules compile and pass MODPOST with the kernel's `-Werror`.
- Original driver revision `9594c5c`, on the same kernel/backports combination:
reproduces both RX argument-count errors and the four incompatible
`set_monitor_channel`, `set_wiphy_params`, `set_tx_power`, `get_tx_power`
callbacks. This comparison uses `-Wno-error=unused-label`, as the issue's
log does, to reach those failures. The fixed build needs no such override.
- Native kernel headers 6.11.0-17, 6.17.0-14 and 7.2.0-070200, with
`CFG80211_VERSION` unset: all three modules compile and pass MODPOST.
The 7.2 check uses GCC 14 and reports compiler/attribute warnings because
those headers were built with GCC 15.
These are build checks. They do not validate an installable OpenWrt package,
firmware loading, Wi-Fi connectivity or Bluetooth operation on hardware.
-41
View File
@@ -1,41 +0,0 @@
#!/usr/bin/env bash
# Compile a source copy against a prepared kernel and staged wireless backport.
# Leaves the build directory for inspection; does not install or load modules.
set -euo pipefail
if [ "$#" -lt 4 ]; then
echo "Usage: $0 KERNEL_BUILD_DIR STAGED_INCLUDE_DIR MAC80211_SYMVERS CFG80211_VERSION [make arguments...]" >&2
exit 2
fi
kernel_dir=$(realpath "$1")
include_dir=$(realpath "$2")
symvers=$(realpath "$3")
wireless_version=$4
shift 4
for required in "$kernel_dir/Makefile" "$kernel_dir/Module.symvers" \
"$include_dir/mac80211/net/cfg80211.h" \
"$include_dir/mac80211-backport/backport/autoconf.h" "$symvers"; do
if [ ! -f "$required" ]; then
echo "Missing build input: $required" >&2
exit 2
fi
done
repo_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/aic8800-backports.XXXXXX")
cp -a "$repo_dir/drivers/aic8800/." "$build_dir/"
echo "Build directory: $build_dir"
make -C "$kernel_dir" M="$build_dir" \
NOSTDINC_FLAGS="-I$include_dir/mac80211-backport/uapi -I$include_dir/mac80211-backport -I$include_dir/mac80211/uapi -I$include_dir/mac80211 -include backport/backport.h" \
KBUILD_EXTRA_SYMBOLS="$symvers" \
CFG80211_VERSION="$wireless_version" \
-j"${JOBS:-2}" "$@" modules
for module in aic_load_fw/aic_load_fw.ko aic8800_fdrv/aic8800_fdrv.ko \
aic_zlp_quirk/aic_zlp_quirk.ko; do
test -s "$build_dir/$module"
done
echo "All three modules built successfully in $build_dir"
+3 -5
View File
@@ -2,8 +2,8 @@
# Sends vendor-specific SCSI CDB to trigger mode switch from # Sends vendor-specific SCSI CDB to trigger mode switch from
# USB Mass Storage to WiFi+BT mode. # USB Mass Storage to WiFi+BT mode.
# #
# The two 16-byte CDBs end in F3 and F2 respectively. Each is wrapped in a # The 16-byte CDB is: FD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F2
# standard 31-byte SCSI CBW (Command Block Wrapper), and must be sent in order. # Wrapped in a standard 31-byte SCSI CBW (Command Block Wrapper).
# #
# Install as: /etc/usb_modeswitch.d/1111:1111 # Install as: /etc/usb_modeswitch.d/1111:1111
# (The filename must contain a colon on Linux; this file is named # (The filename must contain a colon on Linux; this file is named
@@ -13,6 +13,4 @@ DefaultVendor=0x1111
DefaultProduct=0x1111 DefaultProduct=0x1111
TargetVendor=0xa69c TargetVendor=0xa69c
TargetProduct=0x8d80 TargetProduct=0x8d80
MessageContent="555342438765432100000000000010fd0000000000000000000000000000f3" MessageContent="555342438765432100000000000010fd0000000000000000000000000000f2"
MessageContent2="555342438765432100000000000010fd0000000000000000000000000000f2"
NeedResponse=1