mirror of
https://github.com/shenmintao/aic8800d80.git
synced 2026-09-26 17:44:16 +00:00
Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
332677e771 | ||
|
|
a86affa3c6 | ||
|
|
6229bf3c7e | ||
|
|
c8327eab5b | ||
|
|
b0ef216ed8 | ||
|
|
0dfe7588fc | ||
|
|
40f1d081e9 | ||
|
|
966de5e878 | ||
|
|
4b717f4048 | ||
|
|
0e56f1a1f8 | ||
|
|
8378d2ce34 | ||
|
|
2384dbe450 | ||
|
|
8cbefea252 | ||
|
|
655c14f9f3 | ||
|
|
44748e193a | ||
|
|
35f32c238c | ||
|
|
1b7c44ddd4 | ||
|
|
5ea5196eea | ||
|
|
fffad12a26 | ||
|
|
95d889d961 |
+67
@@ -0,0 +1,67 @@
|
||||
# Building with OpenWrt backports
|
||||
|
||||
OpenWrt's target kernel and wireless stack can have different versions.
|
||||
For example, [issue #94](https://github.com/shenmintao/aic8800d80/issues/94)
|
||||
uses Linux **6.12.94** with **backports 6.18.26** on OpenWrt 25.12.5.
|
||||
The Ubuntu build host's kernel version is not used to select these APIs.
|
||||
|
||||
## Package Makefile
|
||||
|
||||
Pass `CFG80211_VERSION=6.18.26` to the kernel make invocation for that
|
||||
combination. Use the `PKG_VERSION` from your OpenWrt
|
||||
`package/kernel/mac80211/Makefile`, in `major.minor.patch` format. Keep the
|
||||
backports include paths and symbol versions from the same build:
|
||||
|
||||
```make
|
||||
NOSTDINC_FLAGS := \
|
||||
$(KERNEL_NOSTDINC_FLAGS) \
|
||||
-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
|
||||
-I$(STAGING_DIR)/usr/include/mac80211-backport \
|
||||
-I$(STAGING_DIR)/usr/include/mac80211/uapi \
|
||||
-I$(STAGING_DIR)/usr/include/mac80211 \
|
||||
-include backport/backport.h
|
||||
|
||||
define Build/Compile
|
||||
+$(KERNEL_MAKE) $(PKG_JOBS) \
|
||||
M="$(PKG_BUILD_DIR)/drivers/aic8800" \
|
||||
KBUILD_EXTRA_SYMBOLS="$(LINUX_DIR)/../symvers/mac80211.symvers" \
|
||||
NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
|
||||
CFG80211_VERSION=6.18.26 \
|
||||
modules
|
||||
endef
|
||||
```
|
||||
|
||||
The package must depend on `kmod-cfg80211` so its headers and symbol versions
|
||||
are staged before this driver is built. Keep any additional dependencies,
|
||||
firmware installation rules and module packaging rules your device needs.
|
||||
Update the package's pinned source revision to one containing this fix, or
|
||||
apply the fix as an OpenWrt package patch, then clean and rebuild the package:
|
||||
|
||||
```sh
|
||||
make package/kernel/aic8800d80/clean
|
||||
make package/kernel/aic8800d80/compile V=sc -j1
|
||||
```
|
||||
|
||||
Changing `CFG80211_VERSION` alone does not update the driver source or the
|
||||
wireless headers. The value must match the actual wireless stack; do not set
|
||||
it to the host kernel version or redefine `LINUX_VERSION_CODE`.
|
||||
|
||||
## Compatibility scope
|
||||
|
||||
The override selects the wireless API changes since Linux 6.12, including
|
||||
monitor-channel callbacks, radio/link arguments, radar notifications and
|
||||
newer cfg80211 callbacks. Timer, USB, memory-management and module namespace
|
||||
checks continue to use the target kernel version. Older target kernels with
|
||||
newer backports may need additional wireless API adaptations.
|
||||
|
||||
Leave `CFG80211_VERSION` unset when building against the kernel's own wireless
|
||||
stack, as on a regular Ubuntu/Debian installation. The driver then uses the
|
||||
kernel version as before. Hardware revision still determines whether to use
|
||||
`main` or `legacy-mcu1`; a wireless API mismatch does not change that choice.
|
||||
|
||||
The feeds/Kconfig duplicate definitions and recursive dependencies also
|
||||
reported in issue #94 belong to the OpenWrt build configuration and require
|
||||
separate investigation.
|
||||
|
||||
See the [build regression recipe](tests/openwrt-backports/README.md) for
|
||||
the tested kernel/backports combinations and a script to repeat the build.
|
||||
@@ -47,8 +47,32 @@ I did not develop this software, The code is sourced from the Tenda U11 driver.
|
||||
### Attention
|
||||
Before installing the driver, delete all aic8800-related folders under /lib/firmware. Using an incorrect firmware version may cause the system to freeze.
|
||||
|
||||
#### Pandora 88M80 mode switching
|
||||
|
||||
Pandora 88M80 adapters that initially appear as USB device `1111:1111` are
|
||||
automatically switched to `a69c:8d80` by sending the required `F3` then `F2`
|
||||
commands. Existing users must rerun `sudo ./install.sh` to replace the installed
|
||||
usb_modeswitch configuration, then unplug the adapter completely and plug it
|
||||
back in.
|
||||
|
||||
If automatic switching does not occur, try the same sequence manually:
|
||||
|
||||
```bash
|
||||
sudo usb_modeswitch -v 1111 -p 1111 \
|
||||
-M "555342438765432100000000000010fd0000000000000000000000000000f3" \
|
||||
-2 "555342438765432100000000000010fd0000000000000000000000000000f2"
|
||||
```
|
||||
|
||||
This only addresses switching from `1111:1111` to `a69c:8d80`. If the device
|
||||
has reached `a69c:8d80` but firmware startup still fails, see
|
||||
[issue #79](https://github.com/shenmintao/aic8800d80/issues/79).
|
||||
|
||||
### Installation Steps
|
||||
|
||||
For OpenWrt SDK/buildroot builds, see [OpenWrt build notes](OPENWRT.md).
|
||||
OpenWrt can use a newer cfg80211 backport than its target kernel; these builds
|
||||
must pass the wireless stack version separately.
|
||||
|
||||
#### Method 1: [Quick Installation](INSTALL_SCRIPT.md) (Recommended)
|
||||
|
||||
#### Method 2: Manual Installation
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# AIC8800 USB mass-storage mode switch rules
|
||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k"
|
||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5722", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k"
|
||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5723", SYMLINK+="tendaudisk", RUN+="/usr/bin/eject /dev/%k"
|
||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5724", SYMLINK+="ugreenax900", RUN+="/usr/bin/eject /dev/%k"
|
||||
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5725", SYMLINK+="tendaudiskv2", RUN+="/usr/bin/eject /dev/%k"
|
||||
|
||||
+23
-3
@@ -1,9 +1,14 @@
|
||||
%global commit 51b7b6e72989afe4d21f52e55b70f5a4d6b21e5b
|
||||
%global commit c8327eab5be246d4b517afdba034775f00afa988
|
||||
%global shortcommit %(echo %{commit} | cut -c1-7)
|
||||
%global snapdate 20260924
|
||||
%global debug_package %{nil}
|
||||
%{!?kver:%global kver %(uname -r)}
|
||||
|
||||
Name: aic8800d80
|
||||
Version: %{shortcommit}
|
||||
# Versions before 2026-09-24 were bare commit hashes, which rpm does not
|
||||
# order by commit history. Epoch 1 sorts every snapshot version after them.
|
||||
Epoch: 1
|
||||
Version: 1.0.0^%{snapdate}git%{shortcommit}
|
||||
Release: 1%{?dist}
|
||||
Summary: AIC8800 USB Wi-Fi, Bluetooth firmware, and ZLP quirk driver
|
||||
|
||||
@@ -17,7 +22,7 @@ BuildRequires: kernel-devel-uname-r = %{kver}
|
||||
|
||||
Requires: kernel-uname-r = %{kver}
|
||||
Requires: /usr/bin/eject
|
||||
Requires: /usr/sbin/usb_modeswitch
|
||||
Requires: usb_modeswitch
|
||||
Requires(post): /usr/sbin/depmod
|
||||
Requires(postun): /usr/sbin/depmod
|
||||
|
||||
@@ -77,6 +82,21 @@ cp -a fw/aic8800* %{buildroot}/usr/lib/firmware/
|
||||
/usr/lib/firmware/aic8800*
|
||||
|
||||
%changelog
|
||||
* Thu Sep 24 2026 Shen Mintao <shenmintao@gmail.com> - 1:1.0.0^20260924gitc8327ea-1
|
||||
- Version snapshots as 1.0.0^<date>git<commit> with Epoch 1. The previous
|
||||
commit-hash versions do not sort in commit order, so rpm could treat a
|
||||
newer snapshot as an older package.
|
||||
|
||||
* Thu Sep 24 2026 Shen Mintao <shenmintao@gmail.com> - c8327ea-1
|
||||
- Build the current legacy-mcu1 branch, which carries the Linux 7.2
|
||||
cfg80211 and strncpy() fixes needed to compile on Bazzite 44.
|
||||
- Include the monitor packet injection path and the 6.12 stable
|
||||
set_monitor_channel() fix synchronized from main.
|
||||
|
||||
* Wed Jul 29 2026 Shen Mintao <shenmintao@gmail.com> - 51b7b6e-2
|
||||
- Disable automatic debug package generation for Bazzite builds.
|
||||
- Require usb_modeswitch by package name for rpm-ostree dependency resolution.
|
||||
|
||||
* Sat Jul 25 2026 Shen Mintao <shenmintao@gmail.com> - 51b7b6e-1
|
||||
- Package the unified installer and ZLP quirk with the legacy MCU1 profiles.
|
||||
- Preserve the matched D80 and DC/DW firmware and loader combinations.
|
||||
|
||||
@@ -61,8 +61,6 @@ endif
|
||||
|
||||
###########################################
|
||||
|
||||
MAKEFLAGS +=-j$(shell nproc)
|
||||
|
||||
KERNEL_AUTOCONF := $(KDIR)/include/config/auto.conf
|
||||
KERNEL_CONFIG := $(KDIR)/.config
|
||||
KERNEL_CC_IS_CLANG := $(shell if [ -r "$(KERNEL_AUTOCONF)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_AUTOCONF)"; then echo y; elif [ -r "$(KERNEL_CONFIG)" ] && grep -q '^CONFIG_CC_IS_CLANG=y' "$(KERNEL_CONFIG)"; then echo y; fi)
|
||||
|
||||
@@ -2,6 +2,16 @@ EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS)
|
||||
EXTRA_CFLAGS += -Wno-implicit-fallthrough
|
||||
#EXTRA_CFLAGS += -Wno-unused-variable
|
||||
|
||||
# OpenWrt may build a newer cfg80211 backport on an older kernel.
|
||||
# Set this to the wireless stack's version, e.g. CFG80211_VERSION=6.18.26.
|
||||
ifneq ($(strip $(CFG80211_VERSION)),)
|
||||
aicwf_cfg80211_version := $(subst ., ,$(CFG80211_VERSION))
|
||||
ifneq ($(words $(aicwf_cfg80211_version)),3)
|
||||
$(error CFG80211_VERSION must have the form major.minor.patch)
|
||||
endif
|
||||
ccflags-y += '-DAICWF_CFG80211_VERSION_CODE=KERNEL_VERSION($(word 1,$(aicwf_cfg80211_version)),$(word 2,$(aicwf_cfg80211_version)),$(word 3,$(aicwf_cfg80211_version)))'
|
||||
endif
|
||||
|
||||
RWNX_VERS_NUM := 6.4.3.0
|
||||
|
||||
CONFIG_AIC8800_WLAN_SUPPORT = m
|
||||
@@ -74,7 +84,11 @@ CONFIG_VHT_FOR_OLD_KERNEL = n
|
||||
CONFIG_COEX = y
|
||||
CONFIG_ALIGN_8BYTES = y
|
||||
CONFIG_TXRX_THREAD_PRIO = y
|
||||
ifdef CONFIG_ARCH_SUN60IW2P1
|
||||
CONFIG_USB_ALIGN_DATA = n
|
||||
else
|
||||
CONFIG_USB_ALIGN_DATA = y
|
||||
endif
|
||||
CONFIG_RX_TASKLET = n
|
||||
CONFIG_TX_TASKLET = n
|
||||
CONFIG_RX_NETIF_RECV_SKB = y
|
||||
@@ -88,7 +102,11 @@ CONFIG_WOWLAN ?= n
|
||||
CONFIG_USB_RX_AGGR = n
|
||||
CONFIG_USB_TX_AGGR = n
|
||||
|
||||
ifdef CONFIG_ARCH_SUN60IW2P1
|
||||
CONFIG_USB_NO_TRANS_DMA_MAP = y
|
||||
else
|
||||
CONFIG_USB_NO_TRANS_DMA_MAP = n
|
||||
endif
|
||||
CONFIG_GPIO_WAKEUP = n
|
||||
CONFIG_CREATE_TRACE_POINTS = n
|
||||
CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y
|
||||
@@ -154,7 +172,7 @@ CONFIG_RWNX_BCMC ?= y
|
||||
|
||||
# Enable Monitor+Data interface support (need FW support)
|
||||
CONFIG_RWNX_MON_DATA =n
|
||||
CONFIG_RWNX_MON_XMIT ?= n
|
||||
CONFIG_RWNX_MON_XMIT ?= y
|
||||
CONFIG_RWNX_MON_RXFILTER ?= n
|
||||
|
||||
CONFIG_FILTER_TCP_ACK =y
|
||||
@@ -349,8 +367,6 @@ ccflags-$(CONFIG_TEMP_CONTROL) += -DCONFIG_TEMP_CONTROL
|
||||
ccflags-$(CONFIG_POWER_LIMIT) += -DCONFIG_POWER_LIMIT
|
||||
ccflags-$(CONFIG_EXT_FEM_8800DCDW) += -DCONFIG_EXT_FEM_8800DCDW
|
||||
ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN
|
||||
MAKEFLAGS +=-j$(shell nproc)
|
||||
|
||||
# Platform support list
|
||||
CONFIG_PLATFORM_ROCKCHIP ?= n
|
||||
CONFIG_PLATFORM_ALLWINNER ?= n
|
||||
|
||||
@@ -1832,7 +1832,7 @@ void set_vendor_extension_ie(char *command){
|
||||
|
||||
}
|
||||
#endif//CONFIG_SET_VENDOR_EXTENSION_IE
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
#else
|
||||
@@ -1840,7 +1840,7 @@ int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
#endif
|
||||
int rwnx_atoi2(char *value, int c_len);
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter)
|
||||
#else
|
||||
void set_mon_chan(struct rwnx_vif *vif, char *parameter)
|
||||
@@ -1867,7 +1867,7 @@ void set_mon_chan(struct rwnx_vif *vif, char *parameter)
|
||||
chandef->center_freq1 = chandef->chan->center_freq;
|
||||
chandef->center_freq2 = 0;
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||
rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, dev, chandef);
|
||||
#else
|
||||
rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, chandef);
|
||||
@@ -2136,7 +2136,7 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
|
||||
char *set_parameter;
|
||||
skip = strlen(CMD_SET_MON_FREQ) + 1;
|
||||
set_parameter = command + skip;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||
set_mon_chan(vif, net, set_parameter);
|
||||
#else
|
||||
set_mon_chan(vif, set_parameter);
|
||||
|
||||
@@ -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);
|
||||
int str_starts(const char *str, const char *start);
|
||||
int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len);
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter);
|
||||
#else
|
||||
void set_mon_chan(struct rwnx_vif *vif, char *parameter);
|
||||
|
||||
@@ -40,7 +40,8 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){
|
||||
char *filename = FW_USERCONFIG_NAME_8800D80;
|
||||
|
||||
#ifndef ANDROID_PLATFORM
|
||||
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80");
|
||||
if (strlcat(aic_fw_path, "/aic8800D80", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||
return -ENAMETOOLONG;
|
||||
#endif
|
||||
|
||||
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
||||
|
||||
@@ -41,7 +41,8 @@ int rwnx_plat_userconfig_load_8800d80x2(struct rwnx_hw *rwnx_hw){
|
||||
char *filename = FW_USERCONFIG_NAME_8800D80X2;
|
||||
|
||||
#ifndef ANDROID_PLATFORM
|
||||
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80X2");
|
||||
if (strlcat(aic_fw_path, "/aic8800D80X2", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||
return -ENAMETOOLONG;
|
||||
#endif
|
||||
|
||||
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
||||
|
||||
@@ -297,18 +297,6 @@ static void aicwf_usb_rx_complete(struct urb *urb)
|
||||
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
||||
if(urb->status < 0){
|
||||
AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status);
|
||||
|
||||
if(g_rwnx_plat->wait_disconnect_cb == false){
|
||||
g_rwnx_plat->wait_disconnect_cb = true;
|
||||
if(atomic_read(&aicwf_deinit_atomic) > 0){
|
||||
atomic_set(&aicwf_deinit_atomic, 0);
|
||||
down(&aicwf_deinit_sem);
|
||||
AICWFDBG(LOGINFO, "%s need to wait for disconnect callback \r\n", __func__);
|
||||
}else{
|
||||
g_rwnx_plat->wait_disconnect_cb = false;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}else{
|
||||
//schedule_work(&usb_dev->rx_urb_work);
|
||||
@@ -385,18 +373,6 @@ static void aicwf_usb_rx_complete(struct urb *urb)
|
||||
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
||||
if(urb->status < 0){
|
||||
AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status);
|
||||
|
||||
if(g_rwnx_plat->wait_disconnect_cb == false){
|
||||
g_rwnx_plat->wait_disconnect_cb = true;
|
||||
if(atomic_read(&aicwf_deinit_atomic) > 0){
|
||||
atomic_set(&aicwf_deinit_atomic, 0);
|
||||
down(&aicwf_deinit_sem);
|
||||
AICWFDBG(LOGINFO, "%s need to wait for disconnect callback \r\n", __func__);
|
||||
}else{
|
||||
g_rwnx_plat->wait_disconnect_cb = false;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}else{
|
||||
//schedule_work(&usb_dev->rx_urb_work);
|
||||
@@ -1979,10 +1955,6 @@ static void aicwf_usb_bus_stop(struct device *dev)
|
||||
if (usb_dev->state == USB_DOWN_ST)
|
||||
return;
|
||||
|
||||
if(g_rwnx_plat && g_rwnx_plat->wait_disconnect_cb == true){
|
||||
atomic_set(&aicwf_deinit_atomic, 1);
|
||||
up(&aicwf_deinit_sem);
|
||||
}
|
||||
aicwf_usb_state_change(usb_dev, USB_DOWN_ST);
|
||||
//aicwf_usb_cancel_all_urbs(usb_dev);//AIDEN
|
||||
}
|
||||
@@ -2341,7 +2313,8 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid
|
||||
usb_dev->chipid = PRODUCT_ID_AIC8801;
|
||||
AICWFDBG(LOGINFO, "%s USE AIC8801\r\n", __func__);
|
||||
return 0;
|
||||
}else if(pid == USB_PRODUCT_ID_AIC8800DC || pid == USB_PRODUCT_ID_TENDA
|
||||
}else if(pid == USB_PRODUCT_ID_AIC8800DC || pid == USB_PRODUCT_ID_AIC8800DE
|
||||
|| pid == USB_PRODUCT_ID_TENDA
|
||||
|| pid == USB_PRODUCT_ID_TENDA_U2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS1
|
||||
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS3
|
||||
|| pid == USB_PRODUCT_ID_AIC8800FC_CUS4 || pid == USB_PRODUCT_ID_AIC8800FC_CUS5
|
||||
@@ -2360,7 +2333,8 @@ 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_CUS5 || pid == USB_PRODUCT_ID_AIC8800M80_CUS6
|
||||
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS7 || pid == USB_PRODUCT_ID_AIC8800M80_CUS8
|
||||
|| pid == USB_PRODUCT_ID_AIC8800D80_UGREEN || pid == USB_PRODUCT_ID_MERCURY){
|
||||
|| pid == USB_PRODUCT_ID_AIC8800D80_UGREEN || pid == USB_PRODUCT_ID_MERCURY
|
||||
|| pid == USB_PRODUCT_ID_TP){
|
||||
usb_dev->chipid = PRODUCT_ID_AIC8800D81;
|
||||
aicwf_usb_rx_aggr = true;
|
||||
AICWFDBG(LOGINFO, "%s USE AIC8800D81\r\n", __func__);
|
||||
@@ -2670,6 +2644,7 @@ static struct usb_device_id aicwf_usb_id_table[] = {
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D81, 0xff, 0xff, 0xff)},
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D41, 0xff, 0xff, 0xff)},
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DC, 0xff, 0xff, 0xff)},
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DE, 0xff, 0xff, 0xff)},
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_TENDA_V2, USB_PRODUCT_ID_TENDA_TX1U_NANO, 0xff, 0xff, 0xff)},
|
||||
{USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DW)},
|
||||
{USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800M80_CUS1)},
|
||||
@@ -2705,6 +2680,7 @@ 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_AIC8800D80_UGREEN)},
|
||||
{USB_DEVICE(USB_VENDOR_ID_TP, USB_PRODUCT_ID_MERCURY)},
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_TP, USB_PRODUCT_ID_TP, 0xff, 0xff, 0xff)},
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#else
|
||||
#define USB_PRODUCT_ID_AIC8801 0x8801
|
||||
#define USB_PRODUCT_ID_AIC8800DC 0x88dc
|
||||
#define USB_PRODUCT_ID_AIC8800DE 0x88de
|
||||
#define USB_PRODUCT_ID_AIC8800DW 0x88dd
|
||||
#define USB_PRODUCT_ID_AIC8800D81 0x8d81
|
||||
#define USB_PRODUCT_ID_AIC8800D41 0x8d41
|
||||
|
||||
@@ -23,6 +23,33 @@
|
||||
#define _RWNX_COMPAT_H_
|
||||
#include <linux/version.h>
|
||||
|
||||
/* Keep wireless API checks separate from timer, USB and other kernel APIs. */
|
||||
#ifndef AICWF_CFG80211_VERSION_CODE
|
||||
#define AICWF_CFG80211_VERSION_CODE LINUX_VERSION_CODE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* cfg80211_ops.set_monitor_channel() gained a "struct net_device *dev"
|
||||
* parameter. The change went into mainline 6.13, but it was also
|
||||
* backported to the 6.12 stable series starting with 6.12.101, so a
|
||||
* plain ">= 6.13.0" test misses 6.12.101 and later. Those kernels then
|
||||
* compile against the old prototype, which is fatal with
|
||||
* -Wincompatible-pointer-types:
|
||||
*
|
||||
* rwnx_main.c: error: initialization of
|
||||
* 'int (*)(struct wiphy *, struct net_device *, struct cfg80211_chan_def *)'
|
||||
* from incompatible pointer type
|
||||
* 'int (*)(struct wiphy *, struct cfg80211_chan_def *)'
|
||||
*
|
||||
* Debian 13 (6.12.107) is one such kernel. The 6.12.101 threshold
|
||||
* covers both the backport and mainline, and leaves 6.11 and earlier
|
||||
* 6.12.x on the old prototype. Keep the check in one place so every
|
||||
* consumer stays in sync.
|
||||
*/
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 101)
|
||||
#define AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
|
||||
#error "Minimum kernel version supported is 3.10"
|
||||
#endif
|
||||
|
||||
@@ -2942,7 +2942,7 @@ bool key_flag = false;
|
||||
* when adding a group key.
|
||||
*/
|
||||
static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct wireless_dev *wdev,
|
||||
#else
|
||||
struct net_device *netdev,
|
||||
@@ -2954,7 +2954,7 @@ static int rwnx_cfg80211_add_key(struct wiphy *wiphy,
|
||||
struct key_params *params)
|
||||
{
|
||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
||||
#else
|
||||
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,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct wireless_dev *wdev,
|
||||
#else
|
||||
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.
|
||||
*/
|
||||
static int rwnx_cfg80211_del_key(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct wireless_dev *wdev,
|
||||
#else
|
||||
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)
|
||||
{
|
||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
||||
#else
|
||||
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
|
||||
*/
|
||||
static int rwnx_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct wireless_dev *wdev,
|
||||
#else
|
||||
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.cipher = sme->crypto.cipher_group;
|
||||
rwnx_cfg80211_add_key(wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
&rwnx_vif->wdev,
|
||||
#else
|
||||
dev,
|
||||
@@ -3480,7 +3480,7 @@ static int rwnx_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *d
|
||||
* @add_station: Add a new station.
|
||||
*/
|
||||
static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct wireless_dev *wdev,
|
||||
#else
|
||||
struct net_device *dev,
|
||||
@@ -3493,7 +3493,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
||||
struct station_parameters *params)
|
||||
{
|
||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
||||
#else
|
||||
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;
|
||||
#endif
|
||||
cfg80211_new_sta(
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
&rwnx_vif->wdev,
|
||||
#else
|
||||
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"]" : "")
|
||||
|
||||
netdev_info(
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
wdev->netdev,
|
||||
#else
|
||||
dev,
|
||||
@@ -3651,7 +3651,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
|
||||
* @del_station: Remove a station
|
||||
*/
|
||||
static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct wireless_dev *wdev,
|
||||
#else
|
||||
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);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
||||
#else
|
||||
struct rwnx_vif *rwnx_vif = netdev_priv(dev);
|
||||
@@ -3711,7 +3711,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
||||
|
||||
if(found) {
|
||||
netdev_info(
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
wdev->netdev,
|
||||
#else
|
||||
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) {
|
||||
cfg80211_del_sta(
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
&rwnx_vif->wdev,
|
||||
#else
|
||||
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.
|
||||
*/
|
||||
static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct wireless_dev *wdev,
|
||||
#else
|
||||
struct net_device *dev,
|
||||
@@ -3975,7 +3975,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
||||
struct station_parameters *params)
|
||||
{
|
||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
||||
#else
|
||||
struct rwnx_vif *vif = netdev_priv(dev);
|
||||
@@ -3988,7 +3988,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
|
||||
/* Add the TDLS station */
|
||||
if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
||||
#else
|
||||
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"]" : "")
|
||||
|
||||
netdev_info(
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
wdev->netdev,
|
||||
#else
|
||||
dev,
|
||||
@@ -4353,7 +4353,7 @@ static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
|
||||
/* delete any remaining STA*/
|
||||
while (!list_empty(&rwnx_vif->ap.sta_list)) {
|
||||
rwnx_cfg80211_del_station_compat(wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
&rwnx_vif->wdev,
|
||||
#else
|
||||
dev,
|
||||
@@ -4420,29 +4420,13 @@ cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1,
|
||||
}
|
||||
#endif
|
||||
|
||||
#define RWNX_CFG80211_OP_TYPE(_member) \
|
||||
typeof(((struct cfg80211_ops *)0)->_member)
|
||||
#define RWNX_CFG80211_OP_MATCH(_member, _type) \
|
||||
__builtin_types_compatible_p(RWNX_CFG80211_OP_TYPE(_member), _type)
|
||||
#define RWNX_CFG80211_OP_ASSERT(_member, _callback) \
|
||||
typedef char rwnx_cfg80211_##_member##_signature_must_match[ \
|
||||
__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)
|
||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||
static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
#else
|
||||
static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
#endif
|
||||
{
|
||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||
struct rwnx_vif *rwnx_vif;
|
||||
@@ -4495,40 +4479,19 @@ static int rwnx_cfg80211_set_monitor_channel_common(
|
||||
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);
|
||||
}
|
||||
|
||||
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))
|
||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
(void)dev;
|
||||
return rwnx_cfg80211_set_monitor_channel_common(wiphy, chandef);
|
||||
return rwnx_cfg80211_set_monitor_channel(wiphy, dev, chandef);
|
||||
}
|
||||
#else
|
||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
return rwnx_cfg80211_set_monitor_channel_common(wiphy, chandef);
|
||||
return rwnx_cfg80211_set_monitor_channel(wiphy, chandef);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4590,45 +4553,15 @@ void rwnx_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
|
||||
* have changed. The actual parameter values are available in
|
||||
* struct wiphy. If returning an error, no value should be changed.
|
||||
*/
|
||||
typedef int (*rwnx_set_wiphy_params_legacy_t)(struct wiphy *wiphy,
|
||||
u32 changed);
|
||||
typedef int (*rwnx_set_wiphy_params_radio_t)(struct wiphy *wiphy,
|
||||
int radio_idx, u32 changed);
|
||||
|
||||
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)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||
static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, u32 changed)
|
||||
#else
|
||||
static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
|
||||
#endif
|
||||
{
|
||||
(void)wiphy;
|
||||
(void)changed;
|
||||
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,
|
||||
@@ -4637,25 +4570,18 @@ static int rwnx_cfg80211_set_wiphy_params_radio(struct wiphy *wiphy,
|
||||
* always be %NULL unless the driver supports per-vif TX power
|
||||
* (as advertised by the nl80211 feature flag.)
|
||||
*/
|
||||
typedef int (*rwnx_set_tx_power_no_wdev_t)(
|
||||
struct wiphy *wiphy, enum nl80211_tx_power_setting type, int mbm);
|
||||
typedef int (*rwnx_set_tx_power_wdev_t)(
|
||||
struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
enum nl80211_tx_power_setting type, int mbm);
|
||||
typedef int (*rwnx_set_tx_power_radio_t)(
|
||||
struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
|
||||
enum nl80211_tx_power_setting type, int mbm);
|
||||
|
||||
typedef char rwnx_set_tx_power_signature_must_be_supported[
|
||||
(RWNX_CFG80211_OP_MATCH(set_tx_power, rwnx_set_tx_power_no_wdev_t) ||
|
||||
RWNX_CFG80211_OP_MATCH(set_tx_power, rwnx_set_tx_power_wdev_t) ||
|
||||
RWNX_CFG80211_OP_MATCH(set_tx_power,
|
||||
rwnx_set_tx_power_radio_t)) ? 1 : -1];
|
||||
|
||||
static int rwnx_cfg80211_set_tx_power_common(
|
||||
struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
static int rwnx_cfg80211_set_tx_power(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
|
||||
struct wireless_dev *wdev,
|
||||
#endif
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||
int radio_idx,
|
||||
#endif
|
||||
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_vif *vif;
|
||||
s8 pwr;
|
||||
@@ -4681,112 +4607,31 @@ static int rwnx_cfg80211_set_tx_power_common(
|
||||
return res;
|
||||
}
|
||||
|
||||
static int rwnx_cfg80211_set_tx_power_no_wdev(
|
||||
struct wiphy *wiphy, enum nl80211_tx_power_setting type, int mbm)
|
||||
{
|
||||
return rwnx_cfg80211_set_tx_power_common(wiphy, NULL, type, mbm);
|
||||
}
|
||||
|
||||
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,
|
||||
static int rwnx_cfg80211_get_tx_power(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
|
||||
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)
|
||||
#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)
|
||||
struct wireless_dev *wdev = NULL;
|
||||
#endif
|
||||
//struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||
//struct rwnx_vif *vif;
|
||||
s8 pwr = 0;
|
||||
int res = 0;
|
||||
|
||||
(void)wiphy;
|
||||
(void)wdev;
|
||||
if (!dbm)
|
||||
return -EINVAL;
|
||||
*mbm = get_txpwr_max(pwr);
|
||||
|
||||
*dbm = get_txpwr_max(pwr);
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
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:
|
||||
* Power-save off
|
||||
@@ -5012,7 +4857,17 @@ rwnx_cfg80211_remain_on_channel(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||
enum nl80211_channel_type channel_type,
|
||||
#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,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
|
||||
@@ -5154,7 +5009,11 @@ static int rwnx_cfg80211_get_channel(struct wiphy *wiphy,
|
||||
if (rwnx_vif->vif_index == rwnx_hw->monitor_vif)
|
||||
{
|
||||
//retrieve channel from firmware
|
||||
rwnx_cfg80211_set_monitor_channel_common(wiphy, NULL);
|
||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||
rwnx_cfg80211_set_monitor_channel(wiphy, wdev->netdev, NULL);
|
||||
#else
|
||||
rwnx_cfg80211_set_monitor_channel(wiphy, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
//Check if channel context is valid
|
||||
@@ -5341,28 +5200,17 @@ send_frame:
|
||||
/**
|
||||
* @start_radar_detection: Start radar detection in the driver.
|
||||
*/
|
||||
typedef int (*rwnx_start_radar_detection_legacy_t)(
|
||||
struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
typedef int (*rwnx_start_radar_detection_cac_t)(
|
||||
struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef, u32 cac_time_ms);
|
||||
typedef int (*rwnx_start_radar_detection_link_t)(
|
||||
struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef, u32 cac_time_ms, int link_id);
|
||||
|
||||
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)
|
||||
static
|
||||
int rwnx_cfg80211_start_radar_detection(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
|
||||
, u32 cac_time_ms
|
||||
#endif
|
||||
#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 0))
|
||||
, int link_id
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||
struct rwnx_vif *rwnx_vif = netdev_priv(dev);
|
||||
@@ -5370,8 +5218,9 @@ static int rwnx_cfg80211_start_radar_detection_common(
|
||||
|
||||
printk("%s\n", __func__);
|
||||
|
||||
if (start_cac_timer)
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
|
||||
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);
|
||||
|
||||
if (cfm.status == CO_OK) {
|
||||
@@ -5389,42 +5238,6 @@ static int rwnx_cfg80211_start_radar_detection_common(
|
||||
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
|
||||
* driver. If the SME is in the driver/firmware, this information can be
|
||||
@@ -6178,7 +5991,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
|
||||
*/
|
||||
static int rwnx_cfg80211_get_station(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct wireless_dev *wdev,
|
||||
#else
|
||||
struct net_device *dev,
|
||||
@@ -6190,7 +6003,7 @@ static int rwnx_cfg80211_get_station(struct wiphy *wiphy,
|
||||
#endif
|
||||
struct station_info *sinfo)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct rwnx_vif *vif = netdev_priv(wdev->netdev);
|
||||
#else
|
||||
struct rwnx_vif *vif = netdev_priv(dev);
|
||||
@@ -6228,14 +6041,14 @@ static int rwnx_cfg80211_get_station(struct wiphy *wiphy,
|
||||
* @dump_station: dump station callback -- resume dump at index @idx
|
||||
*/
|
||||
static int rwnx_cfg80211_dump_station(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct wireless_dev *wdev,
|
||||
#else
|
||||
struct net_device *dev,
|
||||
#endif
|
||||
int idx, u8 *mac, struct station_info *sinfo)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
struct rwnx_vif *rwnx_vif = netdev_priv(wdev->netdev);
|
||||
#else
|
||||
struct rwnx_vif *rwnx_vif = netdev_priv(dev);
|
||||
@@ -6717,59 +6530,6 @@ static int rwnx_cfg80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
|
||||
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 = {
|
||||
.add_virtual_intf = rwnx_cfg80211_add_iface,
|
||||
.del_virtual_intf = rwnx_cfg80211_del_iface,
|
||||
@@ -6791,20 +6551,20 @@ static struct cfg80211_ops rwnx_cfg80211_ops = {
|
||||
.start_ap = rwnx_cfg80211_start_ap,
|
||||
.change_beacon = rwnx_cfg80211_change_beacon,
|
||||
.stop_ap = rwnx_cfg80211_stop_ap,
|
||||
.set_monitor_channel = RWNX_CFG80211_SET_MONITOR_CHANNEL_CB,
|
||||
.set_monitor_channel = rwnx_cfg80211_set_monitor_channel,
|
||||
.probe_client = rwnx_cfg80211_probe_client,
|
||||
// .mgmt_frame_register = rwnx_cfg80211_mgmt_frame_register,
|
||||
.set_wiphy_params = RWNX_CFG80211_SET_WIPHY_PARAMS_CB,
|
||||
.set_wiphy_params = rwnx_cfg80211_set_wiphy_params,
|
||||
.set_txq_params = rwnx_cfg80211_set_txq_params,
|
||||
.set_tx_power = RWNX_CFG80211_SET_TX_POWER_CB,
|
||||
.get_tx_power = RWNX_CFG80211_GET_TX_POWER_CB,
|
||||
.set_tx_power = rwnx_cfg80211_set_tx_power,
|
||||
.get_tx_power = rwnx_cfg80211_get_tx_power,
|
||||
.set_power_mgmt = rwnx_cfg80211_set_power_mgmt,
|
||||
.get_station = rwnx_cfg80211_get_station,
|
||||
.remain_on_channel = rwnx_cfg80211_remain_on_channel,
|
||||
.cancel_remain_on_channel = rwnx_cfg80211_cancel_remain_on_channel,
|
||||
.dump_survey = rwnx_cfg80211_dump_survey,
|
||||
.get_channel = rwnx_cfg80211_get_channel,
|
||||
.start_radar_detection = RWNX_CFG80211_START_RADAR_DETECTION_CB,
|
||||
.start_radar_detection = rwnx_cfg80211_start_radar_detection,
|
||||
.update_ft_ies = rwnx_cfg80211_update_ft_ies,
|
||||
.set_cqm_rssi_config = rwnx_cfg80211_set_cqm_rssi_config,
|
||||
#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);
|
||||
void apm_staloss_work_process(struct work_struct *work);
|
||||
void apm_probe_sta_work_process(struct work_struct *work);
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0))
|
||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
|
||||
@@ -825,7 +825,9 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw,
|
||||
#endif
|
||||
|
||||
}
|
||||
#ifdef CONFIG_USE_WIRELESS_EXT
|
||||
putbss:
|
||||
#endif
|
||||
if (bss != NULL)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
|
||||
cfg80211_put_bss(bss);
|
||||
|
||||
@@ -4849,7 +4849,13 @@ int rwnx_send_dbg_trigger_req(struct rwnx_hw *rwnx_hw, char *msg)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Set parameters for the MM_DBG_TRIGGER_REQ message */
|
||||
strncpy(req->error, msg, sizeof(req->error));
|
||||
/*
|
||||
* strncpy() is gone in 7.2. req->error is a fixed 64-byte field of a
|
||||
* firmware message that is not NUL-terminated, and the message came
|
||||
* from kzalloc(), so copying at most the field size is all strncpy()
|
||||
* did here.
|
||||
*/
|
||||
memcpy(req->error, msg, strnlen(msg, sizeof(req->error)));
|
||||
|
||||
/* Send the MM_DBG_TRIGGER_REQ message to LMAC FW */
|
||||
return rwnx_send_msg(rwnx_hw, req, 0, -1, NULL);
|
||||
|
||||
@@ -1669,7 +1669,8 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
|
||||
if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC ||
|
||||
rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){
|
||||
#ifndef ANDROID_PLATFORM
|
||||
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800DC");
|
||||
if (strlcat(aic_fw_path, "/aic8800DC", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||
return -ENAMETOOLONG;
|
||||
#endif
|
||||
AICWFDBG(LOGINFO, "testmode=%d\n", testmode);
|
||||
if (chip_sub_id == 0) {
|
||||
@@ -1808,7 +1809,8 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
|
||||
}
|
||||
} else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) {
|
||||
#ifndef ANDROID_PLATFORM
|
||||
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80N");
|
||||
if (strlcat(aic_fw_path, "/aic8800D80N", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||
return -ENAMETOOLONG;
|
||||
#endif
|
||||
if (testmode == FW_NORMAL_MODE) {
|
||||
ret = aicwf_plat_patch_load_8800d80n(rwnx_hw);
|
||||
@@ -1838,7 +1840,8 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
|
||||
}
|
||||
else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN) {
|
||||
#ifndef ANDROID_PLATFORM
|
||||
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800DLN");
|
||||
if (strlcat(aic_fw_path, "/aic8800DLN", sizeof(aic_fw_path)) >= sizeof(aic_fw_path))
|
||||
return -ENAMETOOLONG;
|
||||
#endif
|
||||
if (testmode == FW_NORMAL_MODE) {
|
||||
aicwf_patch_config_8800dln(rwnx_hw);
|
||||
|
||||
@@ -22,52 +22,6 @@
|
||||
#include "rwnx_events.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
|
||||
* TODO: this might need to be HW-dependent
|
||||
@@ -1517,8 +1471,15 @@ static void rwnx_radar_cac_work(struct work_struct *ws)
|
||||
}
|
||||
|
||||
ctxt = &rwnx_hw->chanctx_table[radar->cac_vif->ch_index];
|
||||
rwnx_cfg80211_cac_event_compat(radar->cac_vif->ndev, &ctxt->chan_def,
|
||||
cfg80211_cac_event(radar->cac_vif->ndev,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
||||
&ctxt->chan_def,
|
||||
#endif
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0);
|
||||
#else
|
||||
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
|
||||
#endif
|
||||
rwnx_send_apm_stop_cac_req(rwnx_hw, radar->cac_vif);
|
||||
rwnx_chanctx_unlink(radar->cac_vif);
|
||||
|
||||
@@ -1652,9 +1613,15 @@ void rwnx_radar_cancel_cac(struct rwnx_radar *radar)
|
||||
struct rwnx_chanctx *ctxt;
|
||||
ctxt = &rwnx_hw->chanctx_table[radar->cac_vif->ch_index];
|
||||
rwnx_send_apm_stop_cac_req(rwnx_hw, radar->cac_vif);
|
||||
rwnx_cfg80211_cac_event_compat(radar->cac_vif->ndev,
|
||||
cfg80211_cac_event(radar->cac_vif->ndev,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
||||
&ctxt->chan_def,
|
||||
#endif
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||
NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0);
|
||||
#else
|
||||
NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
|
||||
#endif
|
||||
rwnx_chanctx_unlink(radar->cac_vif);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,60 +34,6 @@
|
||||
#define IEEE80211_MAX_CHAINS 4
|
||||
#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;
|
||||
|
||||
u16 tx_legrates_lut_rate[] = {
|
||||
@@ -2337,6 +2283,11 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
|
||||
if(hw_rxhdr->flags_upload)
|
||||
status |= RX_STAT_FORWARD;
|
||||
|
||||
#ifndef CONFIG_RWNX_MON_DATA
|
||||
if (status & RX_STAT_MONITOR)
|
||||
status &= ~RX_STAT_FORWARD;
|
||||
#endif
|
||||
|
||||
/* Check if we need to delete the buffer */
|
||||
if (status & RX_STAT_DELETE) {
|
||||
/* Remove the SK buffer from the rxbuf_elems table */
|
||||
@@ -2399,13 +2350,24 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
|
||||
} else {
|
||||
#ifdef CONFIG_RWNX_MON_DATA
|
||||
skb_monitor = skb_copy_expand(skb, rtap_len, 0, GFP_ATOMIC);
|
||||
if (skb_monitor) {
|
||||
skb_monitor->data += (msdu_offset + 2); //sdio/usb word allign
|
||||
|
||||
//Save frame length
|
||||
frm_len = le32_to_cpu(hw_rxhdr->hwvect.len);
|
||||
}
|
||||
#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->len = 0;
|
||||
skb_reset_tail_pointer(skb_monitor);
|
||||
@@ -2448,8 +2410,11 @@ check_len_update:
|
||||
hdr = (struct ieee80211_hdr *)(skb->data + msdu_offset);
|
||||
rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx);
|
||||
if (rwnx_vif) {
|
||||
rwnx_cfg80211_rx_spurious_frame_compat(rwnx_vif->ndev,
|
||||
hdr->addr2, GFP_ATOMIC);
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||
cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, -1, GFP_ATOMIC);
|
||||
#else
|
||||
cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC);
|
||||
#endif
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
@@ -2792,8 +2757,13 @@ check_len_update:
|
||||
|
||||
if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) {
|
||||
printk("aicwf: 4addr flag error\n");
|
||||
rwnx_cfg80211_rx_unexpected_4addr_frame_compat(
|
||||
rwnx_vif->ndev, sta->mac_addr, GFP_ATOMIC);
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||
cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
|
||||
sta->mac_addr, -1, GFP_ATOMIC);
|
||||
#else
|
||||
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) {
|
||||
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
skb_put(skb, 1 + sizeof(mgmt->u.action.tdls_discover_resp));
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 1, 0)
|
||||
skb_put(skb, 2 + sizeof(mgmt->u.action.tdls_discover_resp));
|
||||
mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
|
||||
mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
|
||||
mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token;
|
||||
|
||||
@@ -1991,7 +1991,7 @@ free_use:
|
||||
|
||||
netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
int rtap_len, ret, idx, tmp_len;
|
||||
int rtap_len, ret, idx;
|
||||
struct ieee80211_radiotap_header *rtap_hdr; // net/ieee80211_radiotap.h
|
||||
struct ieee80211_radiotap_iterator iterator; // net/cfg80211.h
|
||||
u8_l *rtap_buf = (u8_l *)skb->data;
|
||||
@@ -2012,10 +2012,30 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
|
||||
bool offchan = false;
|
||||
int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX;
|
||||
|
||||
rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf);
|
||||
rtap_len = ieee80211_get_radiotap_len(rtap_buf);//max_length
|
||||
frame_len = skb->len;
|
||||
|
||||
if (unlikely(skb->len < sizeof(*rtap_hdr))) {
|
||||
AICWFDBG(LOGERROR, "%s radiotap header is truncated\n", __func__);
|
||||
goto free_tag;
|
||||
}
|
||||
|
||||
rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf);
|
||||
if (unlikely(rtap_hdr->it_version)) {
|
||||
AICWFDBG(LOGERROR, "%s itv \r\n", __func__);
|
||||
goto free_tag;
|
||||
}
|
||||
|
||||
rtap_len = ieee80211_get_radiotap_len(rtap_buf);//max_length
|
||||
if (unlikely(rtap_len < sizeof(*rtap_hdr))) {
|
||||
AICWFDBG(LOGERROR, "%s rtap_len < sizeof(struct ieee80211_radiotap_header) \r\n", __func__);
|
||||
goto free_tag;
|
||||
}
|
||||
|
||||
if (unlikely(skb->len < rtap_len)) {
|
||||
AICWFDBG(LOGERROR, "%s skb->len < rtap_len \r\n", __func__);
|
||||
goto free_tag;
|
||||
}
|
||||
|
||||
AICWFDBG(LOGINFO, "rwnx_start_monitor_if_xmit, skb_len=%d, rtap_len=%d\n", skb->len, rtap_len);
|
||||
//rwnx_data_dump((char*)__func__, skb->data, skb->len);
|
||||
if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) ||
|
||||
@@ -2023,23 +2043,6 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
|
||||
g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){
|
||||
nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC;
|
||||
}
|
||||
|
||||
|
||||
if (unlikely(rtap_hdr->it_version)){
|
||||
AICWFDBG(LOGERROR, "%s itv \r\n", __func__);
|
||||
goto free_tag;
|
||||
}
|
||||
|
||||
if (unlikely(skb->len < rtap_len)){
|
||||
AICWFDBG(LOGERROR, "%s skb->len < rtap_len \r\n", __func__);
|
||||
goto free_tag;
|
||||
}
|
||||
|
||||
if (unlikely(rtap_len < sizeof(struct ieee80211_radiotap_header))){
|
||||
AICWFDBG(LOGERROR, "%s rtap_len < sizeof(struct ieee80211_radiotap_header) \r\n", __func__);
|
||||
goto free_tag;
|
||||
}
|
||||
|
||||
frame_len -= rtap_len;
|
||||
pframe = rtap_buf + rtap_len;
|
||||
|
||||
|
||||
@@ -172,7 +172,8 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
u64 *cookie);
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||
#ifdef CONFIG_RWNX_MON_XMIT
|
||||
int rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||
netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev);
|
||||
#endif
|
||||
int rwnx_txdatacfm(void *pthis, void *host_id);
|
||||
|
||||
|
||||
@@ -149,7 +149,11 @@ static int usb_submit_urb_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
|
||||
(void)p;
|
||||
|
||||
#if defined(CONFIG_ARM)
|
||||
urb = (struct urb *)regs->ARM_r0;
|
||||
#else
|
||||
urb = (struct urb *)regs_get_kernel_argument(regs, 0);
|
||||
#endif
|
||||
if (is_bluetooth_acl_endpoint(urb))
|
||||
enable_zlp(urb);
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# 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.
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/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
|
||||
# USB Mass Storage to WiFi+BT mode.
|
||||
#
|
||||
# The 16-byte CDB is: FD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F2
|
||||
# Wrapped in a standard 31-byte SCSI CBW (Command Block Wrapper).
|
||||
# The two 16-byte CDBs end in F3 and F2 respectively. Each is wrapped in a
|
||||
# standard 31-byte SCSI CBW (Command Block Wrapper), and must be sent in order.
|
||||
#
|
||||
# Install as: /etc/usb_modeswitch.d/1111:1111
|
||||
# (The filename must contain a colon on Linux; this file is named
|
||||
@@ -13,4 +13,6 @@ DefaultVendor=0x1111
|
||||
DefaultProduct=0x1111
|
||||
TargetVendor=0xa69c
|
||||
TargetProduct=0x8d80
|
||||
MessageContent="555342438765432100000000000010fd0000000000000000000000000000f2"
|
||||
MessageContent="555342438765432100000000000010fd0000000000000000000000000000f3"
|
||||
MessageContent2="555342438765432100000000000010fd0000000000000000000000000000f2"
|
||||
NeedResponse=1
|
||||
|
||||
Reference in New Issue
Block a user