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