diff --git a/INSTALL_SCRIPT.md b/INSTALL_SCRIPT.md
index 37e34d0..9eda17c 100644
--- a/INSTALL_SCRIPT.md
+++ b/INSTALL_SCRIPT.md
@@ -5,12 +5,12 @@
This automated installation script (`install.sh`) simplifies the process of installing the AIC8800D80 WiFi driver on Linux systems.
- Automatic Secure Boot detection
-- Dependency installation
-- Driver compilation and installation
+- Automatic dependency installation
+- Automatic driver compilation and installation
- Automatic module loading on boot
- Comprehensive error handling
- Colored output and logging
-- Compatible with Ubuntu, Debian, and derivatives
+- Compatible with Ubuntu, Debian, Fedora, and derivatives (DKMS supported `dkms.conf`)
## 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
# Run the installation
-./install.sh
+sudo ./install.sh
```
-> For more information, please refer to the [README.md](README.md) file.
\ No newline at end of file
+> For more information, please refer to the [README.md](README.md) file.
+
+
+
+---
+
+
+
+# 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
+```
\ No newline at end of file
diff --git a/README.md b/README.md
index 2583eb6..cfdc2d9 100644
--- a/README.md
+++ b/README.md
@@ -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.
### 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/:
```bash
diff --git a/aic.rules b/aic.rules
index a811a40..5c81448 100644
--- a/aic.rules
+++ b/aic.rules
@@ -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}=="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}=="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"
diff --git a/diagnostic_build.sh b/diagnostic_build.sh
new file mode 100755
index 0000000..3500a7a
--- /dev/null
+++ b/diagnostic_build.sh
@@ -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
diff --git a/dkms.conf b/dkms.conf
new file mode 100644
index 0000000..bed83f8
--- /dev/null
+++ b/dkms.conf
@@ -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"
diff --git a/drivers/aic8800/aic8800_fdrv/Makefile b/drivers/aic8800/aic8800_fdrv/Makefile
index edce2c6..53fa11e 100644
--- a/drivers/aic8800/aic8800_fdrv/Makefile
+++ b/drivers/aic8800/aic8800_fdrv/Makefile
@@ -341,7 +341,6 @@ ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP
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
@@ -381,13 +380,11 @@ KDIR ?= /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt
endif
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
-KDIR ?= /lib/modules/$(shell uname -r)/build
-#KDIR ?= ~/D/Workspace/CyberQuantum/Linux/linux-4.15/
+KVER := $(or $(KVER), $(kernelver), $(KERNELRELEASE), $(shell uname -r))
+KDIR ?= /lib/modules/$(KVER)/build
PWD ?= $(shell pwd)
-KVER ?= $(shell uname -r)
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 ?= $(SUBARCH)
+ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
CROSS_COMPILE ?=
endif
diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c
index 9e98284..81eaabd 100644
--- a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c
+++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c
@@ -42,12 +42,14 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){
char *filename = FW_USERCONFIG_NAME_8800D80;
if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS1
- || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS4) {
+ || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS4
+ || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS7) {
filename = FW_USERCONFIG_NAME_8800D80_U11;
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11_PRO
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS3
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS5
- || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS6) {
+ || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS6
+ || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS8) {
filename = FW_USERCONFIG_NAME_8800D80_U11_PRO;
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS2) {
filename = FW_USERCONFIG_NAME_8800D80_U11_CUS;
diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c
index 53dbfcb..3a23045 100644
--- a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c
+++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c
@@ -3511,12 +3511,15 @@ int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){
int size;
u32 *dst=NULL;
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;
} else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U2
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS1
|| rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS2
- || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS3) {
+ || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS4) {
filename = FW_USERCONFIG_NAME_8800DW_U2;
}
diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c b/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c
index 399a847..100ad6f 100644
--- a/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c
+++ b/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c
@@ -1001,8 +1001,7 @@ static void aicwf_sdio_bus_pwrctl(struct timer_list *t)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
- struct aic_sdio_dev *sdiodev = timer_container_of(sdiodev, t, timer);
-#else
+ struct aic_sdio_dev *sdiodev = timer_container_of(sdiodev, t, timer);#else
struct aic_sdio_dev *sdiodev = from_timer(sdiodev, t, timer);
#endif
diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.c b/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.c
index 3bcfd6e..ba4576b 100644
--- a/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.c
+++ b/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.c
@@ -106,8 +106,8 @@ void tcp_ack_deinit(struct rwnx_hw *priv)
drop_msg = NULL;
write_seqlock_bh(&ack_m->ack_info[i].seqlock);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
- timer_delete(&ack_m->ack_info[i].timer);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
+ timer_delete(&ack_m->ack_info[i].timer);
#else
del_timer(&ack_m->ack_info[i].timer);
#endif
@@ -379,7 +379,7 @@ int tcp_ack_handle(struct msg_buf *new_msgbuf,
//printk("%lx \n",ack_info->msgbuf);
drop_msg = ack_info->msgbuf;
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);
#else
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)))) {
ack_info->drop_cnt = 0;
ack_info->in_send_msg = new_msgbuf;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
- timer_delete(&ack_info->timer);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
+ timer_delete(&ack_info->timer);
#else
del_timer(&ack_info->timer);
#endif
@@ -484,8 +484,8 @@ int tcp_ack_handle_new(struct msg_buf *new_msgbuf,
ack_info->drop_cnt = 0;
//send_msg = new_msgbuf;
ack_info->in_send_msg = new_msgbuf;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
- timer_delete(&ack_info->timer);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
+ timer_delete(&ack_info->timer);
#else
del_timer(&ack_info->timer);
#endif
diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_usb.c b/drivers/aic8800/aic8800_fdrv/aicwf_usb.c
index 456a382..9adcb61 100644
--- a/drivers/aic8800/aic8800_fdrv/aicwf_usb.c
+++ b/drivers/aic8800/aic8800_fdrv/aicwf_usb.c
@@ -1214,6 +1214,9 @@ fail:
usb_buf->skb = NULL;
aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf,
&usb_dev->tx_free_count, &usb_dev->tx_free_lock);
+ if (ret == -ENODEV) {
+ break;
+ }
#endif
}
}
@@ -2140,7 +2143,7 @@ static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *in
/* Check interface number */
#ifdef CONFIG_USB_BT
- if (usb->actconfig->desc.bNumInterfaces != 3)
+ if (usb->actconfig->desc.bNumInterfaces != 1 && usb->actconfig->desc.bNumInterfaces != 3)
#else
if (usb->actconfig->desc.bNumInterfaces != 1)
#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){
AICWFDBG(LOGERROR, "AIC8800DC change to AIC8800DW\n");
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");
} else if(usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 ||
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;
}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_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;
AICWFDBG(LOGINFO, "%s USE AIC8800DC\r\n", __func__);
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;
AICWFDBG(LOGINFO, "%s USE AIC8800DW\r\n", __func__);
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_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){
usb_dev->chipid = PRODUCT_ID_AIC8800D81;
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_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_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)},
{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_CUS2)},
{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_CUS2)},
{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_CUS5)},
{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)},
#endif
{}
diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_usb.h b/drivers/aic8800/aic8800_fdrv/aicwf_usb.h
index fa1974a..84403bc 100644
--- a/drivers/aic8800/aic8800_fdrv/aicwf_usb.h
+++ b/drivers/aic8800/aic8800_fdrv/aicwf_usb.h
@@ -18,6 +18,8 @@
#define USB_VENDOR_ID_AIC 0xA69C
#define USB_VENDOR_ID_AIC_V2 0x368B
#define USB_VENDOR_ID_TENDA 0x2604
+#define USB_VENDOR_ID_TENDA_V2 0x3625
+
#ifndef CONFIG_USB_BT
#define USB_PRODUCT_ID_AIC8800 0x8800
@@ -39,16 +41,23 @@
#define USB_PRODUCT_ID_TENDA_U2 0x0014
#define USB_PRODUCT_ID_TENDA_U11 0x001f
#define USB_PRODUCT_ID_TENDA_U11_PRO 0x0020
+#define USB_PRODUCT_ID_TENDA_TX1U_NANO 0x0110
#define USB_PRODUCT_ID_AIC8800FC_CUS1 0x88df
#define USB_PRODUCT_ID_AIC8800FC_CUS2 0x88E0
#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_CUS2 0x8D85
#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_CUS5 0x8D8A
#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
enum AICWF_IC{
diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_compat.h b/drivers/aic8800/aic8800_fdrv/rwnx_compat.h
index 204561b..7c26d0f 100644
--- a/drivers/aic8800/aic8800_fdrv/rwnx_compat.h
+++ b/drivers/aic8800/aic8800_fdrv/rwnx_compat.h
@@ -41,7 +41,7 @@
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK
#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
#endif
diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_main.c b/drivers/aic8800/aic8800_fdrv/rwnx_main.c
index c68f6cb..2b1d07a 100644
--- a/drivers/aic8800/aic8800_fdrv/rwnx_main.c
+++ b/drivers/aic8800/aic8800_fdrv/rwnx_main.c
@@ -2036,11 +2036,11 @@ void aicwf_p2p_alive_timeout(struct timer_list *t)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
rwnx_vif = (struct rwnx_vif *)data;
rwnx_hw = rwnx_vif->rwnx_hw;
- #elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
- rwnx_hw = timer_container_of(rwnx_hw, t, p2p_alive_timer);
+ #elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0)
+ rwnx_hw = from_timer(rwnx_hw, t, p2p_alive_timer);
rwnx_vif = rwnx_hw->p2p_dev_vif;
#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;
#endif
@@ -2233,10 +2233,10 @@ static void aicwf_pwrloss_timer(struct timer_list *t)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
rwnx_vif = (struct rwnx_vif *)data;
rwnx_hw = rwnx_vif->rwnx_hw;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
- rwnx_hw = timer_container_of(rwnx_hw, t, pwrloss_timer);
-#else
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0)
rwnx_hw = from_timer(rwnx_hw, t, pwrloss_timer);
+#else
+ rwnx_hw = timer_container_of(rwnx_hw, t, pwrloss_timer);
#endif
if (!work_pending(&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) {
rwnx_hw->is_p2p_alive = 0;
if (timer_pending(&rwnx_hw->p2p_alive_timer)) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
- timer_delete_sync(&rwnx_hw->p2p_alive_timer);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
+ timer_delete_sync(&rwnx_hw->p2p_alive_timer);
#else
del_timer_sync(&rwnx_hw->p2p_alive_timer);
#endif
@@ -4092,12 +4092,13 @@ static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
#ifdef CONFIG_BAND_STEERING
rwnx_vif->ap.start = false;
aicwf_nl_hook_deinit(rwnx_vif->ap.band, rwnx_vif->rwnx_hw->iface_idx);
- if (timer_pending(&rwnx_vif->steer_timer))
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
- timer_delete_sync(&rwnx_vif->steer_timer);
+ if (timer_pending(&rwnx_vif->steer_timer)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
+ timer_delete_sync(&rwnx_vif->steer_timer);
#else
- del_timer_sync(&rwnx_vif->steer_timer);
+ del_timer_sync(&rwnx_vif->steer_timer);
#endif
+ }
cancel_work_sync(&rwnx_vif->steer_work);
flush_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
* 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)
- int radio_idx,
- #endif
- u32 changed)
+#if LINUX_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
{
return 0;
}
@@ -4300,7 +4301,7 @@ static int rwnx_cfg80211_set_tx_power(struct wiphy *wiphy,
struct wireless_dev *wdev,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
- int radio_idx,
+int radio_idx,
#endif
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
if(timer_pending(&rwnx_hw->pwrloss_timer)){
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
- timer_delete_sync(&rwnx_hw->pwrloss_timer);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
+ timer_delete_sync(&rwnx_hw->pwrloss_timer);
#else
del_timer_sync(&rwnx_hw->pwrloss_timer);
#endif
+ }
+
cancel_work_sync(&rwnx_hw->pwrloss_work);
#endif
@@ -9054,12 +9057,13 @@ void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw)
if (!list_empty(&rwnx_hw->defrag_list)) {
list_for_each_entry(defrag_ctrl, &rwnx_hw->defrag_list, list) {
list_del_init(&defrag_ctrl->list);
- if (timer_pending(&defrag_ctrl->defrag_timer))
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
+ if (timer_pending(&defrag_ctrl->defrag_timer)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
timer_delete_sync(&defrag_ctrl->defrag_timer);
#else
del_timer_sync(&defrag_ctrl->defrag_timer);
#endif
+ }
dev_kfree_skb(defrag_ctrl->skb);
kfree(defrag_ctrl);
}
diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_rx.c b/drivers/aic8800/aic8800_fdrv/rwnx_rx.c
index 9a2a8a2..be6055e 100644
--- a/drivers/aic8800/aic8800_fdrv/rwnx_rx.c
+++ b/drivers/aic8800/aic8800_fdrv/rwnx_rx.c
@@ -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);
#else
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,
RWNX_VIF_TYPE(rwnx_vif), 0, NULL, NULL, false);
#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);
preorder_ctrl->enable = false;
spin_unlock_irqrestore(&preorder_ctrl->reord_list_lock, flags);
- if (timer_pending(&preorder_ctrl->reord_timer))
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
- ret = timer_delete_sync(&preorder_ctrl->reord_timer);
+ if (timer_pending(&preorder_ctrl->reord_timer)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
+ ret = timer_delete_sync(&preorder_ctrl->reord_timer);
#else
ret = del_timer_sync(&preorder_ctrl->reord_timer);
#endif
+ }
cancel_work_sync(&preorder_ctrl->reord_timer_work);
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){
preorder_ctrl->enable = false;
if (timer_pending(&preorder_ctrl->reord_timer)) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
- ret = timer_delete_sync(&preorder_ctrl->reord_timer);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
+ ret = timer_delete_sync(&preorder_ctrl->reord_timer);
#else
ret = del_timer_sync(&preorder_ctrl->reord_timer);
#endif
@@ -1868,10 +1871,10 @@ void reord_timeout_handler (struct timer_list *t)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
struct reord_ctrl *preorder_ctrl = (struct reord_ctrl *)data;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
- struct reord_ctrl *preorder_ctrl = timer_container_of(preorder_ctrl, t, reord_timer);
-#else
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(6,16,0)
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
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 {
if(timer_pending(&preorder_ctrl->reord_timer)) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
- ret = timer_delete(&preorder_ctrl->reord_timer);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
+ ret = timer_delete(&preorder_ctrl->reord_timer);
#else
ret = del_timer(&preorder_ctrl->reord_timer);
#endif
@@ -2199,10 +2202,10 @@ void defrag_timeout_cb(struct timer_list *t)
struct defrag_ctrl_info *defrag_ctrl = NULL;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
defrag_ctrl = (struct defrag_ctrl_info *)data;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
- defrag_ctrl = timer_container_of(defrag_ctrl, t, defrag_timer);
-#else
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(6,16,0)
defrag_ctrl = from_timer(defrag_ctrl, t, defrag_timer);
+#else
+ defrag_ctrl = timer_container_of(defrag_ctrl, t, defrag_timer);
#endif
printk("%s:%p\r\n", __func__, defrag_ctrl);
@@ -2368,11 +2371,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) {
- #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);
- #else
- cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, UNKNOWN_LINK_ID, GFP_ATOMIC);
- #endif
+#endif
}
goto end;
}
@@ -2567,8 +2570,8 @@ check_len_update:
skb_tmp = defrag_info->skb;
list_del_init(&defrag_info->list);
if (timer_pending(&defrag_info->defrag_timer)) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
- ret = timer_delete(&defrag_info->defrag_timer);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0))
+ ret = timer_delete(&defrag_info->defrag_timer);
#else
ret = del_timer(&defrag_info->defrag_timer);
#endif
@@ -2622,15 +2625,13 @@ check_len_update:
}
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,
sta->mac_addr, GFP_ATOMIC);
- #else
- cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
- sta->mac_addr,
- UNKNOWN_LINK_ID,
- GFP_ATOMIC);
- #endif
+#endif
}
}
diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_rx.h b/drivers/aic8800/aic8800_fdrv/rwnx_rx.h
index 46527e2..e7e71f6 100644
--- a/drivers/aic8800/aic8800_fdrv/rwnx_rx.h
+++ b/drivers/aic8800/aic8800_fdrv/rwnx_rx.h
@@ -405,8 +405,4 @@ struct element {
#endif
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
-#define UNKNOWN_LINK_ID -1
-#endif
-
#endif /* _RWNX_RX_H_ */
diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_version_gen.h b/drivers/aic8800/aic8800_fdrv/rwnx_version_gen.h
index 705c56e..b58a50b 100644
--- a/drivers/aic8800/aic8800_fdrv/rwnx_version_gen.h
+++ b/drivers/aic8800/aic8800_fdrv/rwnx_version_gen.h
@@ -1,5 +1,5 @@
#define RWNX_VERS_REV "1a4b0054d2M (master)"
#define RWNX_VERS_MOD "6.4.3.0"
#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)"
-#define RELEASE_DATE "2025_0423_71b66e7b"
+#define RELEASE_DATE "2025_1018_71b66e7b"
diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_wakelock.c b/drivers/aic8800/aic8800_fdrv/rwnx_wakelock.c
index 970262b..f6dc413 100644
--- a/drivers/aic8800/aic8800_fdrv/rwnx_wakelock.c
+++ b/drivers/aic8800/aic8800_fdrv/rwnx_wakelock.c
@@ -9,15 +9,12 @@
#include "rwnx_defs.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 *ws;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
- ws = wakeup_source_register(NULL, name);
-#else
ws = wakeup_source_create(name);
wakeup_source_add(ws);
-#endif
return ws;
}
@@ -25,15 +22,10 @@ void rwnx_wakeup_deinit(struct wakeup_source *ws)
{
if (ws && ws->active)
__pm_relax(ws);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
- wakeup_source_unregister(ws);
-#else
wakeup_source_remove(ws);
wakeup_source_destroy(ws);
-#endif
}
-
+#endif
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)
{
+ #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_rx = rwnx_wakeup_init("rwnx_rx_wakelock");
rwnx_hw->ws_irqrx = rwnx_wakeup_init("rwnx_irqrx_wakelock");
rwnx_hw->ws_pwrctrl = rwnx_wakeup_init("rwnx_pwrcrl_wakelock");
+ #endif
}
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_rx);
rwnx_wakeup_deinit(rwnx_hw->ws_irqrx);
rwnx_wakeup_deinit(rwnx_hw->ws_pwrctrl);
+ #endif
rwnx_hw->ws_tx = NULL;
rwnx_hw->ws_rx = NULL;
rwnx_hw->ws_irqrx = NULL;
diff --git a/drivers/aic8800/aic_load_fw/Makefile b/drivers/aic8800/aic_load_fw/Makefile
index 3479e82..3cdb65b 100644
--- a/drivers/aic8800/aic_load_fw/Makefile
+++ b/drivers/aic8800/aic_load_fw/Makefile
@@ -67,7 +67,7 @@ ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
#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-
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-
#KDIR := /home/yaya/E/Rockchip/3399/rk3399-android-10/kernel
#ARCH ?= arm64
@@ -91,13 +91,12 @@ endif
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU
-KDIR := /lib/modules/$(shell uname -r)/build
-PWD := $(shell pwd)
-KVER := $(shell uname -r)
-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 ?= $(SUBARCH)
-CROSS_COMPILE :=
+KVER := $(or $(KVER), $(kernelver), $(KERNELRELEASE), $(shell uname -r))
+KDIR ?= /lib/modules/$(KVER)/build
+PWD ?= $(shell pwd)
+MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
+ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
+CROSS_COMPILE ?=
endif
diff --git a/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c b/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c
index fe1f82e..4040e00 100644
--- a/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c
+++ b/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c
@@ -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;
- //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 */
mem_write_req = rwnx_msg_zalloc(DBG_MEM_WRITE_REQ, TASK_DBG, DRV_TASK_ID,
diff --git a/install.sh b/install.sh
old mode 100644
new mode 100755
index c32f9e6..0ffac7a
--- a/install.sh
+++ b/install.sh
@@ -1,438 +1,556 @@
#!/bin/bash
-# Cores for output
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
-BLUE='\033[0;34m'
-CYAN='\033[0;36m'
-NC='\033[0m' # No Color
+#############################################################################
+# AIC8800D80 WiFi 6 Driver - Universal Installer (DKMS) - VERSÃO CORRIGIDA
+# Version: 2.0.4
+# Date: 2025-12-30
+# Description: Multi-distribution installer with DKMS support
+# Supported: Debian/Ubuntu, Fedora/RHEL, Arch Linux, and derivatives
+# FIX: Corrected DKMS module configuration for aic8800_fdrv
+#############################################################################
-# Variables
-DRIVER_REPO="https://github.com/shenmintao/aic8800d80.git"
-DRIVER_DIR="$HOME/aic8800d80"
-LOG_FILE="/tmp/aic8800d80_install.log"
-MODULE_NAME="aic8800_fdrv"
+set -e # Exit on error
+
+# Color definitions
+readonly RED='\033[0;31m'
+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() {
echo -e "${BLUE}[INFO]${NC} $1"
- echo "[INFO] $1" >> "$LOG_FILE"
+ log_message "INFO" "$1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
- echo "[SUCCESS] $1" >> "$LOG_FILE"
+ log_message "SUCCESS" "$1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
- echo "[WARNING] $1" >> "$LOG_FILE"
+ log_message "WARNING" "$1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
- echo "[ERROR] $1" >> "$LOG_FILE"
+ log_message "ERROR" "$1"
}
print_step() {
- echo -e "\n${CYAN}==>${NC} ${1}"
- echo "==> $1" >> "$LOG_FILE"
+ echo ""
+ echo -e "${CYAN}==>${NC} ${1}"
+ log_message "STEP" "$1"
}
-# Function to check if the command was successful
-check_success() {
- if [ $? -eq 0 ]; then
- print_success "$1"
- return 0
- else
- print_error "$2"
- return 1
+#############################################################################
+# Error Handling
+#############################################################################
+
+cleanup_on_error() {
+ print_error "Installation failed. Check $LOG_FILE for details."
+ exit 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
}
#############################################################################
-# Check Secure Boot
+# Secure Boot Detection
#############################################################################
check_secure_boot() {
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
- SECURE_BOOT_STATUS=$(mokutil --sb-state 2>/dev/null | grep -i "SecureBoot" | awk '{print $2}')
-
- 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
+ if mokutil --sb-state 2>/dev/null | grep -qi "SecureBoot enabled"; then
+ secure_boot_enabled=true
fi
fi
- # Method 2: Check via /sys/firmware/efi/efivars (fallback)
- if [ -d /sys/firmware/efi/efivars ]; then
- if [ -f /sys/firmware/efi/efivars/SecureBoot-* ]; then
- SB_VALUE=$(od -An -t u1 /sys/firmware/efi/efivars/SecureBoot-* | awk '{print $NF}')
- if [ "$SB_VALUE" = "1" ]; then
- print_error "Secure Boot is ENABLED (detected via EFI vars)!"
- echo ""
- echo -e "${RED}Secure Boot needs to be disabled to install this driver.${NC}"
- 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
+ # Method 2: Check via EFI variables (fallback)
+ if [ "$secure_boot_enabled" = false ] && [ -d /sys/firmware/efi ]; then
+ local secureboot_files=(/sys/firmware/efi/efivars/SecureBoot-*)
+ if [ -f "${secureboot_files[0]}" ]; then
+ local sb_value
+ sb_value=$(od -An -t u1 "${secureboot_files[0]}" 2>/dev/null | awk '{print $NF}')
+ if [ "$sb_value" = "1" ]; then
+ secure_boot_enabled=true
fi
fi
fi
- # Method 3: Check via dmesg (last resort)
- DMESG_SB=$(dmesg | grep -i "secure boot" | grep -i "enabled")
- if [ -n "$DMESG_SB" ]; then
- print_warning "Secure Boot may be enabled (detected via dmesg)."
- echo "Please check manually and disable if necessary."
- read -p "Do you want to continue anyway? (y/N): " choice
- if [[ ! "$choice" =~ ^[Ss]$ ]]; then
- return 1
+ if [ "$secure_boot_enabled" = true ]; then
+ echo ""
+ echo -e "${YELLOW}╔════════════════════════════════════════════════════════════════╗${NC}"
+ echo -e "${YELLOW}║ SECURE BOOT IS ENABLED ║${NC}"
+ echo -e "${YELLOW}╚════════════════════════════════════════════════════════════════╝${NC}"
+ echo ""
+ echo "The driver may not load automatically due to Secure Boot restrictions."
+ 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
+ print_warning "Continuing with Secure Boot enabled..."
+ else
+ print_success "Secure Boot is disabled or not present."
fi
-
- print_success "Secure Boot verification completed."
- return 0
}
#############################################################################
-# Check requirements
+# Package Manager Detection and Dependency Installation
#############################################################################
-check_requirements() {
- print_step "Checking system requirements..."
+detect_package_manager() {
+ print_step "Detecting package manager and distribution..."
- # Verificar se é root
- if [ "$EUID" -eq 0 ]; then
- print_error "This script MUST NOT be run as root!"
- echo "Run as a normal user. The script will request sudo when necessary."
+ local pkg_manager=""
+ local distro_name=""
+
+ 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
fi
- # Check kernel
- KERNEL_VERSION=$(uname -r)
- 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."
+ print_success "Detected: $distro_name ($pkg_manager)"
+ DETECTED_PKG_MANAGER="$pkg_manager"
}
-#############################################################################
-# Install dependencies
-#############################################################################
-
install_dependencies() {
- print_step "Installing necessary dependencies..."
+ local pkg_manager="$1"
- # Update package list
- print_info "Updating package list..."
- sudo apt update >> "$LOG_FILE" 2>&1
- check_success "Package list updated" "Failed to update package list"
+ print_step "Installing dependencies..."
- # List of dependencies
- DEPENDENCIES=(
- "git"
- "build-essential"
- "dkms"
- "bc"
- "linux-headers-$(uname -r)"
- "mokutil"
- )
+ case "$pkg_manager" in
+ apt)
+ print_info "Updating package database..."
+ apt-get update -qq >> "$LOG_FILE" 2>&1
+
+ print_info "Installing: dkms, build-essential, linux-headers, mokutil..."
+ apt-get install -y dkms build-essential linux-headers-$(uname -r) mokutil >> "$LOG_FILE" 2>&1
+ ;;
+
+ 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[*]}"
- sudo apt install -y "${DEPENDENCIES[@]}" >> "$LOG_FILE" 2>&1
- check_success "Dependencies installed" "Failed to install dependencies"
+ print_success "Dependencies installed successfully."
}
#############################################################################
-# Download driver
+# Firmware Installation
#############################################################################
-download_driver() {
- print_step "Downloading AIC8800D80 driver..."
+install_firmware() {
+ print_step "Installing firmware..."
- # If the directory already exists, ask if you want to update
- if [ -d "$DRIVER_DIR" ]; then
- 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
+ local fw_source="${SCRIPT_DIR}/fw/aic8800D80"
+ local fw_dest="/lib/firmware/aic8800D80"
- # Clone repository
- print_info "Cloning repository..."
- cd "$HOME" || exit 1
- 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)"
+ if [ ! -d "$fw_source" ]; then
+ print_error "Firmware directory not found: $fw_source"
+ echo "Please ensure you're running the script from the repository root."
exit 1
fi
- # Step 5: Compile driver
- print_info "Compiling driver (this may take a few minutes)..."
- make >> "$LOG_FILE" 2>&1
-
- if [ $? -ne 0 ]; then
- print_warning "Compilation failed with default GCC. Trying with gcc-12..."
- 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"
+ # Remove old firmware versions
+ if [ -d "$fw_dest" ]; then
+ print_info "Removing existing firmware..."
+ if [ -d "/lib/firmware" ] && [ -n "$(find /lib/firmware -maxdepth 1 -name 'aic8800*' -type d 2>/dev/null)" ]; then
+ rm -rf /lib/firmware/aic8800* >> "$LOG_FILE" 2>&1
+ fi
fi
- # Step 6: Install driver
- print_info "Installing driver..."
- sudo make install >> "$LOG_FILE" 2>&1
- check_success "Driver installed" "Failed to install driver" || exit 1
+ # Copy new firmware
+ print_info "Copying firmware to $fw_dest..."
+ cp -r "$fw_source" "$fw_dest" >> "$LOG_FILE" 2>&1
+
+ print_success "Firmware installed successfully."
}
#############################################################################
-# Configure automatic loading
+# DKMS Configuration - CORRIGIDO v2.0.4
#############################################################################
-configure_autoload() {
- print_step "Configuring automatic loading on boot..."
+create_dkms_conf() {
+ print_step "Configuring DKMS..."
- # Add module to /etc/modules
- if ! grep -q "^$MODULE_NAME$" /etc/modules 2>/dev/null; then
- echo "$MODULE_NAME" | sudo tee -a /etc/modules >> "$LOG_FILE" 2>&1
- print_success "Module added to /etc/modules"
- else
- print_info "Module already configured in /etc/modules"
+ local dkms_conf="${SCRIPT_DIR}/dkms.conf"
+
+ # Check if dkms.conf already exists
+ if [ -f "$dkms_conf" ]; then
+ print_info "DKMS configuration file already exists."
+ return 0
fi
- # Create configuration file modules-load.d
- 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/"
+ print_info "Creating dkms.conf..."
+
+ # 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() {
- 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
if lsmod | grep -q "$MODULE_NAME"; then
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
- # Load module
- sudo modprobe "$MODULE_NAME" >> "$LOG_FILE" 2>&1
-
- if [ $? -eq 0 ]; then
- print_success "Module loaded successfully"
+ # Load the module
+ print_info "Loading $MODULE_NAME..."
+ if modprobe "$MODULE_NAME" >> "$LOG_FILE" 2>&1; then
+ print_success "Module loaded successfully."
- # Check if it is listed
- sleep 2
- if lsmod | grep -q "$MODULE_NAME"; then
- print_success "Module active in kernel"
- lsmod | grep aic | tee -a "$LOG_FILE"
+ # Verify module is loaded
+ print_info "Waiting for module to initialize..."
+ local module_loaded=false
+ for i in {1..10}; do
+ 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
- print_warning "Module not appears in lsmod"
+ print_warning "Module may not be fully initialized yet."
fi
else
- print_error "Failed to load module"
- echo "Check dmesg for more details: sudo dmesg | tail -50"
- return 1
+ print_warning "Module installed but could not be loaded immediately."
+ print_info "This may be due to Secure Boot or missing hardware."
+ print_info "Try rebooting or check: sudo dmesg | grep aic8800"
fi
}
#############################################################################
-# Post-installation verification
+# Post-Installation Verification
#############################################################################
verify_installation() {
print_step "Verifying installation..."
- # Check module
- if lsmod | grep -q "$MODULE_NAME"; then
- print_success "Module $MODULE_NAME is loaded"
+ # Check DKMS status
+ local dkms_status
+ 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
- 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
# Check firmware
if [ -d "/lib/firmware/aic8800D80" ]; then
print_success "Firmware installed in /lib/firmware/aic8800D80"
- else
- print_error "Firmware not found!"
fi
- # Check wireless interfaces
- print_info "Wireless interfaces available:"
- iwconfig 2>/dev/null | grep -E "wlan|IEEE" | tee -a "$LOG_FILE"
-
- # Check USB devices
- print_info "USB devices AIC detected:"
- lsusb | grep -i "aic\|368B" | tee -a "$LOG_FILE"
+ # Check for wireless interfaces
+ print_info "Checking for wireless interfaces..."
+ 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)"
+ fi
}
#############################################################################
-# Final instructions
+# Final Instructions
#############################################################################
show_final_instructions() {
echo ""
- echo -e "${GREEN}╔════════════════════════════════════════════════════════════════════╗${NC}"
- echo -e "${GREEN}║ INSTALLATION COMPLETED SUCCESSFULLY! ║${NC}"
- echo -e "${GREEN}╚════════════════════════════════════════════════════════════════════╝${NC}"
+ echo -e "${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}"
+ echo -e "${GREEN}║ INSTALLATION COMPLETED SUCCESSFULLY! ║${NC}"
+ echo -e "${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}"
echo ""
- echo -e "${CYAN}Next steps:${NC}"
+ echo -e "${CYAN}Important Information:${NC}"
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 "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}ip link show${NC}"
echo ""
- echo "3. To view kernel logs about the device:"
- echo " ${BLUE}sudo dmesg | tail -30${NC}"
+ echo "3. View kernel messages about the driver:"
+ echo " ${BLUE}sudo dmesg | grep aic8800${NC}"
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 connect \"NETWORK_NAME\" password \"PASSWORD\"${NC}"
+ echo " ${BLUE}nmcli device wifi connect \"SSID\" password \"PASSWORD\"${NC}"
echo ""
- echo "5. To disable internal WiFi (optional):"
- echo " ${BLUE}rfkill list${NC}"
- echo " ${BLUE}sudo rfkill block ${NC}"
+ echo -e "${CYAN}Troubleshooting:${NC}"
echo ""
- echo -e "${YELLOW}Important notes:${NC}"
- echo "- Bluetooth does not work with this driver (known limitation)"
- 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 "• Check DKMS status:"
+ echo " ${BLUE}dkms status${NC}"
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 ""
}
#############################################################################
-# Main function
+# Main Installation Flow
#############################################################################
main() {
- # Clear previous log
- > "$LOG_FILE"
+ # Initialize 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 "╔════════════════════════════════════════════════════════════════════╗"
- echo "║ Installation script for AIC8800D80 WiFi 6 driver ║"
- echo "║ Version 1.0 - 2025-12-29 ║"
- echo "╚════════════════════════════════════════════════════════════════════╝"
+ echo "╔════════════════════════════════════════════════════════════════╗"
+ echo "║ AIC8800D80 WiFi 6 Driver - Universal Installer (DKMS) ║"
+ echo "║ Version 2.0.4 (Fixed) ║"
+ echo "╚════════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
- # Step 1: Check Secure Boot (REQUIRED)
- check_secure_boot || exit 1
+ log_message "START" "Installation started"
+ 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
- check_requirements
+ # Step 1: Check root privileges
+ check_root
- # Step 3: Install dependencies
- install_dependencies
+ # Step 2: Check Secure Boot
+ check_secure_boot
- # Step 4: Download driver
- download_driver
+ # Step 3: Detect package manager
+ detect_package_manager
- # Step 5: Install driver
- install_driver
+ # Step 4: Install dependencies
+ install_dependencies "$DETECTED_PKG_MANAGER"
- # Step 6: Configure autoload
- configure_autoload
+ # Step 5: Install firmware
+ 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
- # Step 8: Verify installation
+ # Step 9: Verify installation
verify_installation
- # Step 9: Show final instructions
+ # Step 10: Show final instructions
show_final_instructions
+
+ log_message "END" "Installation completed successfully"
}
-# Execute script
+# Execute main function
main "$@"
exit 0