Refactor script for other Linux distros with automatic kernel updates

This commit is contained in:
Spacery
2025-12-30 18:01:39 -04:00
parent 1ce24d71ff
commit 6cefc43cda
21 changed files with 706 additions and 387 deletions
+20 -5
View File
@@ -5,12 +5,12 @@
This automated installation script (`install.sh`) simplifies the process of installing the AIC8800D80 WiFi driver on Linux systems. This automated installation script (`install.sh`) simplifies the process of installing the AIC8800D80 WiFi driver on Linux systems.
- Automatic Secure Boot detection - Automatic Secure Boot detection
- Dependency installation - Automatic dependency installation
- Driver compilation and installation - Automatic driver compilation and installation
- Automatic module loading on boot - Automatic module loading on boot
- Comprehensive error handling - Comprehensive error handling
- Colored output and logging - Colored output and logging
- Compatible with Ubuntu, Debian, and derivatives - Compatible with Ubuntu, Debian, Fedora, and derivatives (DKMS supported `dkms.conf`)
## Usage ## Usage
@@ -19,7 +19,22 @@ This automated installation script (`install.sh`) simplifies the process of inst
git clone https://github.com/shenmintao/aic8800d80.git && cd aic8800d80 && chmod +x install.sh git clone https://github.com/shenmintao/aic8800d80.git && cd aic8800d80 && chmod +x install.sh
# Run the installation # Run the installation
./install.sh sudo ./install.sh
``` ```
> For more information, please refer to the [README.md](README.md) file. > For more information, please refer to the [README.md](README.md) file.
<br>
---
<br>
# Diagnostic Build Script (Optional)
This script is used to diagnose build issues with the AIC8800D80 driver. Useful for identifying the root cause of the build failure.
```bash
# Make the script executable and run it
chmod +x diagnostic_build.sh && sudo ./diagnostic_build.sh
```
+5 -1
View File
@@ -14,8 +14,12 @@ I did not develop this software, The code is sourced from the Tenda U11 driver.
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.
### Installation Steps ### Installation Steps
#### Copy udev rules:
#### Method 1: [Quick Installation](INSTALL_SCRIPT.md) (Recommended)
#### Method 2: Manual Installation
#### Copy udev rules:
Copy the aic.rules file to /lib/udev/rules.d/: Copy the aic.rules file to /lib/udev/rules.d/:
```bash ```bash
+3
View File
@@ -2,4 +2,7 @@ KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", SYMLINK+="aic
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"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5726", SYMLINK+="tendaudiskv3", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5727", SYMLINK+="tendaudiskv4", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572a", SYMLINK+="tendaudiskv5", RUN+="/usr/bin/eject /dev/%k"
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572c", SYMLINK+="cudydiskv2", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="572c", SYMLINK+="cudydiskv2", RUN+="/usr/bin/eject /dev/%k"
+132
View File
@@ -0,0 +1,132 @@
#!/bin/bash
#############################################################################
# Diagnostic Build Script - AIC8800D80 Driver Build Failure
# Run this script to diagnose the problem with the DKMS
#############################################################################
echo "╔════════════════════════════════════════════════════════════════╗"
echo "║ DIAGNOSTIC BUILD SCRIPT - AIC8800D80 DRIVER ║"
echo "╚════════════════════════════════════════════════════════════════╝"
echo ""
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_section() {
echo ""
echo -e "${BLUE}━━━ $1 ━━━${NC}"
echo ""
}
print_section "1. Checking directory structure"
echo "Current directory:"
pwd
echo ""
echo "Current directory content:"
ls -la
echo ""
echo "Checking if drivers/aic8800/ exists:"
if [ -d "drivers/aic8800" ]; then
echo -e "${GREEN}✓${NC} drivers/aic8800 directory exists"
echo ""
echo "drivers/aic8800/ content:"
ls -la drivers/aic8800/
echo ""
echo "Checking Makefile:"
if [ -f "drivers/aic8800/Makefile" ]; then
echo -e "${GREEN}✓${NC} Makefile found"
echo ""
echo "First 20 lines of Makefile:"
head -20 drivers/aic8800/Makefile
else
echo -e "${RED}✗${NC} Makefile NOT FOUND!"
echo "This is probably the problem!"
fi
else
echo -e "${RED}✗${NC} drivers/aic8800 directory NOT FOUND!"
echo "The script expects to find the source code in drivers/aic8800/"
fi
print_section "2. Checking DKMS directory"
if [ -d "/usr/src/aic8800-1.0.0" ]; then
echo -e "${GREEN}✓${NC} /usr/src/aic8800-1.0.0 directory exists"
echo ""
echo "Content:"
ls -la /usr/src/aic8800-1.0.0/
echo ""
echo "Checking drivers/aic8800 inside DKMS:"
if [ -d "/usr/src/aic8800-1.0.0/drivers/aic8800" ]; then
echo -e "${GREEN}✓${NC} drivers/aic8800 copied to DKMS"
ls -la /usr/src/aic8800-1.0.0/drivers/aic8800/
else
echo -e "${RED}✗${NC} drivers/aic8800 NOT copied correctly!"
fi
else
echo -e "${RED}✗${NC} /usr/src/aic8800-1.0.0 directory NOT FOUND"
fi
print_section "3. Checking DKMS build logs"
if [ -f "/var/lib/dkms/aic8800/1.0.0/build/make.log" ]; then
echo -e "${GREEN}✓${NC} Build log found"
echo ""
echo "Last 50 lines of make.log:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
tail -50 /var/lib/dkms/aic8800/1.0.0/build/make.log
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
else
echo -e "${RED}✗${NC} Build log not found in /var/lib/dkms/aic8800/1.0.0/build/make.log"
fi
print_section "4. Checking dkms.conf"
if [ -f "/usr/src/aic8800-1.0.0/dkms.conf" ]; then
echo -e "${GREEN}✓${NC} dkms.conf found"
echo ""
echo "dkms.conf content:"
cat /usr/src/aic8800-1.0.0/dkms.conf
else
echo -e "${RED}✗${NC} dkms.conf NOT FOUND!"
fi
if [ -f "./dkms.conf" ]; then
echo ""
echo "dkms.conf in current directory:"
cat ./dkms.conf
fi
print_section "5. Checking firmware"
if [ -d "/lib/firmware/aic8800D80" ]; then
echo -e "${GREEN}✓${NC} Firmware installed"
ls -la /lib/firmware/aic8800D80/
else
echo -e "${RED}✗${NC} Firmware NOT installed"
fi
print_section "6. System information"
echo "Kernel: $(uname -r)"
echo "Architecture: $(uname -m)"
echo ""
echo "GCC version:"
gcc --version | head -1
echo ""
echo "Installed kernel headers:"
ls -d /lib/modules/$(uname -r)/build 2>/dev/null && echo "✓ Headers found" || echo "✗ Headers NOT found"
print_section "7. DKMS status"
echo "DKMS modules registered:"
dkms status
+16
View File
@@ -0,0 +1,16 @@
PACKAGE_NAME="aic8800"
PACKAGE_VERSION="1.0.0"
CLEAN="cd drivers/aic8800 && make clean"
MAKE="cd drivers/aic8800 && make"
# Main module (aic8800_fdrv)
BUILT_MODULE_NAME[0]="aic8800_fdrv"
BUILT_MODULE_LOCATION[0]="drivers/aic8800/aic8800_fdrv"
DEST_MODULE_LOCATION[0]="/updates/dkms"
# Firmware loading module (aic_load_fw)
BUILT_MODULE_NAME[1]="aic_load_fw"
BUILT_MODULE_LOCATION[1]="drivers/aic8800/aic_load_fw"
DEST_MODULE_LOCATION[1]="/updates/dkms"
AUTOINSTALL="yes"
+3 -6
View File
@@ -341,7 +341,6 @@ ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP
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
@@ -381,13 +380,11 @@ KDIR ?= /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt
endif endif
ifeq ($(CONFIG_PLATFORM_UBUNTU), y) ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
KDIR ?= /lib/modules/$(shell uname -r)/build KVER := $(or $(KVER), $(kernelver), $(KERNELRELEASE), $(shell uname -r))
#KDIR ?= ~/D/Workspace/CyberQuantum/Linux/linux-4.15/ KDIR ?= /lib/modules/$(KVER)/build
PWD ?= $(shell pwd) PWD ?= $(shell pwd)
KVER ?= $(shell uname -r)
MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800 MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/) ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= CROSS_COMPILE ?=
endif endif
@@ -42,12 +42,14 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){
char *filename = FW_USERCONFIG_NAME_8800D80; char *filename = FW_USERCONFIG_NAME_8800D80;
if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11 if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS1 || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS1
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS4) { || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS4
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS7) {
filename = FW_USERCONFIG_NAME_8800D80_U11; filename = FW_USERCONFIG_NAME_8800D80_U11;
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11_PRO } else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11_PRO
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS3 || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS3
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS5 || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS5
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS6) { || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS6
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS8) {
filename = FW_USERCONFIG_NAME_8800D80_U11_PRO; filename = FW_USERCONFIG_NAME_8800D80_U11_PRO;
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS2) { } else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS2) {
filename = FW_USERCONFIG_NAME_8800D80_U11_CUS; filename = FW_USERCONFIG_NAME_8800D80_U11_CUS;
@@ -3511,12 +3511,15 @@ int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){
int size; int size;
u32 *dst=NULL; u32 *dst=NULL;
char *filename = FW_USERCONFIG_NAME_8800DW; char *filename = FW_USERCONFIG_NAME_8800DW;
if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA) { if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS3
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS5
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS6) {
filename = FW_USERCONFIG_NAME_8800DW_W311; filename = FW_USERCONFIG_NAME_8800DW_W311;
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U2 } else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U2
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS1 || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS1
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS2 || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS2
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS3) { || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS4) {
filename = FW_USERCONFIG_NAME_8800DW_U2; filename = FW_USERCONFIG_NAME_8800DW_U2;
} }
+1 -2
View File
@@ -1001,8 +1001,7 @@ static void aicwf_sdio_bus_pwrctl(struct timer_list *t)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data; struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0) #elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
struct aic_sdio_dev *sdiodev = timer_container_of(sdiodev, t, timer); struct aic_sdio_dev *sdiodev = timer_container_of(sdiodev, t, timer);#else
#else
struct aic_sdio_dev *sdiodev = from_timer(sdiodev, t, timer); struct aic_sdio_dev *sdiodev = from_timer(sdiodev, t, timer);
#endif #endif
+7 -7
View File
@@ -106,8 +106,8 @@ void tcp_ack_deinit(struct rwnx_hw *priv)
drop_msg = NULL; drop_msg = NULL;
write_seqlock_bh(&ack_m->ack_info[i].seqlock); write_seqlock_bh(&ack_m->ack_info[i].seqlock);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
timer_delete(&ack_m->ack_info[i].timer); timer_delete(&ack_m->ack_info[i].timer);
#else #else
del_timer(&ack_m->ack_info[i].timer); del_timer(&ack_m->ack_info[i].timer);
#endif #endif
@@ -379,7 +379,7 @@ int tcp_ack_handle(struct msg_buf *new_msgbuf,
//printk("%lx \n",ack_info->msgbuf); //printk("%lx \n",ack_info->msgbuf);
drop_msg = ack_info->msgbuf; drop_msg = ack_info->msgbuf;
ack_info->msgbuf = NULL; ack_info->msgbuf = NULL;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
timer_delete(&ack_info->timer); timer_delete(&ack_info->timer);
#else #else
del_timer(&ack_info->timer); del_timer(&ack_info->timer);
@@ -417,8 +417,8 @@ int tcp_ack_handle(struct msg_buf *new_msgbuf,
atomic_read(&ack_m->max_drop_cnt)))) { atomic_read(&ack_m->max_drop_cnt)))) {
ack_info->drop_cnt = 0; ack_info->drop_cnt = 0;
ack_info->in_send_msg = new_msgbuf; ack_info->in_send_msg = new_msgbuf;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
timer_delete(&ack_info->timer); timer_delete(&ack_info->timer);
#else #else
del_timer(&ack_info->timer); del_timer(&ack_info->timer);
#endif #endif
@@ -484,8 +484,8 @@ int tcp_ack_handle_new(struct msg_buf *new_msgbuf,
ack_info->drop_cnt = 0; ack_info->drop_cnt = 0;
//send_msg = new_msgbuf; //send_msg = new_msgbuf;
ack_info->in_send_msg = new_msgbuf; ack_info->in_send_msg = new_msgbuf;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
timer_delete(&ack_info->timer); timer_delete(&ack_info->timer);
#else #else
del_timer(&ack_info->timer); del_timer(&ack_info->timer);
#endif #endif
+18 -4
View File
@@ -1214,6 +1214,9 @@ fail:
usb_buf->skb = NULL; usb_buf->skb = NULL;
aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf, aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf,
&usb_dev->tx_free_count, &usb_dev->tx_free_lock); &usb_dev->tx_free_count, &usb_dev->tx_free_lock);
if (ret == -ENODEV) {
break;
}
#endif #endif
} }
} }
@@ -2140,7 +2143,7 @@ static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *in
/* Check interface number */ /* Check interface number */
#ifdef CONFIG_USB_BT #ifdef CONFIG_USB_BT
if (usb->actconfig->desc.bNumInterfaces != 3) if (usb->actconfig->desc.bNumInterfaces != 1 && usb->actconfig->desc.bNumInterfaces != 3)
#else #else
if (usb->actconfig->desc.bNumInterfaces != 1) if (usb->actconfig->desc.bNumInterfaces != 1)
#endif #endif
@@ -2150,7 +2153,9 @@ static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *in
if(usb_dev->chipid == PRODUCT_ID_AIC8800DC){ if(usb_dev->chipid == PRODUCT_ID_AIC8800DC){
AICWFDBG(LOGERROR, "AIC8800DC change to AIC8800DW\n"); AICWFDBG(LOGERROR, "AIC8800DC change to AIC8800DW\n");
usb_dev->chipid = PRODUCT_ID_AIC8800DW; usb_dev->chipid = PRODUCT_ID_AIC8800DW;
} else if (usb_dev->chipid == PRODUCT_ID_AIC8800D81) { }else if (usb_dev->chipid == PRODUCT_ID_AIC8800DW) {
AICWFDBG(LOGINFO, "AIC8800DW\n");}
else if (usb_dev->chipid == PRODUCT_ID_AIC8800D81) {
AICWFDBG(LOGINFO, "AIC8800D80\n"); AICWFDBG(LOGINFO, "AIC8800D80\n");
} else if(usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 || } else if(usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 ||
usb_dev->chipid == PRODUCT_ID_AIC8800D89X2 || usb_dev->chipid == PRODUCT_ID_AIC8800D89X2 ||
@@ -2339,11 +2344,13 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid
return 0; return 0;
}else if(pid == USB_PRODUCT_ID_AIC8800DC || pid == USB_PRODUCT_ID_TENDA }else if(pid == USB_PRODUCT_ID_AIC8800DC || 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_CUS6){
usb_dev->chipid = PRODUCT_ID_AIC8800DC; usb_dev->chipid = PRODUCT_ID_AIC8800DC;
AICWFDBG(LOGINFO, "%s USE AIC8800DC\r\n", __func__); AICWFDBG(LOGINFO, "%s USE AIC8800DC\r\n", __func__);
return 0; return 0;
}else if(pid == USB_PRODUCT_ID_AIC8800DW){ }else if(pid == USB_PRODUCT_ID_AIC8800DW || pid == USB_PRODUCT_ID_TENDA_TX1U_NANO){
usb_dev->chipid = PRODUCT_ID_AIC8800DW; usb_dev->chipid = PRODUCT_ID_AIC8800DW;
AICWFDBG(LOGINFO, "%s USE AIC8800DW\r\n", __func__); AICWFDBG(LOGINFO, "%s USE AIC8800DW\r\n", __func__);
return 0; return 0;
@@ -2352,6 +2359,7 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS1 || pid == USB_PRODUCT_ID_AIC8800M80_CUS2 || pid == USB_PRODUCT_ID_AIC8800M80_CUS1 || pid == USB_PRODUCT_ID_AIC8800M80_CUS2
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS3 || pid == USB_PRODUCT_ID_AIC8800M80_CUS4 || pid == USB_PRODUCT_ID_AIC8800M80_CUS3 || pid == USB_PRODUCT_ID_AIC8800M80_CUS4
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS5 || pid == USB_PRODUCT_ID_AIC8800M80_CUS6 || pid == USB_PRODUCT_ID_AIC8800M80_CUS5 || pid == USB_PRODUCT_ID_AIC8800M80_CUS6
|| pid == USB_PRODUCT_ID_AIC8800M80_CUS7 || pid == USB_PRODUCT_ID_AIC8800M80_CUS8
|| pid == USB_PRODUCT_ID_AIC8800D80_UGREEN){ || pid == USB_PRODUCT_ID_AIC8800D80_UGREEN){
usb_dev->chipid = PRODUCT_ID_AIC8800D81; usb_dev->chipid = PRODUCT_ID_AIC8800D81;
aicwf_usb_rx_aggr = true; aicwf_usb_rx_aggr = true;
@@ -2652,6 +2660,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_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_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)},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D81X2, 0xff, 0xff, 0xff)}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D81X2, 0xff, 0xff, 0xff)},
@@ -2664,12 +2673,17 @@ static struct usb_device_id aicwf_usb_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS1)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS1)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS2)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS2)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS3)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS3)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS4)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS5)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS6)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS1)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS1)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS2)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS2)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS3)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS3)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS4)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS4)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS5)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS5)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS6)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS6)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS7)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS8)},
{USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80_UGREEN)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80_UGREEN)},
#endif #endif
{} {}
+10 -1
View File
@@ -18,6 +18,8 @@
#define USB_VENDOR_ID_AIC 0xA69C #define USB_VENDOR_ID_AIC 0xA69C
#define USB_VENDOR_ID_AIC_V2 0x368B #define USB_VENDOR_ID_AIC_V2 0x368B
#define USB_VENDOR_ID_TENDA 0x2604 #define USB_VENDOR_ID_TENDA 0x2604
#define USB_VENDOR_ID_TENDA_V2 0x3625
#ifndef CONFIG_USB_BT #ifndef CONFIG_USB_BT
#define USB_PRODUCT_ID_AIC8800 0x8800 #define USB_PRODUCT_ID_AIC8800 0x8800
@@ -39,16 +41,23 @@
#define USB_PRODUCT_ID_TENDA_U2 0x0014 #define USB_PRODUCT_ID_TENDA_U2 0x0014
#define USB_PRODUCT_ID_TENDA_U11 0x001f #define USB_PRODUCT_ID_TENDA_U11 0x001f
#define USB_PRODUCT_ID_TENDA_U11_PRO 0x0020 #define USB_PRODUCT_ID_TENDA_U11_PRO 0x0020
#define USB_PRODUCT_ID_TENDA_TX1U_NANO 0x0110
#define USB_PRODUCT_ID_AIC8800FC_CUS1 0x88df #define USB_PRODUCT_ID_AIC8800FC_CUS1 0x88df
#define USB_PRODUCT_ID_AIC8800FC_CUS2 0x88E0 #define USB_PRODUCT_ID_AIC8800FC_CUS2 0x88E0
#define USB_PRODUCT_ID_AIC8800FC_CUS3 0x88E1 #define USB_PRODUCT_ID_AIC8800FC_CUS3 0x88E1
#define USB_PRODUCT_ID_AIC8800FC_CUS4 0x88E2
#define USB_PRODUCT_ID_AIC8800FC_CUS5 0x88E3
#define USB_PRODUCT_ID_AIC8800FC_CUS6 0x88E5
#define USB_PRODUCT_ID_AIC8800M80_CUS1 0x8D83 #define USB_PRODUCT_ID_AIC8800M80_CUS1 0x8D83
#define USB_PRODUCT_ID_AIC8800M80_CUS2 0x8D85 #define USB_PRODUCT_ID_AIC8800M80_CUS2 0x8D85
#define USB_PRODUCT_ID_AIC8800M80_CUS3 0x8D86 #define USB_PRODUCT_ID_AIC8800M80_CUS3 0x8D86
#define USB_PRODUCT_ID_AIC8800D80_UGREEN 0x8D88
#define USB_PRODUCT_ID_AIC8800M80_CUS4 0x8D89 #define USB_PRODUCT_ID_AIC8800M80_CUS4 0x8D89
#define USB_PRODUCT_ID_AIC8800M80_CUS5 0x8D8A #define USB_PRODUCT_ID_AIC8800M80_CUS5 0x8D8A
#define USB_PRODUCT_ID_AIC8800M80_CUS6 0x8D8C #define USB_PRODUCT_ID_AIC8800M80_CUS6 0x8D8C
#define USB_PRODUCT_ID_AIC8800D80_UGREEN 0x8D88 #define USB_PRODUCT_ID_AIC8800M80_CUS7 0x8D8B
#define USB_PRODUCT_ID_AIC8800M80_CUS8 0x8D8D
#endif #endif
enum AICWF_IC{ enum AICWF_IC{
+1 -1
View File
@@ -41,7 +41,7 @@
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK
#endif #endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 15, 60) #if LINUX_VERSION_CODE > KERNEL_VERSION(5, 18, 0)
#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE #define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE
#endif #endif
+26 -22
View File
@@ -2036,11 +2036,11 @@ void aicwf_p2p_alive_timeout(struct timer_list *t)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
rwnx_vif = (struct rwnx_vif *)data; rwnx_vif = (struct rwnx_vif *)data;
rwnx_hw = rwnx_vif->rwnx_hw; rwnx_hw = rwnx_vif->rwnx_hw;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0) #elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0)
rwnx_hw = timer_container_of(rwnx_hw, t, p2p_alive_timer); rwnx_hw = from_timer(rwnx_hw, t, p2p_alive_timer);
rwnx_vif = rwnx_hw->p2p_dev_vif; rwnx_vif = rwnx_hw->p2p_dev_vif;
#else #else
rwnx_hw = from_timer(rwnx_hw, t, p2p_alive_timer); rwnx_hw = timer_container_of(rwnx_hw, t, p2p_alive_timer);
rwnx_vif = rwnx_hw->p2p_dev_vif; rwnx_vif = rwnx_hw->p2p_dev_vif;
#endif #endif
@@ -2233,10 +2233,10 @@ static void aicwf_pwrloss_timer(struct timer_list *t)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
rwnx_vif = (struct rwnx_vif *)data; rwnx_vif = (struct rwnx_vif *)data;
rwnx_hw = rwnx_vif->rwnx_hw; rwnx_hw = rwnx_vif->rwnx_hw;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0) #elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0)
rwnx_hw = timer_container_of(rwnx_hw, t, pwrloss_timer);
#else
rwnx_hw = from_timer(rwnx_hw, t, pwrloss_timer); rwnx_hw = from_timer(rwnx_hw, t, pwrloss_timer);
#else
rwnx_hw = timer_container_of(rwnx_hw, t, pwrloss_timer);
#endif #endif
if (!work_pending(&rwnx_hw->pwrloss_work)) if (!work_pending(&rwnx_hw->pwrloss_work))
schedule_work(&rwnx_hw->pwrloss_work); schedule_work(&rwnx_hw->pwrloss_work);
@@ -2682,8 +2682,8 @@ static void rwnx_cfgp2p_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev
if (rwnx_vif == rwnx_hw->p2p_dev_vif) { if (rwnx_vif == rwnx_hw->p2p_dev_vif) {
rwnx_hw->is_p2p_alive = 0; rwnx_hw->is_p2p_alive = 0;
if (timer_pending(&rwnx_hw->p2p_alive_timer)) { if (timer_pending(&rwnx_hw->p2p_alive_timer)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
timer_delete_sync(&rwnx_hw->p2p_alive_timer); timer_delete_sync(&rwnx_hw->p2p_alive_timer);
#else #else
del_timer_sync(&rwnx_hw->p2p_alive_timer); del_timer_sync(&rwnx_hw->p2p_alive_timer);
#endif #endif
@@ -4092,12 +4092,13 @@ static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
#ifdef CONFIG_BAND_STEERING #ifdef CONFIG_BAND_STEERING
rwnx_vif->ap.start = false; rwnx_vif->ap.start = false;
aicwf_nl_hook_deinit(rwnx_vif->ap.band, rwnx_vif->rwnx_hw->iface_idx); aicwf_nl_hook_deinit(rwnx_vif->ap.band, rwnx_vif->rwnx_hw->iface_idx);
if (timer_pending(&rwnx_vif->steer_timer)) if (timer_pending(&rwnx_vif->steer_timer)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
timer_delete_sync(&rwnx_vif->steer_timer); timer_delete_sync(&rwnx_vif->steer_timer);
#else #else
del_timer_sync(&rwnx_vif->steer_timer); del_timer_sync(&rwnx_vif->steer_timer);
#endif #endif
}
cancel_work_sync(&rwnx_vif->steer_work); cancel_work_sync(&rwnx_vif->steer_work);
flush_workqueue(rwnx_vif->rsp_wq); flush_workqueue(rwnx_vif->rsp_wq);
destroy_workqueue(rwnx_vif->rsp_wq); destroy_workqueue(rwnx_vif->rsp_wq);
@@ -4278,11 +4279,11 @@ 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.
*/ */
static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, u32 changed)
int radio_idx, #else
#endif static int rwnx_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
u32 changed) #endif
{ {
return 0; return 0;
} }
@@ -4300,7 +4301,7 @@ static int rwnx_cfg80211_set_tx_power(struct wiphy *wiphy,
struct wireless_dev *wdev, struct wireless_dev *wdev,
#endif #endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
int radio_idx, int radio_idx,
#endif #endif
enum nl80211_tx_power_setting type, int mbm) enum nl80211_tx_power_setting type, int mbm)
{ {
@@ -9037,11 +9038,13 @@ void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw)
#ifdef CONFIG_DYNAMIC_PWR #ifdef CONFIG_DYNAMIC_PWR
if(timer_pending(&rwnx_hw->pwrloss_timer)){ if(timer_pending(&rwnx_hw->pwrloss_timer)){
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
timer_delete_sync(&rwnx_hw->pwrloss_timer); timer_delete_sync(&rwnx_hw->pwrloss_timer);
#else #else
del_timer_sync(&rwnx_hw->pwrloss_timer); del_timer_sync(&rwnx_hw->pwrloss_timer);
#endif #endif
}
cancel_work_sync(&rwnx_hw->pwrloss_work); cancel_work_sync(&rwnx_hw->pwrloss_work);
#endif #endif
@@ -9054,12 +9057,13 @@ void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw)
if (!list_empty(&rwnx_hw->defrag_list)) { if (!list_empty(&rwnx_hw->defrag_list)) {
list_for_each_entry(defrag_ctrl, &rwnx_hw->defrag_list, list) { list_for_each_entry(defrag_ctrl, &rwnx_hw->defrag_list, list) {
list_del_init(&defrag_ctrl->list); list_del_init(&defrag_ctrl->list);
if (timer_pending(&defrag_ctrl->defrag_timer)) if (timer_pending(&defrag_ctrl->defrag_timer)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
timer_delete_sync(&defrag_ctrl->defrag_timer); timer_delete_sync(&defrag_ctrl->defrag_timer);
#else #else
del_timer_sync(&defrag_ctrl->defrag_timer); del_timer_sync(&defrag_ctrl->defrag_timer);
#endif #endif
}
dev_kfree_skb(defrag_ctrl->skb); dev_kfree_skb(defrag_ctrl->skb);
kfree(defrag_ctrl); kfree(defrag_ctrl);
} }
+28 -27
View File
@@ -481,7 +481,9 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
rwnx_rxdata_process_amsdu(rwnx_hw, skb, flags_vif_idx, &list); rwnx_rxdata_process_amsdu(rwnx_hw, skb, flags_vif_idx, &list);
#else #else
int count; int count;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) // Debian 6.1.0-26 backported the new function call, but not Ubuntu 6.2.
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 109) && LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0))
ieee80211_amsdu_to_8023s(skb, &list, rwnx_vif->ndev->dev_addr, ieee80211_amsdu_to_8023s(skb, &list, rwnx_vif->ndev->dev_addr,
RWNX_VIF_TYPE(rwnx_vif), 0, NULL, NULL, false); RWNX_VIF_TYPE(rwnx_vif), 0, NULL, NULL, false);
#else #else
@@ -1584,12 +1586,13 @@ int reord_flush_tid(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u8 tid)
AICWFDBG(LOGINFO, "flush:tid=%d", tid); AICWFDBG(LOGINFO, "flush:tid=%d", tid);
preorder_ctrl->enable = false; preorder_ctrl->enable = false;
spin_unlock_irqrestore(&preorder_ctrl->reord_list_lock, flags); spin_unlock_irqrestore(&preorder_ctrl->reord_list_lock, flags);
if (timer_pending(&preorder_ctrl->reord_timer)) if (timer_pending(&preorder_ctrl->reord_timer)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
ret = timer_delete_sync(&preorder_ctrl->reord_timer); ret = timer_delete_sync(&preorder_ctrl->reord_timer);
#else #else
ret = del_timer_sync(&preorder_ctrl->reord_timer); ret = del_timer_sync(&preorder_ctrl->reord_timer);
#endif #endif
}
cancel_work_sync(&preorder_ctrl->reord_timer_work); cancel_work_sync(&preorder_ctrl->reord_timer_work);
return 0; return 0;
@@ -1615,8 +1618,8 @@ void reord_deinit_sta(struct aicwf_rx_priv* rx_priv, struct reord_ctrl_info *reo
if(preorder_ctrl->enable){ if(preorder_ctrl->enable){
preorder_ctrl->enable = false; preorder_ctrl->enable = false;
if (timer_pending(&preorder_ctrl->reord_timer)) { if (timer_pending(&preorder_ctrl->reord_timer)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
ret = timer_delete_sync(&preorder_ctrl->reord_timer); ret = timer_delete_sync(&preorder_ctrl->reord_timer);
#else #else
ret = del_timer_sync(&preorder_ctrl->reord_timer); ret = del_timer_sync(&preorder_ctrl->reord_timer);
#endif #endif
@@ -1868,10 +1871,10 @@ void reord_timeout_handler (struct timer_list *t)
{ {
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
struct reord_ctrl *preorder_ctrl = (struct reord_ctrl *)data; struct reord_ctrl *preorder_ctrl = (struct reord_ctrl *)data;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0) #elif LINUX_VERSION_CODE < KERNEL_VERSION(6,16,0)
struct reord_ctrl *preorder_ctrl = timer_container_of(preorder_ctrl, t, reord_timer);
#else
struct reord_ctrl *preorder_ctrl = from_timer(preorder_ctrl, t, reord_timer); struct reord_ctrl *preorder_ctrl = from_timer(preorder_ctrl, t, reord_timer);
#else
struct reord_ctrl *preorder_ctrl = timer_container_of(preorder_ctrl, t, reord_timer);
#endif #endif
AICWFDBG(LOGTRACE, "%s Enter \r\n", __func__); AICWFDBG(LOGTRACE, "%s Enter \r\n", __func__);
@@ -2031,8 +2034,8 @@ int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv,
} }
} else { } else {
if(timer_pending(&preorder_ctrl->reord_timer)) { if(timer_pending(&preorder_ctrl->reord_timer)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
ret = timer_delete(&preorder_ctrl->reord_timer); ret = timer_delete(&preorder_ctrl->reord_timer);
#else #else
ret = del_timer(&preorder_ctrl->reord_timer); ret = del_timer(&preorder_ctrl->reord_timer);
#endif #endif
@@ -2199,10 +2202,10 @@ void defrag_timeout_cb(struct timer_list *t)
struct defrag_ctrl_info *defrag_ctrl = NULL; struct defrag_ctrl_info *defrag_ctrl = NULL;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
defrag_ctrl = (struct defrag_ctrl_info *)data; defrag_ctrl = (struct defrag_ctrl_info *)data;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0) #elif LINUX_VERSION_CODE < KERNEL_VERSION(6,16,0)
defrag_ctrl = timer_container_of(defrag_ctrl, t, defrag_timer);
#else
defrag_ctrl = from_timer(defrag_ctrl, t, defrag_timer); defrag_ctrl = from_timer(defrag_ctrl, t, defrag_timer);
#else
defrag_ctrl = timer_container_of(defrag_ctrl, t, defrag_timer);
#endif #endif
printk("%s:%p\r\n", __func__, defrag_ctrl); printk("%s:%p\r\n", __func__, defrag_ctrl);
@@ -2368,11 +2371,11 @@ 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 LINUX_VERSION_CODE < KERNEL_VERSION(6, 17, 0) #if LINUX_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); cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC);
#else #endif
cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, UNKNOWN_LINK_ID, GFP_ATOMIC);
#endif
} }
goto end; goto end;
} }
@@ -2567,8 +2570,8 @@ check_len_update:
skb_tmp = defrag_info->skb; skb_tmp = defrag_info->skb;
list_del_init(&defrag_info->list); list_del_init(&defrag_info->list);
if (timer_pending(&defrag_info->defrag_timer)) { if (timer_pending(&defrag_info->defrag_timer)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
ret = timer_delete(&defrag_info->defrag_timer); ret = timer_delete(&defrag_info->defrag_timer);
#else #else
ret = del_timer(&defrag_info->defrag_timer); ret = del_timer(&defrag_info->defrag_timer);
#endif #endif
@@ -2622,15 +2625,13 @@ check_len_update:
} }
if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) { if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 17, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
sta->mac_addr, -1, GFP_ATOMIC);
#else
cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev, cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
sta->mac_addr, GFP_ATOMIC); sta->mac_addr, GFP_ATOMIC);
#else #endif
cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
sta->mac_addr,
UNKNOWN_LINK_ID,
GFP_ATOMIC);
#endif
} }
} }
-4
View File
@@ -405,8 +405,4 @@ struct element {
#endif #endif
#endif #endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
#define UNKNOWN_LINK_ID -1
#endif
#endif /* _RWNX_RX_H_ */ #endif /* _RWNX_RX_H_ */
@@ -1,5 +1,5 @@
#define RWNX_VERS_REV "1a4b0054d2M (master)" #define RWNX_VERS_REV "1a4b0054d2M (master)"
#define RWNX_VERS_MOD "6.4.3.0" #define RWNX_VERS_MOD "6.4.3.0"
#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)" #define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)"
#define RELEASE_DATE "2025_0423_71b66e7b" #define RELEASE_DATE "2025_1018_71b66e7b"
+17 -10
View File
@@ -9,15 +9,12 @@
#include "rwnx_defs.h" #include "rwnx_defs.h"
#include "rwnx_wakelock.h" #include "rwnx_wakelock.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0)
struct wakeup_source *rwnx_wakeup_init(const char *name) struct wakeup_source *rwnx_wakeup_init(const char *name)
{ {
struct wakeup_source *ws; struct wakeup_source *ws;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
ws = wakeup_source_register(NULL, name);
#else
ws = wakeup_source_create(name); ws = wakeup_source_create(name);
wakeup_source_add(ws); wakeup_source_add(ws);
#endif
return ws; return ws;
} }
@@ -25,15 +22,10 @@ void rwnx_wakeup_deinit(struct wakeup_source *ws)
{ {
if (ws && ws->active) if (ws && ws->active)
__pm_relax(ws); __pm_relax(ws);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
wakeup_source_unregister(ws);
#else
wakeup_source_remove(ws); wakeup_source_remove(ws);
wakeup_source_destroy(ws); wakeup_source_destroy(ws);
#endif
} }
#endif
struct wakeup_source *rwnx_wakeup_register(struct device *dev, const char *name) struct wakeup_source *rwnx_wakeup_register(struct device *dev, const char *name)
{ {
@@ -81,18 +73,33 @@ void rwnx_wakeup_lock_timeout(struct wakeup_source *ws, unsigned int msec)
void aicwf_wakeup_lock_init(struct rwnx_hw *rwnx_hw) void aicwf_wakeup_lock_init(struct rwnx_hw *rwnx_hw)
{ {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
struct aic_usb_dev *usbdev = rwnx_hw->usbdev;
rwnx_hw->ws_tx = rwnx_wakeup_register(usbdev->dev, "rwnx_tx_wakelock");
rwnx_hw->ws_rx = rwnx_wakeup_register(usbdev->dev,"rwnx_rx_wakelock");
rwnx_hw->ws_irqrx = rwnx_wakeup_register(usbdev->dev, "rwnx_irqrx_wakelock");
rwnx_hw->ws_pwrctrl = rwnx_wakeup_register(usbdev->dev, "rwnx_pwrcrl_wakelock");
#else
rwnx_hw->ws_tx = rwnx_wakeup_init("rwnx_tx_wakelock"); rwnx_hw->ws_tx = rwnx_wakeup_init("rwnx_tx_wakelock");
rwnx_hw->ws_rx = rwnx_wakeup_init("rwnx_rx_wakelock"); rwnx_hw->ws_rx = rwnx_wakeup_init("rwnx_rx_wakelock");
rwnx_hw->ws_irqrx = rwnx_wakeup_init("rwnx_irqrx_wakelock"); rwnx_hw->ws_irqrx = rwnx_wakeup_init("rwnx_irqrx_wakelock");
rwnx_hw->ws_pwrctrl = rwnx_wakeup_init("rwnx_pwrcrl_wakelock"); rwnx_hw->ws_pwrctrl = rwnx_wakeup_init("rwnx_pwrcrl_wakelock");
#endif
} }
void aicwf_wakeup_lock_deinit(struct rwnx_hw *rwnx_hw) void aicwf_wakeup_lock_deinit(struct rwnx_hw *rwnx_hw)
{ {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
rwnx_wakeup_unregister(rwnx_hw->ws_tx);
rwnx_wakeup_unregister(rwnx_hw->ws_rx);
rwnx_wakeup_unregister(rwnx_hw->ws_irqrx);
rwnx_wakeup_unregister(rwnx_hw->ws_pwrctrl);
#else
rwnx_wakeup_deinit(rwnx_hw->ws_tx); rwnx_wakeup_deinit(rwnx_hw->ws_tx);
rwnx_wakeup_deinit(rwnx_hw->ws_rx); rwnx_wakeup_deinit(rwnx_hw->ws_rx);
rwnx_wakeup_deinit(rwnx_hw->ws_irqrx); rwnx_wakeup_deinit(rwnx_hw->ws_irqrx);
rwnx_wakeup_deinit(rwnx_hw->ws_pwrctrl); rwnx_wakeup_deinit(rwnx_hw->ws_pwrctrl);
#endif
rwnx_hw->ws_tx = NULL; rwnx_hw->ws_tx = NULL;
rwnx_hw->ws_rx = NULL; rwnx_hw->ws_rx = NULL;
rwnx_hw->ws_irqrx = NULL; rwnx_hw->ws_irqrx = NULL;
+7 -8
View File
@@ -67,7 +67,7 @@ ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
#ARCH ?= arm #ARCH ?= arm
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- #CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
KDIR := /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/kernel KDIR := /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/kernel
ARCH ?= arm ARCH ?=$(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
#KDIR := /home/yaya/E/Rockchip/3399/rk3399-android-10/kernel #KDIR := /home/yaya/E/Rockchip/3399/rk3399-android-10/kernel
#ARCH ?= arm64 #ARCH ?= arm64
@@ -91,13 +91,12 @@ endif
ifeq ($(CONFIG_PLATFORM_UBUNTU), y) ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU
KDIR := /lib/modules/$(shell uname -r)/build KVER := $(or $(KVER), $(kernelver), $(KERNELRELEASE), $(shell uname -r))
PWD := $(shell pwd) KDIR ?= /lib/modules/$(KVER)/build
KVER := $(shell uname -r) PWD ?= $(shell pwd)
MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800 MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/) ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
ARCH ?= $(SUBARCH) CROSS_COMPILE ?=
CROSS_COMPILE :=
endif endif
@@ -408,7 +408,7 @@ int rwnx_send_dbg_mem_write_req(struct aic_usb_dev *usbdev, u32 mem_addr, u32 me
{ {
struct dbg_mem_write_req *mem_write_req; struct dbg_mem_write_req *mem_write_req;
//printk("%s mem_addr:%x mem_data:%x\r\n", __func__, mem_addr, mem_data); // printk("%s mem_addr:%x mem_data:%x\r\n", __func__, mem_addr, mem_data);
/* Build the DBG_MEM_WRITE_REQ message */ /* Build the DBG_MEM_WRITE_REQ message */
mem_write_req = rwnx_msg_zalloc(DBG_MEM_WRITE_REQ, TASK_DBG, DRV_TASK_ID, mem_write_req = rwnx_msg_zalloc(DBG_MEM_WRITE_REQ, TASK_DBG, DRV_TASK_ID,
Regular → Executable
+401 -283
View File
@@ -1,438 +1,556 @@
#!/bin/bash #!/bin/bash
# Cores for output #############################################################################
RED='\033[0;31m' # AIC8800D80 WiFi 6 Driver - Universal Installer (DKMS) - VERSÃO CORRIGIDA
GREEN='\033[0;32m' # Version: 2.0.4
YELLOW='\033[1;33m' # Date: 2025-12-30
BLUE='\033[0;34m' # Description: Multi-distribution installer with DKMS support
CYAN='\033[0;36m' # Supported: Debian/Ubuntu, Fedora/RHEL, Arch Linux, and derivatives
NC='\033[0m' # No Color # FIX: Corrected DKMS module configuration for aic8800_fdrv
#############################################################################
# Variables set -e # Exit on error
DRIVER_REPO="https://github.com/shenmintao/aic8800d80.git"
DRIVER_DIR="$HOME/aic8800d80" # Color definitions
LOG_FILE="/tmp/aic8800d80_install.log" readonly RED='\033[0;31m'
MODULE_NAME="aic8800_fdrv" readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly CYAN='\033[0;36m'
readonly NC='\033[0m' # No Color
# Driver configuration
readonly DRV_NAME="aic8800"
readonly DRV_VERSION="1.0.0"
readonly SRC_DIR="/usr/src/${DRV_NAME}-${DRV_VERSION}"
readonly MODULE_NAME="aic8800_fdrv"
readonly LOG_FILE="/tmp/aic8800d80_install.log"
# Script directory (where the script is located)
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
#############################################################################
# Logging and Output Functions
#############################################################################
log_message() {
local level="$1"
shift
# Garantir que o arquivo de log existe e tem permissões corretas
if [ ! -f "$LOG_FILE" ]; then
touch "$LOG_FILE" 2>/dev/null || true
chmod 666 "$LOG_FILE" 2>/dev/null || true
fi
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $*" >> "$LOG_FILE" 2>/dev/null || true
}
# Auxiliary functions
print_info() { print_info() {
echo -e "${BLUE}[INFO]${NC} $1" echo -e "${BLUE}[INFO]${NC} $1"
echo "[INFO] $1" >> "$LOG_FILE" log_message "INFO" "$1"
} }
print_success() { print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1" echo -e "${GREEN}[SUCCESS]${NC} $1"
echo "[SUCCESS] $1" >> "$LOG_FILE" log_message "SUCCESS" "$1"
} }
print_warning() { print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1" echo -e "${YELLOW}[WARNING]${NC} $1"
echo "[WARNING] $1" >> "$LOG_FILE" log_message "WARNING" "$1"
} }
print_error() { print_error() {
echo -e "${RED}[ERROR]${NC} $1" echo -e "${RED}[ERROR]${NC} $1"
echo "[ERROR] $1" >> "$LOG_FILE" log_message "ERROR" "$1"
} }
print_step() { print_step() {
echo -e "\n${CYAN}==>${NC} ${1}" echo ""
echo "==> $1" >> "$LOG_FILE" echo -e "${CYAN}==>${NC} ${1}"
log_message "STEP" "$1"
} }
# Function to check if the command was successful #############################################################################
check_success() { # Error Handling
if [ $? -eq 0 ]; then #############################################################################
print_success "$1"
return 0 cleanup_on_error() {
else print_error "Installation failed. Check $LOG_FILE for details."
print_error "$2" exit 1
return 1 }
trap cleanup_on_error ERR
#############################################################################
# Root Privilege Check
#############################################################################
check_root() {
if [ "$EUID" -ne 0 ]; then
print_error "This script must be run as root (use sudo)"
echo ""
echo "Usage: sudo ./install.sh"
exit 1
fi fi
} }
############################################################################# #############################################################################
# Check Secure Boot # Secure Boot Detection
############################################################################# #############################################################################
check_secure_boot() { check_secure_boot() {
print_step "Checking Secure Boot status..." print_step "Checking Secure Boot status..."
# Method 1: Check via mokutil (more reliable) local secure_boot_enabled=false
# Method 1: Check via mokutil
if command -v mokutil &> /dev/null; then if command -v mokutil &> /dev/null; then
SECURE_BOOT_STATUS=$(mokutil --sb-state 2>/dev/null | grep -i "SecureBoot" | awk '{print $2}') if mokutil --sb-state 2>/dev/null | grep -qi "SecureBoot enabled"; then
secure_boot_enabled=true
if [[ "$SECURE_BOOT_STATUS" == "enabled" ]]; then
print_error "Secure Boot is ENABLED!"
echo ""
echo -e "${RED}╔════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${RED}║ SECURE BOOT IS ENABLED - INSTALLATION CANNOT PROCEED ║${NC}"
echo -e "${RED}╚════════════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${YELLOW}Why does Secure Boot need to be disabled?${NC}"
echo ""
echo "Secure Boot is a security feature of UEFI that prevents the loading"
echo "of unsigned kernel modules. The AIC8800D80 driver is a custom module"
echo "compiled locally and does not have a digital signature recognized by the system."
echo ""
echo -e "${CYAN}How to disable Secure Boot:${NC}"
echo ""
echo "1. Restart the computer"
echo "2. Enter the BIOS/UEFI (usually pressing DEL, F2, F10 or ESC)"
echo "3. Search for 'Secure Boot' in the settings (usually in Security)"
echo "4. Change from 'Enabled' to 'Disabled'"
echo "5. Save the settings and restart (usually F10)"
echo "6. Execute this script again"
echo ""
echo -e "${YELLOW}Note:${NC} Disabling Secure Boot is safe for personal use, but"
echo " slightly reduces security against bootrootkits."
echo ""
return 1
else
print_success "Secure Boot is disabled. Proceeding..."
return 0
fi fi
fi fi
# Method 2: Check via /sys/firmware/efi/efivars (fallback) # Method 2: Check via EFI variables (fallback)
if [ -d /sys/firmware/efi/efivars ]; then if [ "$secure_boot_enabled" = false ] && [ -d /sys/firmware/efi ]; then
if [ -f /sys/firmware/efi/efivars/SecureBoot-* ]; then local secureboot_files=(/sys/firmware/efi/efivars/SecureBoot-*)
SB_VALUE=$(od -An -t u1 /sys/firmware/efi/efivars/SecureBoot-* | awk '{print $NF}') if [ -f "${secureboot_files[0]}" ]; then
if [ "$SB_VALUE" = "1" ]; then local sb_value
print_error "Secure Boot is ENABLED (detected via EFI vars)!" sb_value=$(od -An -t u1 "${secureboot_files[0]}" 2>/dev/null | awk '{print $NF}')
echo "" if [ "$sb_value" = "1" ]; then
echo -e "${RED}Secure Boot needs to be disabled to install this driver.${NC}" secure_boot_enabled=true
echo "See the instructions above on how to disable it."
return 1
else
print_success "Secure Boot is disabled (verified via EFI vars)."
return 0
fi fi
fi fi
fi fi
# Method 3: Check via dmesg (last resort) if [ "$secure_boot_enabled" = true ]; then
DMESG_SB=$(dmesg | grep -i "secure boot" | grep -i "enabled") echo ""
if [ -n "$DMESG_SB" ]; then echo -e "${YELLOW}╔════════════════════════════════════════════════════════════════╗${NC}"
print_warning "Secure Boot may be enabled (detected via dmesg)." echo -e "${YELLOW}║ SECURE BOOT IS ENABLED ║${NC}"
echo "Please check manually and disable if necessary." echo -e "${YELLOW}╚════════════════════════════════════════════════════════════════╝${NC}"
read -p "Do you want to continue anyway? (y/N): " choice echo ""
if [[ ! "$choice" =~ ^[Ss]$ ]]; then echo "The driver may not load automatically due to Secure Boot restrictions."
return 1 echo "Third-party modules require signing or Secure Boot must be disabled."
echo ""
echo -e "${CYAN}Options:${NC}"
echo " 1. Disable Secure Boot in BIOS/UEFI settings (recommended)"
echo " 2. Sign the module manually (advanced)"
echo " 3. Continue installation anyway (module may fail to load)"
echo ""
read -p "Continue installation? (y/N): " choice
if [[ ! "$choice" =~ ^[Yy]$ ]]; then
print_info "Installation cancelled by user."
exit 0
fi fi
print_warning "Continuing with Secure Boot enabled..."
else
print_success "Secure Boot is disabled or not present."
fi fi
print_success "Secure Boot verification completed."
return 0
} }
############################################################################# #############################################################################
# Check requirements # Package Manager Detection and Dependency Installation
############################################################################# #############################################################################
check_requirements() { detect_package_manager() {
print_step "Checking system requirements..." print_step "Detecting package manager and distribution..."
# Verificar se é root local pkg_manager=""
if [ "$EUID" -eq 0 ]; then local distro_name=""
print_error "This script MUST NOT be run as root!"
echo "Run as a normal user. The script will request sudo when necessary." if command -v apt-get &> /dev/null; then
pkg_manager="apt"
distro_name="Debian/Ubuntu"
elif command -v dnf &> /dev/null; then
pkg_manager="dnf"
distro_name="Fedora/RHEL"
elif command -v yum &> /dev/null; then
pkg_manager="yum"
distro_name="CentOS/RHEL (legacy)"
elif command -v pacman &> /dev/null; then
pkg_manager="pacman"
distro_name="Arch Linux"
elif command -v zypper &> /dev/null; then
pkg_manager="zypper"
distro_name="openSUSE"
else
print_error "No supported package manager found!"
echo ""
echo "Please install the following packages manually:"
echo " - dkms"
echo " - build-essential / base-devel / development tools"
echo " - linux-headers for your kernel version"
echo " - mokutil (optional, for Secure Boot detection)"
echo ""
exit 1 exit 1
fi fi
# Check kernel print_success "Detected: $distro_name ($pkg_manager)"
KERNEL_VERSION=$(uname -r) DETECTED_PKG_MANAGER="$pkg_manager"
print_info "Kernel detected: $KERNEL_VERSION"
# Check if has access to sudo
if ! sudo -n true 2>/dev/null; then
print_info "This script requires sudo privileges."
sudo -v || { print_error "Failed to obtain sudo privileges."; exit 1; }
fi
print_success "Basic requirements met."
} }
#############################################################################
# Install dependencies
#############################################################################
install_dependencies() { install_dependencies() {
print_step "Installing necessary dependencies..." local pkg_manager="$1"
# Update package list print_step "Installing dependencies..."
print_info "Updating package list..."
sudo apt update >> "$LOG_FILE" 2>&1
check_success "Package list updated" "Failed to update package list"
# List of dependencies case "$pkg_manager" in
DEPENDENCIES=( apt)
"git" print_info "Updating package database..."
"build-essential" apt-get update -qq >> "$LOG_FILE" 2>&1
"dkms"
"bc" print_info "Installing: dkms, build-essential, linux-headers, mokutil..."
"linux-headers-$(uname -r)" apt-get install -y dkms build-essential linux-headers-$(uname -r) mokutil >> "$LOG_FILE" 2>&1
"mokutil" ;;
)
dnf)
print_info "Installing: dkms, gcc, make, kernel-devel, kernel-headers, mokutil..."
dnf install -y dkms make gcc kernel-devel kernel-headers mokutil >> "$LOG_FILE" 2>&1
;;
yum)
print_info "Installing: dkms, gcc, make, kernel-devel, mokutil..."
yum install -y epel-release >> "$LOG_FILE" 2>&1
yum install -y dkms make gcc kernel-devel mokutil >> "$LOG_FILE" 2>&1
;;
pacman)
print_info "Syncing package database..."
pacman -Sy --noconfirm >> "$LOG_FILE" 2>&1
print_info "Installing: dkms, base-devel, linux-headers, mokutil..."
pacman -S --noconfirm dkms base-devel linux-headers mokutil >> "$LOG_FILE" 2>&1
;;
zypper)
print_info "Installing: dkms, gcc, make, kernel-devel, mokutil..."
zypper install -y dkms make gcc kernel-devel mokutil >> "$LOG_FILE" 2>&1
;;
*)
print_error "Unsupported package manager: $pkg_manager"
exit 1
;;
esac
print_info "Installing: ${DEPENDENCIES[*]}" print_success "Dependencies installed successfully."
sudo apt install -y "${DEPENDENCIES[@]}" >> "$LOG_FILE" 2>&1
check_success "Dependencies installed" "Failed to install dependencies"
} }
############################################################################# #############################################################################
# Download driver # Firmware Installation
############################################################################# #############################################################################
download_driver() { install_firmware() {
print_step "Downloading AIC8800D80 driver..." print_step "Installing firmware..."
# If the directory already exists, ask if you want to update local fw_source="${SCRIPT_DIR}/fw/aic8800D80"
if [ -d "$DRIVER_DIR" ]; then local fw_dest="/lib/firmware/aic8800D80"
print_warning "Directory $DRIVER_DIR already exists."
read -p "Do you want to remove and download again? (y/N): " choice
if [[ "$choice" =~ ^[Ss]$ ]]; then
print_info "Removing old directory..."
rm -rf "$DRIVER_DIR"
check_success "Old directory removed" "Failed to remove old directory"
else
print_info "Using existing directory."
cd "$DRIVER_DIR" || exit 1
git pull >> "$LOG_FILE" 2>&1
print_info "Repository updated."
return 0
fi
fi
# Clone repository if [ ! -d "$fw_source" ]; then
print_info "Cloning repository..." print_error "Firmware directory not found: $fw_source"
cd "$HOME" || exit 1 echo "Please ensure you're running the script from the repository root."
git clone "$DRIVER_REPO" >> "$LOG_FILE" 2>&1
check_success "Repository cloned successfully" "Failed to clone repository" || exit 1
cd "$DRIVER_DIR" || exit 1
}
#############################################################################
# Installation of driver
#############################################################################
install_driver() {
print_step "Installing AIC8800D80 driver..."
cd "$DRIVER_DIR" || { print_error "Driver directory not found!"; exit 1; }
# Step 1: Copy udev rules
print_info "Copying udev rules..."
sudo cp aic.rules /lib/udev/rules.d/ >> "$LOG_FILE" 2>&1
check_success "Udev rules copied" "Failed to copy udev rules"
# Step 2: Remove old firmwares (IMPORTANT!)
print_info "Removing old firmwares (prevents freezes)..."
sudo rm -rf /lib/firmware/aic8800* >> "$LOG_FILE" 2>&1
print_success "Old firmwares removed"
# Step 3: Copy new firmware
print_info "Copying new firmware AIC8800D80..."
sudo cp -r ./fw/aic8800D80 /lib/firmware/ >> "$LOG_FILE" 2>&1
check_success "Firmware copied" "Failed to copy firmware" || exit 1
# Step 4: Navigate to driver directory
print_info "Navigating to driver directory..."
cd ./drivers/aic8800 || { print_error "Driver directory drivers/aic8800 not found!"; exit 1; }
# Check if Makefile exists
if [ ! -f "Makefile" ]; then
print_error "Makefile not found in $(pwd)"
exit 1 exit 1
fi fi
# Step 5: Compile driver # Remove old firmware versions
print_info "Compiling driver (this may take a few minutes)..." if [ -d "$fw_dest" ]; then
make >> "$LOG_FILE" 2>&1 print_info "Removing existing firmware..."
if [ -d "/lib/firmware" ] && [ -n "$(find /lib/firmware -maxdepth 1 -name 'aic8800*' -type d 2>/dev/null)" ]; then
if [ $? -ne 0 ]; then rm -rf /lib/firmware/aic8800* >> "$LOG_FILE" 2>&1
print_warning "Compilation failed with default GCC. Trying with gcc-12..." fi
make clean >> "$LOG_FILE" 2>&1
make CC=gcc-12 >> "$LOG_FILE" 2>&1
check_success "Driver compiled with gcc-12" "Failed to compile driver" || exit 1
else
print_success "Driver compiled successfully"
fi fi
# Step 6: Install driver # Copy new firmware
print_info "Installing driver..." print_info "Copying firmware to $fw_dest..."
sudo make install >> "$LOG_FILE" 2>&1 cp -r "$fw_source" "$fw_dest" >> "$LOG_FILE" 2>&1
check_success "Driver installed" "Failed to install driver" || exit 1
print_success "Firmware installed successfully."
} }
############################################################################# #############################################################################
# Configure automatic loading # DKMS Configuration - CORRIGIDO v2.0.4
############################################################################# #############################################################################
configure_autoload() { create_dkms_conf() {
print_step "Configuring automatic loading on boot..." print_step "Configuring DKMS..."
# Add module to /etc/modules local dkms_conf="${SCRIPT_DIR}/dkms.conf"
if ! grep -q "^$MODULE_NAME$" /etc/modules 2>/dev/null; then
echo "$MODULE_NAME" | sudo tee -a /etc/modules >> "$LOG_FILE" 2>&1 # Check if dkms.conf already exists
print_success "Module added to /etc/modules" if [ -f "$dkms_conf" ]; then
else print_info "DKMS configuration file already exists."
print_info "Module already configured in /etc/modules" return 0
fi fi
# Create configuration file modules-load.d print_info "Creating dkms.conf..."
echo "$MODULE_NAME" | sudo tee /etc/modules-load.d/aic8800.conf >> "$LOG_FILE" 2>&1
print_success "Configuration file created in /etc/modules-load.d/" # CORRIGIDO: Configuração para múltiplos módulos
cat > "$dkms_conf" << EOF
PACKAGE_NAME="${DRV_NAME}"
PACKAGE_VERSION="${DRV_VERSION}"
CLEAN="cd drivers/aic8800 && make clean"
MAKE="cd drivers/aic8800 && make"
# Módulo principal (aic8800_fdrv)
BUILT_MODULE_NAME[0]="aic8800_fdrv"
BUILT_MODULE_LOCATION[0]="drivers/aic8800/aic8800_fdrv"
DEST_MODULE_LOCATION[0]="/updates/dkms"
# Módulo de carregamento de firmware (aic_load_fw)
BUILT_MODULE_NAME[1]="aic_load_fw"
BUILT_MODULE_LOCATION[1]="drivers/aic8800/aic_load_fw"
DEST_MODULE_LOCATION[1]="/updates/dkms"
AUTOINSTALL="yes"
EOF
print_success "DKMS configuration created."
} }
############################################################################# #############################################################################
# Load module # DKMS Installation
#############################################################################
install_via_dkms() {
print_step "Installing driver via DKMS..."
# Remove existing DKMS installation if present
if dkms status | grep -q "${DRV_NAME}/${DRV_VERSION}"; then
print_info "Removing existing DKMS installation..."
dkms remove "${DRV_NAME}/${DRV_VERSION}" --all >> "$LOG_FILE" 2>&1 || true
fi
# Clean up old source directory
if [ -n "$SRC_DIR" ] && [ -d "$SRC_DIR" ]; then
print_info "Cleaning up old source directory..."
rm -rf "$SRC_DIR"
fi
# Copy source to /usr/src
print_info "Copying source files to $SRC_DIR..."
mkdir -p "$SRC_DIR"
cp -r "${SCRIPT_DIR}"/* "$SRC_DIR/" >> "$LOG_FILE" 2>&1
# Add to DKMS
print_info "Adding module to DKMS..."
dkms add -m "${DRV_NAME}" -v "${DRV_VERSION}" >> "$LOG_FILE" 2>&1
# Build with DKMS
print_info "Building module (this may take a few minutes)..."
if ! dkms build -m "${DRV_NAME}" -v "${DRV_VERSION}" >> "$LOG_FILE" 2>&1; then
print_error "DKMS build failed!"
echo ""
echo "Please check the log file: $LOG_FILE"
echo "Common issues:"
echo " - Missing kernel headers"
echo " - Compiler version mismatch"
echo " - Kernel version too new/old"
exit 1
fi
print_success "Module built successfully."
# Install with DKMS
print_info "Installing module..."
dkms install -m "${DRV_NAME}" -v "${DRV_VERSION}" >> "$LOG_FILE" 2>&1
print_success "Module installed via DKMS."
print_info "The driver will automatically rebuild after kernel updates."
}
#############################################################################
# Module Loading
############################################################################# #############################################################################
load_module() { load_module() {
print_step "Loading driver module..." print_step "Loading kernel module..."
# Update module dependencies
print_info "Updating module dependencies..."
depmod -a >> "$LOG_FILE" 2>&1
# Unload module if already loaded # Unload module if already loaded
if lsmod | grep -q "$MODULE_NAME"; then if lsmod | grep -q "$MODULE_NAME"; then
print_info "Module already loaded. Reloading..." print_info "Module already loaded. Reloading..."
sudo modprobe -r "$MODULE_NAME" >> "$LOG_FILE" 2>&1 modprobe -r "$MODULE_NAME" >> "$LOG_FILE" 2>&1 || true
fi fi
# Load module # Load the module
sudo modprobe "$MODULE_NAME" >> "$LOG_FILE" 2>&1 print_info "Loading $MODULE_NAME..."
if modprobe "$MODULE_NAME" >> "$LOG_FILE" 2>&1; then
if [ $? -eq 0 ]; then print_success "Module loaded successfully."
print_success "Module loaded successfully"
# Check if it is listed # Verify module is loaded
sleep 2 print_info "Waiting for module to initialize..."
if lsmod | grep -q "$MODULE_NAME"; then local module_loaded=false
print_success "Module active in kernel" for i in {1..10}; do
lsmod | grep aic | tee -a "$LOG_FILE" if lsmod | grep -q "$MODULE_NAME"; then
module_loaded=true
break
fi
sleep 0.5
done
if [ "$module_loaded" = true ]; then
print_success "Module is active in kernel."
else else
print_warning "Module not appears in lsmod" print_warning "Module may not be fully initialized yet."
fi fi
else else
print_error "Failed to load module" print_warning "Module installed but could not be loaded immediately."
echo "Check dmesg for more details: sudo dmesg | tail -50" print_info "This may be due to Secure Boot or missing hardware."
return 1 print_info "Try rebooting or check: sudo dmesg | grep aic8800"
fi fi
} }
############################################################################# #############################################################################
# Post-installation verification # Post-Installation Verification
############################################################################# #############################################################################
verify_installation() { verify_installation() {
print_step "Verifying installation..." print_step "Verifying installation..."
# Check module # Check DKMS status
if lsmod | grep -q "$MODULE_NAME"; then local dkms_status
print_success "Module $MODULE_NAME is loaded" dkms_status=$(dkms status "${DRV_NAME}/${DRV_VERSION}" 2>/dev/null || echo "not found")
if echo "$dkms_status" | grep -q "installed"; then
print_success "DKMS module registered: $dkms_status"
else else
print_warning "Module is not loaded" print_warning "DKMS status unclear: $dkms_status"
fi
# Check if module is loaded
if lsmod | grep -q "$MODULE_NAME"; then
print_success "Kernel module is loaded."
echo ""
lsmod | grep aic
else
print_info "Module not currently loaded (this is OK if no hardware is connected)."
fi fi
# Check firmware # Check firmware
if [ -d "/lib/firmware/aic8800D80" ]; then if [ -d "/lib/firmware/aic8800D80" ]; then
print_success "Firmware installed in /lib/firmware/aic8800D80" print_success "Firmware installed in /lib/firmware/aic8800D80"
else
print_error "Firmware not found!"
fi fi
# Check wireless interfaces # Check for wireless interfaces
print_info "Wireless interfaces available:" print_info "Checking for wireless interfaces..."
iwconfig 2>/dev/null | grep -E "wlan|IEEE" | tee -a "$LOG_FILE" if command -v iwconfig &> /dev/null; then
iwconfig 2>/dev/null | grep -E "wlan|IEEE" || echo "No wireless interfaces detected (hardware may not be connected)"
# Check USB devices fi
print_info "USB devices AIC detected:"
lsusb | grep -i "aic\|368B" | tee -a "$LOG_FILE"
} }
############################################################################# #############################################################################
# Final instructions # Final Instructions
############################################################################# #############################################################################
show_final_instructions() { show_final_instructions() {
echo "" echo ""
echo -e "${GREEN}╔════════════════════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ INSTALLATION COMPLETED SUCCESSFULLY! ║${NC}" echo -e "${GREEN}║ INSTALLATION COMPLETED SUCCESSFULLY! ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════════════════════════════════╝${NC}" echo -e "${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}"
echo "" echo ""
echo -e "${CYAN}Next steps:${NC}" echo -e "${CYAN}Important Information:${NC}"
echo "" echo ""
echo "1. ${YELLOW}CONNECT THE USB ADAPTER${NC} physically (if not already connected)" echo "✓ Driver installed via DKMS"
echo "✓ Automatic rebuild enabled for kernel updates"
echo "✓ Firmware installed in /lib/firmware/"
echo "" echo ""
echo "2. Wait a few seconds and check if it was detected:" echo -e "${CYAN}Next Steps:${NC}"
echo ""
echo "1. Connect your AIC8800D80 USB WiFi adapter"
echo ""
echo "2. Check if the adapter is detected:"
echo " ${BLUE}lsusb | grep -i aic${NC}"
echo " ${BLUE}iwconfig${NC}" echo " ${BLUE}iwconfig${NC}"
echo " ${BLUE}ip link show${NC}" echo " ${BLUE}ip link show${NC}"
echo "" echo ""
echo "3. To view kernel logs about the device:" echo "3. View kernel messages about the driver:"
echo " ${BLUE}sudo dmesg | tail -30${NC}" echo " ${BLUE}sudo dmesg | grep aic8800${NC}"
echo "" echo ""
echo "4. To connect to a WiFi network:" echo "4. Connect to a WiFi network:"
echo " ${BLUE}nmcli device wifi list${NC}" echo " ${BLUE}nmcli device wifi list${NC}"
echo " ${BLUE}nmcli device wifi connect \"NETWORK_NAME\" password \"PASSWORD\"${NC}" echo " ${BLUE}nmcli device wifi connect \"SSID\" password \"PASSWORD\"${NC}"
echo "" echo ""
echo "5. To disable internal WiFi (optional):" echo -e "${CYAN}Troubleshooting:${NC}"
echo " ${BLUE}rfkill list${NC}"
echo " ${BLUE}sudo rfkill block <internal_wifi_number>${NC}"
echo "" echo ""
echo -e "${YELLOW}Important notes:${NC}" echo "• Check DKMS status:"
echo "- Bluetooth does not work with this driver (known limitation)" echo " ${BLUE}dkms status${NC}"
echo "- After kernel update, recompile the driver:"
echo " ${BLUE}cd $DRIVER_DIR/drivers/aic8800${NC}"
echo " ${BLUE}make clean && make && sudo make install${NC}"
echo "" echo ""
echo -e "${CYAN}Complete log saved in:${NC} $LOG_FILE" echo "• Check loaded modules:"
echo " ${BLUE}lsmod | grep aic8800${NC}"
echo ""
echo "• Manually load the module:"
echo " ${BLUE}sudo modprobe aic8800_fdrv${NC}"
echo ""
echo "• View detailed logs:"
echo " ${BLUE}cat $LOG_FILE${NC}"
echo ""
echo -e "${YELLOW}Known Limitations:${NC}"
echo "• Bluetooth functionality is not supported"
echo "• Secure Boot may prevent module loading (disable in BIOS if needed)"
echo ""
echo -e "${CYAN}Uninstallation:${NC}"
echo " ${BLUE}sudo dkms remove ${DRV_NAME}/${DRV_VERSION} --all${NC}"
echo " ${BLUE}sudo rm -rf /lib/firmware/aic8800D80${NC}"
echo "" echo ""
} }
############################################################################# #############################################################################
# Main function # Main Installation Flow
############################################################################# #############################################################################
main() { main() {
# Clear previous log # Initialize log file
> "$LOG_FILE" rm -f "$LOG_FILE" 2>/dev/null || true
touch "$LOG_FILE" 2>/dev/null || true
chmod 666 "$LOG_FILE" 2>/dev/null || true
echo -e "${CYAN}" echo -e "${CYAN}"
echo "╔════════════════════════════════════════════════════════════════════╗" echo "╔════════════════════════════════════════════════════════════════╗"
echo "║ Installation script for AIC8800D80 WiFi 6 driver ║" echo "║ AIC8800D80 WiFi 6 Driver - Universal Installer (DKMS) ║"
echo "║ Version 1.0 - 2025-12-29 ║" echo "║ Version 2.0.4 (Fixed) ║"
echo "╚════════════════════════════════════════════════════════════════════╝" echo "╚════════════════════════════════════════════════════════════════╝"
echo -e "${NC}" echo -e "${NC}"
# Step 1: Check Secure Boot (REQUIRED) log_message "START" "Installation started"
check_secure_boot || exit 1 log_message "INFO" "Kernel: $(uname -r)"
log_message "INFO" "Distribution: $(cat /etc/os-release 2>/dev/null | grep PRETTY_NAME | cut -d= -f2 | tr -d '"')"
# Step 2: Check requirements # Step 1: Check root privileges
check_requirements check_root
# Step 3: Install dependencies # Step 2: Check Secure Boot
install_dependencies check_secure_boot
# Step 4: Download driver # Step 3: Detect package manager
download_driver detect_package_manager
# Step 5: Install driver # Step 4: Install dependencies
install_driver install_dependencies "$DETECTED_PKG_MANAGER"
# Step 6: Configure autoload # Step 5: Install firmware
configure_autoload install_firmware
# Step 7: Load module # Step 6: Create DKMS configuration
create_dkms_conf
# Step 7: Install via DKMS
install_via_dkms
# Step 8: Load the module
load_module load_module
# Step 8: Verify installation # Step 9: Verify installation
verify_installation verify_installation
# Step 9: Show final instructions # Step 10: Show final instructions
show_final_instructions show_final_instructions
log_message "END" "Installation completed successfully"
} }
# Execute script # Execute main function
main "$@" main "$@"
exit 0 exit 0