mirror of
https://github.com/shenmintao/aic8800d80.git
synced 2026-09-27 01:54:16 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bef3cc252f | ||
|
|
d9688590c2 | ||
|
|
4902793c01 |
-67
@@ -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.
|
|
||||||
@@ -47,32 +47,8 @@ I did not develop this software, The code is sourced from the Tenda U11 driver.
|
|||||||
### Attention
|
### Attention
|
||||||
Before installing the driver, delete all aic8800-related folders under /lib/firmware. Using an incorrect firmware version may cause the system to freeze.
|
Before installing the driver, delete all aic8800-related folders under /lib/firmware. Using an incorrect firmware version may cause the system to freeze.
|
||||||
|
|
||||||
#### Pandora 88M80 mode switching
|
|
||||||
|
|
||||||
Pandora 88M80 adapters that initially appear as USB device `1111:1111` are
|
|
||||||
automatically switched to `a69c:8d80` by sending the required `F3` then `F2`
|
|
||||||
commands. Existing users must rerun `sudo ./install.sh` to replace the installed
|
|
||||||
usb_modeswitch configuration, then unplug the adapter completely and plug it
|
|
||||||
back in.
|
|
||||||
|
|
||||||
If automatic switching does not occur, try the same sequence manually:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo usb_modeswitch -v 1111 -p 1111 \
|
|
||||||
-M "555342438765432100000000000010fd0000000000000000000000000000f3" \
|
|
||||||
-2 "555342438765432100000000000010fd0000000000000000000000000000f2"
|
|
||||||
```
|
|
||||||
|
|
||||||
This only addresses switching from `1111:1111` to `a69c:8d80`. If the device
|
|
||||||
has reached `a69c:8d80` but firmware startup still fails, see
|
|
||||||
[issue #79](https://github.com/shenmintao/aic8800d80/issues/79).
|
|
||||||
|
|
||||||
### Installation Steps
|
### Installation Steps
|
||||||
|
|
||||||
For OpenWrt SDK/buildroot builds, see [OpenWrt build notes](OPENWRT.md).
|
|
||||||
OpenWrt can use a newer cfg80211 backport than its target kernel; these builds
|
|
||||||
must pass the wireless stack version separately.
|
|
||||||
|
|
||||||
#### Method 1: [Quick Installation](INSTALL_SCRIPT.md) (Recommended)
|
#### Method 1: [Quick Installation](INSTALL_SCRIPT.md) (Recommended)
|
||||||
|
|
||||||
#### Method 2: Manual Installation
|
#### Method 2: Manual Installation
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
+3
-23
@@ -1,14 +1,9 @@
|
|||||||
%global commit c8327eab5be246d4b517afdba034775f00afa988
|
%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,21 +77,6 @@ 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^20260924gitc8327ea-1
|
|
||||||
- Version snapshots as 1.0.0^<date>git<commit> with Epoch 1. The previous
|
|
||||||
commit-hash versions do not sort in commit order, so rpm could treat a
|
|
||||||
newer snapshot as an older package.
|
|
||||||
|
|
||||||
* Thu Sep 24 2026 Shen Mintao <shenmintao@gmail.com> - c8327ea-1
|
|
||||||
- Build the current legacy-mcu1 branch, which carries the Linux 7.2
|
|
||||||
cfg80211 and strncpy() fixes needed to compile on Bazzite 44.
|
|
||||||
- Include the monitor packet injection path and the 6.12 stable
|
|
||||||
set_monitor_channel() fix synchronized from main.
|
|
||||||
|
|
||||||
* Wed Jul 29 2026 Shen Mintao <shenmintao@gmail.com> - 51b7b6e-2
|
|
||||||
- Disable automatic debug package generation for Bazzite builds.
|
|
||||||
- Require usb_modeswitch by package name for rpm-ostree dependency resolution.
|
|
||||||
|
|
||||||
* Sat Jul 25 2026 Shen Mintao <shenmintao@gmail.com> - 51b7b6e-1
|
* Sat Jul 25 2026 Shen Mintao <shenmintao@gmail.com> - 51b7b6e-1
|
||||||
- Package the unified installer and ZLP quirk with the legacy MCU1 profiles.
|
- Package the unified installer and ZLP quirk with the legacy MCU1 profiles.
|
||||||
- Preserve the matched D80 and DC/DW firmware and loader combinations.
|
- Preserve the matched D80 and DC/DW firmware and loader combinations.
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -2942,7 +2942,7 @@ bool key_flag = false;
|
|||||||
* when adding a group key.
|
* when adding a group key.
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
|
static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
|
||||||
#if 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,
|
||||||
@@ -2954,7 +2954,7 @@ static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
|
|||||||
struct key_params *params)
|
struct key_params *params)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
#if 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);
|
||||||
@@ -3066,7 +3066,7 @@ static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_get_key(struct wiphy *wiphy,
|
static int rwnx_cfg80211_get_key(struct wiphy *wiphy,
|
||||||
#if 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,
|
||||||
@@ -3090,7 +3090,7 @@ static int rwnx_cfg80211_get_key(struct wiphy *wiphy,
|
|||||||
* and @key_index, return -ENOENT if the key doesn't exist.
|
* and @key_index, return -ENOENT if the key doesn't exist.
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_del_key(struct wiphy *wiphy,
|
static int rwnx_cfg80211_del_key(struct wiphy *wiphy,
|
||||||
#if 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,
|
||||||
@@ -3102,7 +3102,7 @@ static int rwnx_cfg80211_del_key(struct wiphy *wiphy,
|
|||||||
u8 key_index, bool pairwise, const u8 *mac_addr)
|
u8 key_index, bool pairwise, const u8 *mac_addr)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
#if 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);
|
||||||
@@ -3154,7 +3154,7 @@ static int rwnx_cfg80211_set_default_key(struct wiphy *wiphy,
|
|||||||
* @set_default_mgmt_key: set the default management frame key on an interface
|
* @set_default_mgmt_key: set the default management frame key on an interface
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
|
static int rwnx_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
|
||||||
#if 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,
|
||||||
@@ -3249,7 +3249,7 @@ static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
|||||||
key_params.seq_len = 0;
|
key_params.seq_len = 0;
|
||||||
key_params.cipher = sme->crypto.cipher_group;
|
key_params.cipher = sme->crypto.cipher_group;
|
||||||
rwnx_cfg80211_add_key(wiphy,
|
rwnx_cfg80211_add_key(wiphy,
|
||||||
#if 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,
|
||||||
@@ -3480,7 +3480,7 @@ static int rwnx_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *d
|
|||||||
* @add_station: Add a new station.
|
* @add_station: Add a new station.
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
||||||
#if 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,
|
||||||
@@ -3493,7 +3493,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
|||||||
struct station_parameters *params)
|
struct station_parameters *params)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
#if 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);
|
||||||
@@ -3589,7 +3589,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
|||||||
sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
|
sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
|
||||||
#endif
|
#endif
|
||||||
cfg80211_new_sta(
|
cfg80211_new_sta(
|
||||||
#if 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,
|
||||||
@@ -3620,7 +3620,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
|||||||
(params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "")
|
(params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "")
|
||||||
|
|
||||||
netdev_info(
|
netdev_info(
|
||||||
#if 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,
|
||||||
@@ -3651,7 +3651,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
|||||||
* @del_station: Remove a station
|
* @del_station: Remove a station
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
||||||
#if 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,
|
||||||
@@ -3666,7 +3666,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
#if 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);
|
||||||
@@ -3711,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,
|
||||||
@@ -3731,7 +3731,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
|||||||
}
|
}
|
||||||
if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP || rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
|
if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP || rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
|
||||||
cfg80211_del_sta(
|
cfg80211_del_sta(
|
||||||
#if 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,
|
||||||
@@ -3962,7 +3962,7 @@ void apm_probe_sta_work_process(struct work_struct *work)
|
|||||||
* cfg80211_check_station_change() to validate the information.
|
* cfg80211_check_station_change() to validate the information.
|
||||||
*/
|
*/
|
||||||
static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
||||||
#if 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,
|
||||||
@@ -3975,7 +3975,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
|||||||
struct station_parameters *params)
|
struct station_parameters *params)
|
||||||
{
|
{
|
||||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
#if 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);
|
||||||
@@ -3988,7 +3988,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
|||||||
/* Add the TDLS station */
|
/* Add the TDLS station */
|
||||||
if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
|
if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
|
||||||
{
|
{
|
||||||
#if 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);
|
||||||
@@ -4064,7 +4064,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
|||||||
(params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "")
|
(params->sta_flags_set & BIT(NL80211_STA_FLAG_##f) ? "["#f"]" : "")
|
||||||
|
|
||||||
netdev_info(
|
netdev_info(
|
||||||
#if 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,
|
||||||
@@ -4353,7 +4353,7 @@ static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
|
|||||||
/* delete any remaining STA*/
|
/* delete any remaining STA*/
|
||||||
while (!list_empty(&rwnx_vif->ap.sta_list)) {
|
while (!list_empty(&rwnx_vif->ap.sta_list)) {
|
||||||
rwnx_cfg80211_del_station_compat(wiphy,
|
rwnx_cfg80211_del_station_compat(wiphy,
|
||||||
#if 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,
|
||||||
@@ -4420,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;
|
||||||
@@ -4479,19 +4495,40 @@ 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
|
||||||
|
|
||||||
@@ -4553,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,
|
||||||
@@ -4570,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)
|
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)
|
||||||
{
|
{
|
||||||
#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;
|
||||||
@@ -4607,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
|
||||||
@@ -4857,17 +5012,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)
|
||||||
enum nl80211_channel_type channel_type,
|
enum nl80211_channel_type channel_type,
|
||||||
#endif
|
#endif
|
||||||
unsigned int duration, u64 *cookie
|
unsigned int duration, u64 *cookie)
|
||||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 2, 0)
|
|
||||||
/*
|
|
||||||
* 7.2 added an optional receive address filter for the off-channel
|
|
||||||
* period. cfg80211 refuses a non-NULL one unless the driver sets
|
|
||||||
* NL80211_EXT_FEATURE_ROC_ADDR_FILTER, which this one does not, so it
|
|
||||||
* is always NULL here. mac80211 ignores it in the same way.
|
|
||||||
*/
|
|
||||||
, const u8 *rx_addr
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return rwnx_cfg80211_remain_on_channel_(wiphy,
|
return rwnx_cfg80211_remain_on_channel_(wiphy,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
|
||||||
@@ -5009,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
|
||||||
@@ -5200,17 +5341,28 @@ send_frame:
|
|||||||
/**
|
/**
|
||||||
* @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);
|
||||||
@@ -5218,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) {
|
||||||
@@ -5238,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
|
||||||
@@ -5991,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,
|
||||||
@@ -6003,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);
|
||||||
@@ -6041,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);
|
||||||
@@ -6530,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,
|
||||||
@@ -6551,20 +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,
|
||||||
.probe_client = rwnx_cfg80211_probe_client,
|
.probe_client = rwnx_cfg80211_probe_client,
|
||||||
// .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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
|
||||||
&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);
|
|
||||||
#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,
|
NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
|
||||||
#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);
|
|
||||||
#endif
|
|
||||||
rwnx_chanctx_unlink(radar->cac_vif);
|
rwnx_chanctx_unlink(radar->cac_vif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -1991,7 +1991,7 @@ free_use:
|
|||||||
|
|
||||||
netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev)
|
netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
int rtap_len, ret, idx;
|
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;
|
||||||
@@ -2012,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);
|
||||||
@@ -2043,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;
|
||||||
|
|
||||||
|
|||||||
@@ -172,8 +172,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
|||||||
u64 *cookie);
|
u64 *cookie);
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||||
#ifdef CONFIG_RWNX_MON_XMIT
|
#ifdef CONFIG_RWNX_MON_XMIT
|
||||||
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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
|
||||||
@@ -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"
|
|
||||||
@@ -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
|
|
||||||
Reference in New Issue
Block a user