diff --git a/drivers/aic8800/Kconfig b/drivers/aic8800/Kconfig index d12e807..44970d1 100644 --- a/drivers/aic8800/Kconfig +++ b/drivers/aic8800/Kconfig @@ -7,5 +7,4 @@ config AIC_WLAN_SUPPORT if AIC_WLAN_SUPPORT source "drivers/net/wireless/aic8800/aic8800_fdrv/Kconfig" source "drivers/net/wireless/aic8800/aic_load_fw/Kconfig" -source "drivers/net/wireless/aic8800/aic_btusb/Kconfig" endif diff --git a/drivers/aic8800/Makefile b/drivers/aic8800/Makefile index 396e40b..dfb30d9 100644 --- a/drivers/aic8800/Makefile +++ b/drivers/aic8800/Makefile @@ -1,13 +1,14 @@ CONFIG_AIC_LOADFW_SUPPORT := m CONFIG_AIC8800_WLAN_SUPPORT := m -obj-$(CONFIG_AIC_LOADFW_SUPPORT) += aic_load_fw/ +obj-$(CONFIG_AIC_LOADFW_SUPPORT) += aic_load_fw/ obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/ ########## config option ########## export CONFIG_USE_FW_REQUEST = n export CONFIG_PREALLOC_RX_SKB = y export CONFIG_PREALLOC_TXQ = y +export CONFIG_WOWLAN = n ################################### ########## platform support list ########## @@ -46,9 +47,9 @@ KDIR = /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt- endif ifeq ($(CONFIG_PLATFORM_UBUNTU), y) -KVER ?= $(shell uname -r) -KDIR = /lib/modules/$(KVER)/build +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/ -e s/loongarch64/loongarch/ -e s/loong64/loongarch/) ARCH ?= $(SUBARCH) diff --git a/drivers/aic8800/aic8800_fdrv/Makefile b/drivers/aic8800/aic8800_fdrv/Makefile index 53fa11e..7f60d6c 100644 --- a/drivers/aic8800/aic8800_fdrv/Makefile +++ b/drivers/aic8800/aic8800_fdrv/Makefile @@ -82,7 +82,7 @@ CONFIG_BR_SUPPORT = n CONFIG_USB_MSG_OUT_EP = y CONFIG_USB_MSG_IN_EP = y CONFIG_USB_RX_REASSEMBLE = n -CONFIG_WOWLAN = n +CONFIG_WOWLAN ?= n #DCDW support tx aggr, D80 support both CONFIG_USB_RX_AGGR = n @@ -93,7 +93,7 @@ CONFIG_GPIO_WAKEUP = n CONFIG_CREATE_TRACE_POINTS = n CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y CONFIG_USE_USB_ZERO_PACKET = y -CONFIG_DEBUG_FS = n +CONFIG_DEBUG_FS ?= n CONFIG_STA_SCAN_WHEN_P2P_WORKING = y CONFIG_SET_VENDOR_EXTENSION_IE = n CONFIG_VENDOR_GPIO = n @@ -114,6 +114,7 @@ CONFIG_LOFT_CALIB = n CONFIG_GKI = n CONFIG_SCHED_SCAN = n CONFIG_TEMP_COMP = n +CONFIG_TEMP_CONTROL = n CONFIG_POWER_LIMIT = n CONFIG_EXT_FEM_8800DCDW = n # CONFIG_MCC = n for sta and p2p concurrent in same channel. @@ -122,6 +123,8 @@ CONFIG_LOAD_BT_PATCH_IN_FDRV = n CONFIG_DYNAMIC_PWR = n CONFIG_DYNAMIC_PERPWR = n CONFIG_BAND_STEERING = n +CONFIG_PRBREQ_REPORT = n +CONFIG_SUPPORT_4ADDR = n #support D80X2 can write rf result to file CONFIG_WRITE_FILE_D80X2 = n @@ -189,7 +192,9 @@ $(MODULE_NAME)-y := \ aic_priv_cmd.o \ aicwf_compat_8800dc.o \ aicwf_compat_8800d80.o \ - aicwf_compat_8800d80x2.o + aicwf_compat_8800d80x2.o \ + aicwf_compat_8800d80n.o \ + aicwf_compat_8800dln.o $(MODULE_NAME)-$(CONFIG_BAND_STEERING) += aicwf_manager.o \ aicwf_steering.o @@ -263,6 +268,8 @@ ccflags-$(CONFIG_LOAD_BT_PATCH_IN_FDRV) += -DCONFIG_LOAD_BT_PATCH_IN_FDRV ccflags-$(CONFIG_DYNAMIC_PWR) += -DCONFIG_DYNAMIC_PWR ccflags-$(CONFIG_DYNAMIC_PERPWR) += -DCONFIG_DYNAMIC_PERPWR ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING +ccflags-$(CONFIG_PRBREQ_REPORT) += -DCONFIG_PRBREQ_REPORT +ccflags-$(CONFIG_SUPPORT_4ADDR) += -DCONFIG_SUPPORT_4ADDR ccflags-$(CONFIG_WRITE_FILE_D80X2) += -DRF_WRITE_FILE ifeq ($(CONFIG_SDIO_SUPPORT), y) @@ -338,9 +345,11 @@ ccflags-$(CONFIG_GKI) += -DCONFIG_GKI ccflags-$(CONFIG_SCHED_SCAN) += -DCONFIG_SCHED_SCAN ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP +ccflags-$(CONFIG_TEMP_CONTROL) += -DCONFIG_TEMP_CONTROL ccflags-$(CONFIG_POWER_LIMIT) += -DCONFIG_POWER_LIMIT ccflags-$(CONFIG_EXT_FEM_8800DCDW) += -DCONFIG_EXT_FEM_8800DCDW ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN +MAKEFLAGS +=-j$(shell nproc) # Platform support list CONFIG_PLATFORM_ROCKCHIP ?= n @@ -380,11 +389,13 @@ KDIR ?= /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt endif ifeq ($(CONFIG_PLATFORM_UBUNTU), y) -KVER := $(or $(KVER), $(kernelver), $(KERNELRELEASE), $(shell uname -r)) -KDIR ?= /lib/modules/$(KVER)/build +KDIR ?= /lib/modules/$(shell uname -r)/build +#KDIR ?= ~/D/Workspace/CyberQuantum/Linux/linux-4.15/ PWD ?= $(shell pwd) +KVER ?= $(shell uname -r) 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/) +SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/) +ARCH ?= $(SUBARCH) CROSS_COMPILE ?= endif diff --git a/drivers/aic8800/aic8800_fdrv/aic_br_ext.c b/drivers/aic8800/aic8800_fdrv/aic_br_ext.c index dd038e3..2055e9c 100644 --- a/drivers/aic8800/aic8800_fdrv/aic_br_ext.c +++ b/drivers/aic8800/aic8800_fdrv/aic_br_ext.c @@ -1,23 +1,30 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2017 Realtek Corporation. + * Copyright (C) 2019-2021 Aicsemi Corporation * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * http://www.apache.org/licenses/LICENSE-2.0 * - *****************************************************************************/ + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + #define _AIC_BR_EXT_C_ +#include #ifdef __KERNEL__ #include #include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0) #include +#endif #include #include #include @@ -54,6 +61,7 @@ #define MAGIC_CODE_LEN 2 #define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */ + /*----------------------------------------------------------------- How database records network address: 0 1 2 3 4 5 6 7 8 9 10 @@ -503,7 +511,6 @@ static void __nat25_db_network_insert(struct rwnx_vif *vif, spin_unlock_bh(&vif->br_ext_lock); } - static void __nat25_db_print(struct rwnx_vif *vif) { spin_lock_bh(&vif->br_ext_lock); @@ -746,6 +753,22 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method) protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN)); +#if 0 + printk("nat25_db_handle: DA=%02x%02x%02x%02x%02x%02x SA=%02x%02x%02x%02x%02x%02x\n", + skb->data[0], + skb->data[1], + skb->data[2], + skb->data[3], + skb->data[4], + skb->data[5], + skb->data[6], + skb->data[7], + skb->data[8], + skb->data[9], + skb->data[10], + skb->data[11]); +#endif + /*---------------------------------------------------*/ /* Handle IP frame */ /*---------------------------------------------------*/ @@ -849,7 +872,6 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method) case NAT25_LOOKUP: { printk("NAT25: Lookup ARP\n"); - arp_ptr += arp->ar_hln; sender = (unsigned int *)arp_ptr; arp_ptr += (arp->ar_hln + arp->ar_pln); @@ -874,23 +896,34 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method) /*---------------------------------------------------*/ /* Handle IPX and Apple Talk frame */ /*---------------------------------------------------*/ - else if ((protocol == __constant_htons(ETH_P_IPX)) || + else if ( +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0) + (protocol == __constant_htons(ETH_P_IPX)) || +#endif (protocol == __constant_htons(ETH_P_ATALK)) || (protocol == __constant_htons(ETH_P_AARP))) { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0) unsigned char ipx_header[2] = {0xFF, 0xFF}; struct ipxhdr *ipx = NULL; +#endif struct elapaarp *ea = NULL; struct ddpehdr *ddp = NULL; unsigned char *framePtr = skb->data + ETH_HLEN; +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0) if (protocol == __constant_htons(ETH_P_IPX)) { printk("NAT25: Protocol=IPX (Ethernet II)\n"); ipx = (struct ipxhdr *)framePtr; - } else { /* if(protocol <= __constant_htons(ETH_FRAME_LEN)) */ + } else +#endif + { /* if(protocol <= __constant_htons(ETH_FRAME_LEN)) */ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0) if (!memcmp(ipx_header, framePtr, 2)) { printk("NAT25: Protocol=IPX (Ethernet 802.3)\n"); ipx = (struct ipxhdr *)framePtr; - } else { + } else +#endif + { unsigned char ipx_8022_type = 0xE0; unsigned char snap_8022_type = 0xAA; @@ -900,13 +933,15 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method) unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; /* Apple Talk DDP SNAP ID */ framePtr += 3; /* eliminate the 802.2 header */ - +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0) if (!memcmp(ipx_snap_id, framePtr, 5)) { framePtr += 5; /* eliminate the SNAP header */ printk("NAT25: Protocol=IPX (Ethernet SNAP)\n"); ipx = (struct ipxhdr *)framePtr; - } else if (!memcmp(aarp_snap_id, framePtr, 5)) { + } else +#endif + if (!memcmp(aarp_snap_id, framePtr, 5)) { framePtr += 5; /* eliminate the SNAP header */ ea = (struct elapaarp *)framePtr; @@ -919,7 +954,9 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method) framePtr[1], framePtr[2], framePtr[3], framePtr[4]); return -1; } - } else if (*framePtr == ipx_8022_type) { + } +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0) + else if (*framePtr == ipx_8022_type) { framePtr += 3; /* eliminate the 802.2 header */ if (!memcmp(ipx_header, framePtr, 2)) { @@ -928,9 +965,11 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method) } else return -1; } +#endif } } +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0) /* IPX */ if (ipx != NULL) { switch (method) { @@ -997,10 +1036,11 @@ int nat25_db_handle(struct rwnx_vif *vif, struct sk_buff *skb, int method) default: return -1; } - } + }else +#endif /* AARP */ - else if (ea != NULL) { + if (ea != NULL) { /* Sanity check fields. */ if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) { printk("NAT25: Appletalk AARP Sanity check fail!\n"); diff --git a/drivers/aic8800/aic8800_fdrv/aic_br_ext.h b/drivers/aic8800/aic8800_fdrv/aic_br_ext.h index 71ebeb2..fa8f419 100644 --- a/drivers/aic8800/aic8800_fdrv/aic_br_ext.h +++ b/drivers/aic8800/aic8800_fdrv/aic_br_ext.h @@ -1,17 +1,21 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2017 Realtek Corporation. + * Copyright (C) 2019-2021 Aicsemi Corporation * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * http://www.apache.org/licenses/LICENSE-2.0 * - *****************************************************************************/ + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + #ifndef _AIC_BR_EXT_H_ #define _AIC_BR_EXT_H_ diff --git a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c index a09fe79..14f5904 100644 --- a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c +++ b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c @@ -11,8 +11,6 @@ */ #include -#include -#include #include #include "rwnx_defs.h" #include "rwnx_msg_tx.h" @@ -90,6 +88,7 @@ enum { EXEC_FLASH_OPER, RDWR_PWRADD2X, RDWR_EFUSE_PWRADD2X, + GET_RSSI=0x52, CHECK_FLASH=0x108, }; @@ -342,7 +341,7 @@ static int aic_priv_cmd_set_tx (struct rwnx_hw *rwnx_hw, int argc, char *argv[], AICWFDBG(LOGINFO, "txparam:%d,%d,%d,%d,%d,%d\n", settx_param.chan, settx_param.bw, settx_param.mode, settx_param.rate, settx_param.length, settx_param.tx_intv_us); #ifdef CONFIG_POWER_LIMIT - r_idx = get_ccode_region(country_code); + r_idx = get_ccode_region(rwnx_hw->wiphy->regd->alpha2); txpwr_loss = &txpwr_loss_tmp; get_userconfig_txpwr_loss(txpwr_loss); if (txpwr_loss->loss_enable_2g4 == 1) @@ -797,7 +796,10 @@ static int aic_priv_cmd_rdwr_pwrlvl (struct rwnx_hw *rwnx_hw, int argc, char *ar AICWFDBG(LOGERROR, "wrong func: %x\n", func); return -EINVAL; } - if((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)){ + if((dev->chipid == PRODUCT_ID_AIC8800D81)|| + (dev->chipid == PRODUCT_ID_AIC8800D81X2) || + (dev->chipid == PRODUCT_ID_AIC8800D89X2) || + (dev->chipid == PRODUCT_ID_AIC8800D80N)) { memcpy(command, &cfm.rftest_result[0], 6 * 12); return (6 * 12); } else { @@ -823,16 +825,19 @@ static int aic_priv_cmd_rdwr_pwrofst (struct rwnx_hw *rwnx_hw, int argc, char *a if (func == 0) { // read cur rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, 0, NULL, &cfm); } else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1 - if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2))) { + if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || + (dev->chipid == PRODUCT_ID_AIC8800D81X2) || + (dev->chipid == PRODUCT_ID_AIC8800D89X2) || + (dev->chipid == PRODUCT_ID_AIC8800D80N))) { u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16); u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16); - s8_l pwrofst = (u8_l)command_strtoul(argv[4], NULL, 10); + s8_l pwrofst = (s8_l)command_strtoul(argv[4], NULL, 10); u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst}; AICWFDBG(LOGINFO, "set pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst); rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm); - } else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC))) { + } else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DLN))) { u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); - s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); + s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10); u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; AICWFDBG(LOGINFO, "set pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst); rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm); @@ -843,9 +848,9 @@ static int aic_priv_cmd_rdwr_pwrofst (struct rwnx_hw *rwnx_hw, int argc, char *a AICWFDBG(LOGERROR, "wrong func: %x\n", func); return -EINVAL; } - if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW)) { // 3 = 3 (2.4g) + if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DLN)) { // 3 = 3 (2.4g) res_len = 3; - } else if (dev->chipid == PRODUCT_ID_AIC8800D81) { // 3 * 2 (2.4g) + 3 * 6 (5g) + } else if ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D80N)) { // 3 * 2 (2.4g) + 3 * 6 (5g) res_len = 3 * 3 + 3 * 6; } else if ((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // ant0/1 res_len = ( 3 * 3 + 3 * 6 ) * 2; @@ -868,7 +873,7 @@ static int aic_priv_cmd_rdwr_pwrofstfine (struct rwnx_hw *rwnx_hw, int argc, cha } else if (func <= 2) { // write 2.4g/5g pwr ofst if (argc > 3) { u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); - s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); + s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10); u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst); rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFSTFINE, sizeof(buf), buf, &cfm); @@ -930,16 +935,17 @@ static int aic_priv_cmd_rdwr_efuse_pwrofst (struct rwnx_hw *rwnx_hw, int argc, c if (func == 0) { // read cur rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, 0, NULL, &cfm); } else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1 - if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2))) { + if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2) + || (dev->chipid == PRODUCT_ID_AIC8800D80N))) { u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16); u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16); - s8_l pwrofst = (u8_l)command_strtoul(argv[4], NULL, 10); + s8_l pwrofst = (s8_l)command_strtoul(argv[4], NULL, 10); u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst}; AICWFDBG(LOGINFO, "set efuse pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst); rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm); - } else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC))) { + } else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DLN))) { u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); - s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); + s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10); u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; AICWFDBG(LOGINFO, "set efuse pwrofst_%s:[%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", chgrp, pwrofst); rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm); @@ -951,9 +957,9 @@ static int aic_priv_cmd_rdwr_efuse_pwrofst (struct rwnx_hw *rwnx_hw, int argc, c AICWFDBG(LOGERROR, "wrong func: %x\n", func); return -EINVAL; } - if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW)) { // 6 = 3 (2.4g) * 2 + if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DLN)) { // 6 = 3 (2.4g) * 2 res_len = 3 * 2; - } else if (dev->chipid == PRODUCT_ID_AIC8800D81) { // 3 * 2 (2.4g) + 3 * 6 (5g) + } else if ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D80N)) { // 3 * 2 (2.4g) + 3 * 6 (5g) res_len = (3 * 3 + 3 * 6) * 2; } else if((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // 3 * 2 (2.4g) *2 + 3 * 6 (5g) *2 res_len = (3 * 3 + 3 * 6) * 2 * 2; @@ -976,7 +982,7 @@ static int aic_priv_cmd_rdwr_efuse_pwrofstfine (struct rwnx_hw *rwnx_hw, int arg } else if (func <= 2) { // write 2.4g/5g pwr ofst if (argc > 3) { u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); - s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); + s8_l pwrofst = (s8_l)command_strtoul(argv[3], NULL, 10); u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst); rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFSTFINE, sizeof(buf), buf, &cfm); @@ -1273,6 +1279,49 @@ static int aic_priv_cmd_set_pll_test (struct rwnx_hw *rwnx_hw, int argc, char *a return 0; } +static int aic_priv_cmd_get_txpwr(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) +{ + s8_l power=0; + power = get_txpwr_max(power); + memcpy(command, &power, 1); + return 1; +} + +static int aic_priv_cmd_set_txpwr_loss(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) +{ + s8_l func; +#ifdef AICWF_SDIO_SUPPORT + struct aic_sdio_dev *dev = g_rwnx_plat->sdiodev; +#endif +#ifdef AICWF_USB_SUPPORT + struct aic_usb_dev *dev = g_rwnx_plat->usbdev; +#endif + + if (argc > 1) { + func = (s8_l)command_strtoul(argv[1], NULL, 10); + AICWFDBG(LOGINFO, "set txpwr loss: %d\n", func); + if (dev->chipid == PRODUCT_ID_AIC8800D81 || + dev->chipid == PRODUCT_ID_AIC8800D80N){ + set_txpwr_loss_ofst(func); + rwnx_send_txpwr_lvl_v3_req(dev->rwnx_hw); + }else if(dev->chipid == PRODUCT_ID_AIC8800D81X2 || + dev->chipid == PRODUCT_ID_AIC8800D89X2){ + set_txpwr_loss_ofst(func); + rwnx_send_txpwr_lvl_v4_req(dev->rwnx_hw); + }else if(dev->chipid == PRODUCT_ID_AIC8800DC || + dev->chipid == PRODUCT_ID_AIC8800DW){ + set_txpwr_loss_ofst(func); + rwnx_send_txpwr_lvl_req(dev->rwnx_hw); + }else{ + AICWFDBG(LOGINFO, "error:don't support 8800D"); + } + } else { + AICWFDBG(LOGERROR, "wrong args\n"); + return -EINVAL; + } + return 0; +} + static int aic_priv_cmd_set_ant_mode (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) { u8_l func = 0; @@ -1340,6 +1389,12 @@ static int aic_priv_cmd_country_set(struct rwnx_hw *rwnx_hw, int argc, return -1; } + if (!rwnx_hw->mod_params->custregd) { + AICWFDBG(LOGERROR, "%s: invalid custregd\n", __func__); + return -1; + } + + AICWFDBG(LOGINFO, "cmd country_set: %s\n", argv[1]); regdomain = getRegdomainFromRwnxDB(rwnx_hw->wiphy, argv[1]); @@ -1474,6 +1529,58 @@ static int aic_priv_cmd_check_flash(struct rwnx_hw *rwnx_hw, int argc, char *arg return 8; } +static int aic_priv_cmd_get_rssi(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) +{ + rwnx_send_rftest_req(rwnx_hw, GET_RSSI, 0, NULL, &cfm); + memcpy(command, &cfm.rftest_result[0], 1); + + AICWFDBG(LOGINFO, "get_rssi: %d\n", (char)cfm.rftest_result[0]); + + return 1; +} + +#ifdef CONFIG_DYNAMIC_PERPWR +static int aic_priv_cmd_set_sta_thd(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) +{ + int i; + s8_l val; + + if (argc < 3) { + AICWFDBG(LOGERROR, "%s: Invalid parameters (argc=%d)\n", __func__, argc); + return -EINVAL; + } + + AICWFDBG(LOGDEBUG, "cmd set_sta_thd: %s, %s\n", argv[1], argv[2]); + + val = (s8_l)command_strtoul(argv[2], NULL, 10); + + struct { + const char *name; + s8_l *target; + size_t name_len; + } thd_map[] = { + { "rssi_thd_0", &rwnx_hw->pwrth.rssi_thd_0, 10 }, + { "rssi_thd_1", &rwnx_hw->pwrth.rssi_thd_1, 10 }, + { "rssi_thd_2", &rwnx_hw->pwrth.rssi_thd_2, 10 }, + { "pwr_loss_lvl_0", &rwnx_hw->pwrth.pwr_loss_lvl_0, 14 }, + { "pwr_loss_lvl_1", &rwnx_hw->pwrth.pwr_loss_lvl_1, 14 }, + { "pwr_loss_lvl_2", &rwnx_hw->pwrth.pwr_loss_lvl_2, 14 }, + { "pwr_loss_lvl_3", &rwnx_hw->pwrth.pwr_loss_lvl_3, 14 }, + }; + + for (i = 0; i < ARRAY_SIZE(thd_map); i++) { + if (strncmp(argv[1], thd_map[i].name, thd_map[i].name_len) == 0) { + *thd_map[i].target = val; + AICWFDBG(LOGINFO, "%s: %s = %d\n", __func__, thd_map[i].name, val); + return 0; + } + } + + AICWFDBG(LOGERROR, "%s: Unknown parameter '%s'\n", __func__, argv[1]); + return -EINVAL; +} +#endif + static int aic_priv_cmd_help (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) { print_help(argc > 0 ? argv[0] : NULL); @@ -1575,6 +1682,10 @@ static const struct aic_priv_cmd aic_priv_commands[] = { "= off usb configure before usb disconnect" }, { "set_pll_test", aic_priv_cmd_set_pll_test, " = use pll test to measure saturation power" }, + { "get_txpwr", aic_priv_cmd_get_txpwr, + "= get userconfig max txpwr" }, + { "set_txpwr_loss",aic_priv_cmd_set_txpwr_loss, + " = txpwr will change ,val can be negative" }, { "set_ant", aic_priv_cmd_set_ant_mode, " = 0/ant0, 1/ant1, 2/both" }, { "rdwr_bt_efuse_pwrofst", aic_priv_cmd_rdwr_bt_efuse_pwrofst, @@ -1589,6 +1700,11 @@ static const struct aic_priv_cmd aic_priv_commands[] = { "a value is added for both 2.4G and 5G to achieve overall power adjustment of the band, write to efuse"}, {"check_flash", aic_priv_cmd_check_flash, "check bin crc in flash" }, + {"get_rssi", aic_priv_cmd_get_rssi, "get rssi"}, +#ifdef CONFIG_DYNAMIC_PERPWR + {"set_sta_thd", aic_priv_cmd_set_sta_thd, + "set per_sta power threshold, (set_sta_thd rssi_thd_0 value; set_sta_thd pwr_loss_lvl_0 value)"}, +#endif //Reserve for new aic_priv_cmd. { "help", aic_priv_cmd_help, @@ -1794,7 +1910,7 @@ int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val) } memset(&cs_info, 0, sizeof(struct aicwf_cs_info)); - memcpy(cs_info.countrycode, country_code, 4); + memcpy(cs_info.countrycode, vif->rwnx_hw->wiphy->regd->alpha2, 2); if((sta == NULL) && (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_AP)) { sta = &vif->rwnx_hw->sta_table[vif->ap.bcmc_index]; @@ -1940,6 +2056,11 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) strncasecmp(command, "country_set", strlen("country_set"))) { skip = strlen(CMD_SET_COUNTRY) + 1; country = command + skip; + if (!vif->rwnx_hw->mod_params->custregd) { + AICWFDBG(LOGERROR, "%s: invalid custregd\n", __func__); + ret = -EINVAL; + goto exit; + } if (!country || strlen(country) < RWNX_COUNTRY_CODE_LEN) { AICWFDBG(LOGERROR, "%s: invalid country code\n", __func__); ret = -EINVAL; @@ -1991,9 +2112,11 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) if(g_rwnx_plat && g_rwnx_plat->usbdev->rwnx_hw){ if (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW || (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DC) || + (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DLN) || (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81) || (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81X2) || - (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D89X2)){ + (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) || + (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D80N)){ set_testmode(!testmode); rwnx_send_reboot(g_rwnx_plat->usbdev->rwnx_hw); } diff --git a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h index 50c9783..a51ae48 100644 --- a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h +++ b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h @@ -59,6 +59,14 @@ typedef struct _compat_android_wifi_priv_cmd { int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd); int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val); +unsigned int command_strtoul(const char *cp, char **endp, unsigned int base); +int str_starts(const char *str, const char *start); +int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter); +#else +void set_mon_chan(struct rwnx_vif *vif, char *parameter); +#endif #endif /* _AIC_PRIV_CMD_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/aic_vendor.c b/drivers/aic8800/aic8800_fdrv/aic_vendor.c index 5394c71..2645f62 100644 --- a/drivers/aic8800/aic8800_fdrv/aic_vendor.c +++ b/drivers/aic8800/aic8800_fdrv/aic_vendor.c @@ -323,6 +323,13 @@ static int aicwf_vendor_subcmd_set_country_code(struct wiphy *wiphy, struct wire const struct nlattr *iter; struct ieee80211_regdomain *regdomain; + struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); + + if (!rwnx_hw->mod_params->custregd) { + AICWFDBG(LOGERROR, "%s: invalid custregd\n", __func__); + return -EINVAL; + } + nla_for_each_attr(iter, data, len, rem) { type = nla_type(iter); switch (type) { diff --git a/drivers/aic8800/aic8800_fdrv/aic_vendor.h b/drivers/aic8800/aic8800_fdrv/aic_vendor.h index 0e1e3e0..2ac3e5f 100644 --- a/drivers/aic8800/aic8800_fdrv/aic_vendor.h +++ b/drivers/aic8800/aic8800_fdrv/aic_vendor.h @@ -2,6 +2,7 @@ #define _AIC_VENDOR_H #include +#include "rwnx_defs.h" #define GOOGLE_OUI 0x001A11 #define BRCM_OUI 0x001018 @@ -342,5 +343,10 @@ typedef struct wl_mkeep_alive_pkt { u8 data[1]; } wl_mkeep_alive_pkt_t; +int aic_dev_start_mkeep_alive(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, + u8 mkeep_alive_id, u8 *ip_pkt, u16 ip_pkt_len, u8 *src_mac, u8 *dst_mac, u32 period_msec); +int aic_dev_stop_mkeep_alive(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, u8 mkeep_alive_id); +int aicwf_vendor_init(struct wiphy *wiphy); + #endif /* _AIC_VENDOR_H */ diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c index 81eaabd..bdba575 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c @@ -1,11 +1,9 @@ #include "rwnx_main.h" #include "rwnx_msg_tx.h" #include "reg_access.h" +#include "aicwf_compat_8800d80.h" #define FW_USERCONFIG_NAME_8800D80 "aic_userconfig_8800d80.txt" -#define FW_USERCONFIG_NAME_8800D80_U11 "aic_userconfig_8800d80_u11.txt" -#define FW_USERCONFIG_NAME_8800D80_U11_PRO "aic_userconfig_8800d80_u11_pro.txt" -#define FW_USERCONFIG_NAME_8800D80_U11_CUS "aic_userconfig_8800d80_u11_cus.txt" #define FW_POWERLIMIT_NAME_8800D80 "aic_powerlimit_8800d80.txt" extern char aic_fw_path[200]; @@ -40,20 +38,6 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){ int size; u32 *dst=NULL; 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_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_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; - } #ifndef ANDROID_PLATFORM sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80"); @@ -102,7 +86,7 @@ int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw) AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); /* parsing the file */ - rwnx_plat_powerlimit_parsing((char *)dst, size, country_code); + rwnx_plat_powerlimit_parsing((char *)dst, size); rwnx_release_firmware_common(&dst); @@ -111,3 +95,37 @@ int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw) } #endif +int system_config_8800d80(struct rwnx_hw *rwnx_hw) +{ + int ret; + const u32 mem_addr = 0x40500000; + const u32 read_mem_addr = 0x40241014; + struct dbg_mem_read_cfm rd_mem_addr_cfm; + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm); + if (ret) { + AICWFDBG(LOGINFO, "%x rd fail: %d\n", mem_addr, ret); + return ret; + } + if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL) { + chip_mcu_id = 1; + } + chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16); + AICWFDBG(LOGINFO, "chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id); + if (testmode == 1 && (IS_CHIP_ID_H())) + { + struct dbg_mem_read_cfm rd_mem_addr_cfm; + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, read_mem_addr, &rd_mem_addr_cfm); + AICWFDBG(LOGINFO, "%s 0x%08x=0x%08x\n", __func__, read_mem_addr, rd_mem_addr_cfm.memdata); + if (ret) { + AICWFDBG(LOGERROR, "%x rd fail: %d\n", read_mem_addr, ret); + return ret; + } else { + if (rd_mem_addr_cfm.memdata != 1) { + AICWFDBG(LOGERROR, "check fail: %x\n", rd_mem_addr_cfm.memdata); + return -1; + } + } + } + return 0; +} + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.h b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.h index 134fd1a..40fe9d0 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.h @@ -5,5 +5,5 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw); int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw); #endif int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm); - +int system_config_8800d80(struct rwnx_hw *rwnx_hw); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80n.c b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80n.c new file mode 100644 index 0000000..c737b37 --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80n.c @@ -0,0 +1,560 @@ +#include "rwnx_main.h" +#include "rwnx_msg_tx.h" +#include "reg_access.h" +#include "rwnx_platform.h" +#include "aicwf_compat_8800d80n.h" + +#define FW_USERCONFIG_NAME_8800D80N "aic_userconfig_8800d80n.txt" +#define FW_POWERLIMIT_NAME_8800D80N "aic_powerlimit_8800d80n.txt" +#define RWNX_MAC_FW_RF_BASE_NAME_8800D80N "lmacfw_rf_8800d80n.bin" +#define RWNX_MAC_FW_INITVAR_NAME_8800D80N "fmacfw_initvar_8800d80n.bin" +#define RWNX_MAC_FW_GAINTBL_NAME_8800D80N "fmacfw_gaintbl_8800d80n.bin" +#define RWNX_MAC_FW_CINIT_NAME_8800D80N_U02 "fmacfw_cinit_8800d80n_u02.bin" +#define RWNX_MAC_FW_CALIB_NAME_8800D80N_U02 "fmacfw_calib_8800d80n_u02.bin" +#define RWNX_MAC_PATCH_NAME_8800D80N_U02 "fmacfw_patch_8800d80n_u02.bin" +#define RWNX_MAC_PATCHTBL_NAME_8800D80N_U02 "fmacfw_patch_tbl_8800d80n_u02.bin" + +#define RAM_LMAC_FW_RF_ADDR_8800D80N 0x00132C00 +#define ROM_FMAC_CINIT_ADDR_8800D80N_U02 0x00133000 +#define ROM_FMAC_CALIB_ADDR_8800D80N_U02 0x00138000 +#define ROM_FMAC_PATCH_ADDR_8800D80N_U02 0x00188000 + +#define CHIP_INFO_FLAG_CINIT_BEGIN (0x01U << 12) +#define CHIP_INFO_FLAG_CINIT_DONE (0x01U << 13) + +#define PATCH_VAR_FLAG_CALIB_BEGIN (0x01U << 0) +#define PATCH_VAR_FLAG_CALIB_DONE (0x01U << 1) + +#define WF_RXGAIN_TBL_IDX_MAX 20 +#define WF_RXGAIN_TBL_SIZE 256 +#define WF_TXGAIN_TBL_IDX_MAX 21 +#define WF_TXGAIN_TBL_SIZE 128 + +extern char aic_fw_path[200]; + +int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr, + char *filename); +int rwnx_plat_bin_fw_upload_2_with_version(struct rwnx_hw *rwnx_hw, u32 fw_addr, + char *filename, char *version_str, int version_size); +int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw, + u32** buffer, const char *filename); +void rwnx_plat_userconfig_parsing(char *buffer, int size); +void rwnx_release_firmware_common(u32** buffer); + +extern int get_adap_test(void); + +typedef u32 (*array2_tbl_t)[2]; +typedef u32 (*array3_tbl_t)[3]; + +u32 syscfg_tbl_masked_8800d80n[][3] = { + // {Address, mask, value} + #if DEF_PATCH_METHOD_VER_1 // moved to cinit.bin + // anareg1, u01 only + {0x4050201C, (0x7 << 0), (0x7 << 0)}, + // pmic_pmu_init + {0x70001024, ((0x1F << 0) | (0x1 << 14) | (0x1 << 15)), + ((0x08 << 0) | (0x1 << 14) | (0x1 << 15))}, + {0x70001044, (0xF << 20), (0x4 << 20)}, + {0x70001084, ((0xF << 23) | (0x1 << 27) | (0x1 << 31)), + ((0x4 << 23) | (0x0 << 27) | (0x1 << 31))}, + {0x70002118, (0x3 << 0), (0x0 << 0)}, + {0x7000211C, (0x3 << 2), (0x0 << 2)}, + {0x700021D8, (0x3 << 4), (0x0 << 4)}, + {0x700021D0, ((0x1 << 5) | (0x1 << 6)), + ((0x1 << 5) | (0x1 << 6))}, + #if defined(CONFIG_VRF_DCDC_MODE) + {0x70001000, (0x1 << 0), (0x1 << 0)}, + #else + {0x70001000, (0x1 << 0), (0x0 << 0)}, + #endif + // cm_rf_init + {0x4050500C, ((0x7 << 27) | (0x3 << 30)), + ((0x3 << 27) | (0x3 << 30))}, + {0x40505008, ((0x3 << 11) | (0xF << 15)), + ((0x1 << 11) | (0x4 << 15))}, + #endif + {0x00000000, 0x00000000, 0x00000000}, // last one +}; + +u32 patch_tbl_wifisetting_8800d80n[][2] = +{ + //{0x00b8, 0x00009d08 | (0x01U << 13)}, // debug_mask, bit13: CALIB_BIT +}; + +//adap test +u32 adaptivity_patch_tbl_8800d80n[][2] = { +}; + +u32 patch_tbl_rf_func_8800d80n[][2] = +{ +}; + +extern int testmode; +extern u8 chip_id; +extern u8 chip_mcu_id; + +void system_config_8800d80n(struct rwnx_hw *rwnx_hw) +{ + int syscfg_num; + array3_tbl_t p_syscfg_msk_tbl; + int ret, cnt; + const u32 mem_addr = 0x40500000; + struct dbg_mem_read_cfm rd_mem_addr_cfm; + + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm); + if (ret) { + AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret); + return; + } + chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16); + //printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata); + if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL) { + chip_mcu_id = 1; + } + + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm); + if (ret) { + AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret); + return; + } + chip_sub_id = (u8)(rd_mem_addr_cfm.memdata); + //printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata); + AICWFDBG(LOGINFO, "chip_id=%x, chip_sub_id=%x\n", chip_id, chip_sub_id); + + syscfg_num = sizeof(syscfg_tbl_masked_8800d80n) / sizeof(u32) / 3; + p_syscfg_msk_tbl = syscfg_tbl_masked_8800d80n; + + for (cnt = 0; cnt < syscfg_num; cnt++) { + if (p_syscfg_msk_tbl[cnt][0] == 0x00000000) { + break; + } + + ret = rwnx_send_dbg_mem_mask_write_req(rwnx_hw, + p_syscfg_msk_tbl[cnt][0], p_syscfg_msk_tbl[cnt][1], p_syscfg_msk_tbl[cnt][2]); + if (ret) { + AICWFDBG(LOGERROR, "%x mask write fail: %d\n", p_syscfg_msk_tbl[cnt][0], ret); + return; + } + } +} + +int aicwf_plat_patch_load_8800d80n(struct rwnx_hw *rwnx_hw) +{ + int ret = 0; + char patch_ver_str[128]; + //wifi patch + ret = rwnx_plat_bin_fw_upload_2_with_version(rwnx_hw, + ROM_FMAC_PATCH_ADDR_8800D80N_U02, RWNX_MAC_PATCH_NAME_8800D80N_U02, patch_ver_str, sizeof(patch_ver_str)); + if (ret) { + AICWFDBG(LOGERROR, "load patch bin fail: %d\n", ret); + return ret; + } + AICWFDBG(LOGINFO, "PatchVer: %s", patch_ver_str); + return ret; +} + +int aicwf_plat_patch_table_load_8800d80n(struct rwnx_hw *rwnx_hw) +{ + int err = 0; + unsigned int i, size; + u32 *dst = NULL; + char *filename = RWNX_MAC_PATCHTBL_NAME_8800D80N_U02; + + /* Copy the file on the Embedded side */ + AICWFDBG(LOGINFO, "### Upload %s \n", filename); + + size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); + if (!dst) { + AICWFDBG(LOGERROR, "No such file or directory\n"); + return -1; + } + if (size <= 0) { + AICWFDBG(LOGERROR, "wrong size of firmware file\n"); + dst = NULL; + err = -1; + } + AICWFDBG(LOGINFO, "tbl size = %d \n", size); + + if (!err) { + for (i = 0; i < (size / 4); i += 2) { + if ((dst[i] == 0x0) || (dst[i] == 0xFFFFFFFF)) { + break; // end of tbl + } + AICWFDBG(LOGERROR, "patch_tbl: %x %x\n", dst[i], dst[i+1]); + err = rwnx_send_dbg_mem_write_req(rwnx_hw, dst[i], dst[i+1]); + } + if (err) { + AICWFDBG(LOGERROR, "tbl bin upload fail: %x, err:%d\r\n", dst[i], err); + } + } + + if (dst) { + rwnx_release_firmware_common(&dst); + } + + return err; + +} + +void aicwf_patch_config_8800d80n(struct rwnx_hw *rwnx_hw) +{ + #ifdef CONFIG_ROM_PATCH_EN + int ret = 0; + int cnt = 0; + +//adap test + int adap_test = 0; + int adap_patch_num = 0; + + adap_test = get_adap_test(); +//adap test + + if (testmode == 0) { + const u32 cfg_base = 0x10170; + struct dbg_mem_read_cfm cfm; + //int i; + u32 wifisetting_cfg_addr; + u32 agc_cfg_addr; + u32 txgain_cfg_24g_addr, txgain_cfg_5g_addr; + u32 jump_tbl_addr = 0; + + u32 patch_tbl_wifisetting_num = sizeof(patch_tbl_wifisetting_8800d80n)/sizeof(u32)/2; + //u32 jump_tbl_size = 0; + //u32 patch_tbl_func_num = 0; + + //array2_tbl_t jump_tbl_base = NULL; + //array2_tbl_t patch_tbl_func_base = NULL; + + if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm))) { + AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", cfg_base, ret); + } + wifisetting_cfg_addr = cfm.memdata; + + if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 4, &cfm))) { + AICWFDBG(LOGERROR, "jump_tbl base[0x%x] rd fail: %d\n", cfg_base + 4, ret); + } + jump_tbl_addr = cfm.memdata; + + if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x10, &cfm))) { + AICWFDBG(LOGERROR, "agc_cfg base[0x%x] rd fail: %d\n", cfg_base + 0xc, ret); + } + agc_cfg_addr = cfm.memdata; + + if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) { + AICWFDBG(LOGERROR, "txgain_cfg_24g base[0x%x] rd fail: %d\n", cfg_base + 0x10, ret); + } + txgain_cfg_24g_addr = cfm.memdata; + + if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x18, &cfm))) { + AICWFDBG(LOGERROR, "txgain_cfg_5g base[0x%x] rd fail: %d\n", cfg_base + 0x10, ret); + } + txgain_cfg_5g_addr = cfm.memdata; + + AICWFDBG(LOGINFO, "wifisetting_cfg_addr=%x, jump_tbl_addr=%x, agc_cfg_addr=%x, txgain_cfg_24g_addr=%x, txgain_cfg_5g_addr=%x\n", + wifisetting_cfg_addr, jump_tbl_addr, agc_cfg_addr, txgain_cfg_24g_addr, txgain_cfg_5g_addr); + + for (cnt = 0; cnt < patch_tbl_wifisetting_num; cnt++) { + if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + patch_tbl_wifisetting_8800d80n[cnt][0], patch_tbl_wifisetting_8800d80n[cnt][1]))) { + AICWFDBG(LOGERROR, "wifisetting %x write fail\n", patch_tbl_wifisetting_8800d80n[cnt][0]); + } + } + + //adap test + if (adap_test) { + adap_patch_num = sizeof(adaptivity_patch_tbl_8800d80n)/sizeof(u32)/2; + for(cnt = 0; cnt < adap_patch_num; cnt++) + { + if((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + adaptivity_patch_tbl_8800d80n[cnt][0], adaptivity_patch_tbl_8800d80n[cnt][1]))) { + AICWFDBG(LOGERROR, "%x write fail\n", wifisetting_cfg_addr + adaptivity_patch_tbl_8800d80n[cnt][0]); + } + } + } + //adap test + + #if DEF_PATCH_METHOD_VER_1 + ret = aicwf_plat_initvar_load_8800d80n(rwnx_hw, txgain_cfg_24g_addr); + if (ret) { + AICWFDBG(LOGERROR, "initvar load fail: %d\n", ret); + return; + } + #endif + } + else { + u32 patch_tbl_rf_func_num = sizeof(patch_tbl_rf_func_8800d80n)/sizeof(u32)/2; + for (cnt = 0; cnt < patch_tbl_rf_func_num; cnt++) { + if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_rf_func_8800d80n[cnt][0], patch_tbl_rf_func_8800d80n[cnt][1]))) { + AICWFDBG(LOGERROR, "patch_tbl_rf_func %x write fail\n", patch_tbl_rf_func_8800d80n[cnt][0]); + } + } + } + #endif +} + +int aicwf_plat_rftest_load_8800d80n(struct rwnx_hw *rwnx_hw) +{ + int ret = 0; + ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, RAM_LMAC_FW_RF_ADDR_8800D80N, RWNX_MAC_FW_RF_BASE_NAME_8800D80N); + if (ret) { + AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret); + return ret; + } + return ret; +} + +int aicwf_plat_rftest_exec_8800d80n(struct rwnx_hw *rwnx_hw) +{ + int ret = 0; + uint32_t fw_addr, boot_type; + uint32_t rst_hdlr_addr = RAM_LMAC_FW_RF_ADDR_8800D80N + 0x04; + uint32_t rst_hdlr_val; + struct dbg_mem_read_cfm rd_mem_addr_cfm; + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, rst_hdlr_addr, &rd_mem_addr_cfm); + if (ret) { + AICWFDBG(LOGERROR, "%x rd fail: %d\n", rst_hdlr_addr, ret); + return ret; + } + rst_hdlr_val = rd_mem_addr_cfm.memdata; + if ((rst_hdlr_val & ~0x03FF) == RAM_LMAC_FW_RF_ADDR_8800D80N) { + AICWFDBG(LOGINFO, "rftest loaded, hdlr=%x\n", rst_hdlr_val); + } + /* fw start */ + fw_addr = RAM_LMAC_FW_RF_ADDR_8800D80N; + boot_type = HOST_START_APP_AUTO; + AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type); + ret = rwnx_send_dbg_start_app_req(rwnx_hw, fw_addr, boot_type); + if (ret) { + AICWFDBG(LOGERROR, "start app fail: %d\n", ret); + return ret; + } + return ret; +} + +#if DEF_PATCH_METHOD_VER_1 +int aicwf_plat_initvar_load_8800d80n(struct rwnx_hw *rwnx_hw, u32 var_base_addr) +{ + int ret = 0; + ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, var_base_addr, RWNX_MAC_FW_INITVAR_NAME_8800D80N); + if (ret) { + AICWFDBG(LOGERROR, "load initvar bin fail: %d\n", ret); + return ret; + } + return ret; +} + +int aicwf_plat_gain_table_load_8800d80n(struct rwnx_hw *rwnx_hw) +{ + int size, desired_size, idx, ret; + u32 *dst=NULL; + u8_l *tbl_base; + char *filename = RWNX_MAC_FW_GAINTBL_NAME_8800D80N; + + AICWFDBG(LOGINFO, "gaintbl file path:%s\n", filename); + + /* load file */ + size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); + desired_size = WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE + WF_TXGAIN_TBL_IDX_MAX * WF_TXGAIN_TBL_SIZE; + if ((size <= 0) || (size != desired_size)) { + AICWFDBG(LOGERROR, "wrong size of firmware file, desired=%d, size=%d\n", desired_size, size); + if (dst) { + rwnx_release_firmware_common(&dst); + dst = NULL; + } + return 0; + } + + /* Copy the file on the Embedded side */ + AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); + + /* RX gain */ + tbl_base = (u8_l *)dst; + for (idx = 0; idx < WF_RXGAIN_TBL_IDX_MAX; idx++) { + u16_l ofst = idx * 16; + u8_l *tbl_ptr = tbl_base + idx * WF_RXGAIN_TBL_SIZE; + ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 0, tbl_ptr, WF_RXGAIN_TBL_SIZE); + if (ret) { + AICWFDBG(LOGERROR, "rx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst); + break; + } + } + + /* TX gain */ + tbl_base = (u8_l *)dst + WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE; + for (idx = 0; idx < WF_TXGAIN_TBL_IDX_MAX; idx++) { + u16_l ofst = idx * 16; + u8_l *tbl_ptr = tbl_base + idx * WF_TXGAIN_TBL_SIZE; + ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 2, tbl_ptr, WF_TXGAIN_TBL_SIZE); + if (ret) { + AICWFDBG(LOGERROR, "tx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst); + break; + } + } + + rwnx_release_firmware_common(&dst); + + AICWFDBG(LOGINFO, "gaintbl download complete\n\n"); + return 0; +} +#endif + +#if DEF_PATCH_METHOD_VER_2 +int aicwf_plat_cinit_exec_8800d80n(struct rwnx_hw *rwnx_hw) +{ + int ret = 0; + uint32_t fw_addr, boot_type; + uint32_t mem_addr = 0x40500184; + uint32_t mem_val; + struct dbg_mem_read_cfm rd_mem_addr_cfm; + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm); + if (ret) { + AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret); + return ret; + } + mem_val = rd_mem_addr_cfm.memdata; + if (mem_val & CHIP_INFO_FLAG_CINIT_BEGIN) { + // wait done + while (!(mem_val & CHIP_INFO_FLAG_CINIT_DONE)) { + AICWFDBG(LOGINFO, "cinit rd chipinfo=%x\n", mem_val); + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm); + if (ret) { + AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret); + return ret; + } + mem_val = rd_mem_addr_cfm.memdata; + } + AICWFDBG(LOGINFO, "cinit executed, chipinfo=%x\n", mem_val); + return ret; + } + ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_CINIT_ADDR_8800D80N_U02, RWNX_MAC_FW_CINIT_NAME_8800D80N_U02); + if (ret) { + AICWFDBG(LOGERROR, "load cinit bin fail: %d\n", ret); + return ret; + } + /* fw start */ + fw_addr = ROM_FMAC_CINIT_ADDR_8800D80N_U02 + 0x0009; + boot_type = HOST_START_APP_FNCALL; + AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type); + ret = rwnx_send_dbg_start_app_req(rwnx_hw, fw_addr, boot_type); + if (ret) { + AICWFDBG(LOGERROR, "start app fail: %d\n", ret); + return ret; + } + return ret; +} + +int aicwf_plat_calib_exec_8800d80n(struct rwnx_hw *rwnx_hw) +{ + int ret = 0; + uint32_t fw_addr, boot_type; + uint32_t patch_var_flags_addr = ROM_FMAC_PATCH_ADDR_8800D80N_U02 + 0x08; + uint32_t patch_var_flags_val; + struct dbg_mem_read_cfm rd_mem_addr_cfm; + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, patch_var_flags_addr, &rd_mem_addr_cfm); + if (ret) { + AICWFDBG(LOGERROR, "%x rd fail: %d\n", patch_var_flags_addr, ret); + return ret; + } + patch_var_flags_val = rd_mem_addr_cfm.memdata; + if (patch_var_flags_val & (PATCH_VAR_FLAG_CALIB_BEGIN | PATCH_VAR_FLAG_CALIB_DONE)) { + AICWFDBG(LOGINFO, "calib executed, var_flags=%x\n", patch_var_flags_val); + return ret; + } + ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_CALIB_ADDR_8800D80N_U02, RWNX_MAC_FW_CALIB_NAME_8800D80N_U02); + if (ret) { + AICWFDBG(LOGERROR, "load calib bin fail: %d\n", ret); + return ret; + } + /* fw start */ + fw_addr = ROM_FMAC_CALIB_ADDR_8800D80N_U02 + 0x0009; + boot_type = HOST_START_APP_FNCALL; + AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type); + ret = rwnx_send_dbg_start_app_req(rwnx_hw, fw_addr, boot_type); + if (ret) { + AICWFDBG(LOGERROR, "start app fail: %d\n", ret); + return ret; + } + return ret; +} +#endif + +int aicwf_set_rf_config_8800d80n(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm) +{ + int ret = 0; + + if ((ret = rwnx_send_txpwr_lvl_v3_req(rwnx_hw))) { + return -1; + } + if ((ret = rwnx_send_txpwr_lvl_adj_req(rwnx_hw))) { + return -1; + } + if ((ret = rwnx_send_txpwr_ofst2x_req(rwnx_hw))) { + return -1; + } + #if DEF_PATCH_METHOD_VER_1 + if (testmode == FW_NORMAL_MODE) { + aicwf_plat_gain_table_load_8800d80n(rwnx_hw); + } + #endif + if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) { + return -1; + } + return 0 ; +} + + +int rwnx_plat_userconfig_load_8800d80n(struct rwnx_hw *rwnx_hw){ + int size; + u32 *dst=NULL; + char *filename = FW_USERCONFIG_NAME_8800D80N; + + AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); + + /* load file */ + size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); + if (size <= 0) { + AICWFDBG(LOGERROR, "wrong size of firmware file\n"); + dst = NULL; + return 0; + } + + /* Copy the file on the Embedded side */ + AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); + + rwnx_plat_userconfig_parsing((char *)dst, size); + + rwnx_release_firmware_common(&dst); + + AICWFDBG(LOGINFO, "userconfig download complete\n\n"); + return 0; + +} + +#ifdef CONFIG_POWER_LIMIT +extern char country_code[]; +int rwnx_plat_powerlimit_load_8800d80n(struct rwnx_hw *rwnx_hw) +{ + int size; + u32 *dst=NULL; + char *filename = FW_POWERLIMIT_NAME_8800D80N; + + AICWFDBG(LOGINFO, "powerlimit file path:%s \r\n", filename); + + /* load file */ + size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); + if (size <= 0) { + AICWFDBG(LOGERROR, "wrong size of cfg file\n"); + dst = NULL; + return 0; + } + + AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); + + /* parsing the file */ + rwnx_plat_powerlimit_parsing((char *)dst, size, country_code); + + rwnx_release_firmware_common(&dst); + + AICWFDBG(LOGINFO, "powerlimit download complete\n\n"); + return 0; +} +#endif + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80n.h b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80n.h new file mode 100644 index 0000000..036a995 --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80n.h @@ -0,0 +1,32 @@ +#include + +#define DEF_PATCH_METHOD_VER_1 0 // deprecated +#define DEF_PATCH_METHOD_VER_2 1 // in used + +void system_config_8800d80n(struct rwnx_hw *rwnx_hw); + +int aicwf_plat_patch_load_8800d80n(struct rwnx_hw *rwnx_hw); +int aicwf_plat_patch_table_load_8800d80n(struct rwnx_hw *rwnx_hw); + +void aicwf_patch_config_8800d80n(struct rwnx_hw *rwnx_hw); + +int aicwf_plat_rftest_load_8800d80n(struct rwnx_hw *rwnx_hw); +int aicwf_plat_rftest_exec_8800d80n(struct rwnx_hw *rwnx_hw); + +#if DEF_PATCH_METHOD_VER_1 +int aicwf_plat_initvar_load_8800d80n(struct rwnx_hw *rwnx_hw, u32 var_base_addr); +int aicwf_plat_gain_table_load_8800d80n(struct rwnx_hw *rwnx_hw); +#endif + +#if DEF_PATCH_METHOD_VER_2 +int aicwf_plat_cinit_exec_8800d80n(struct rwnx_hw *rwnx_hw); +int aicwf_plat_calib_exec_8800d80n(struct rwnx_hw *rwnx_hw); +#endif + +int rwnx_plat_userconfig_load_8800d80n(struct rwnx_hw *rwnx_hw); +#ifdef CONFIG_POWER_LIMIT +int rwnx_plat_powerlimit_load_8800d80n(struct rwnx_hw *rwnx_hw); +#endif +int aicwf_set_rf_config_8800d80n(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm); + + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80x2.c b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80x2.c index 2d6c5e0..ef62e86 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80x2.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80x2.c @@ -1,6 +1,7 @@ #include "rwnx_main.h" #include "rwnx_msg_tx.h" #include "reg_access.h" +#include "aicwf_compat_8800d80x2.h" #define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt" #define FW_POWERLIMIT_NAME_8800D80X2 "aic_powerlimit_8800d80x2.txt" @@ -86,7 +87,7 @@ int rwnx_plat_powerlimit_load_8800d80x2(struct rwnx_hw *rwnx_hw) AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); /* parsing the file */ - rwnx_plat_powerlimit_parsing((char *)dst, size, country_code); + rwnx_plat_powerlimit_parsing((char *)dst, size); rwnx_release_firmware_common(&dst); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c index 3a23045..69eb99a 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c @@ -45,8 +45,6 @@ #define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt" #define FW_POWERLIMIT_NAME_8800DC "aic_powerlimit_8800dc.txt" #define FW_POWERLIMIT_NAME_8800DW "aic_powerlimit_8800dw.txt" -#define FW_USERCONFIG_NAME_8800DW_W311 "aic_userconfig_8800dw_w311.txt" -#define FW_USERCONFIG_NAME_8800DW_U2 "aic_userconfig_8800dw_u2.txt" #ifdef CONFIG_LOAD_BT_PATCH_IN_FDRV enum aicbt_patch_table_type { @@ -169,6 +167,7 @@ u32 syscfg_tbl_masked_8800dc[][3] = { {0x700010A0, (0x1 << 11), (0x1 << 11)}, {0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, {0x70001038, (0x1 << 8), (0x1 << 8)}, + {0x70001084, (0x3 << 13), (0x0 << 13)}, {0x70001094, (0x3 << 2), (0x0 << 2)}, {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, {0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)), @@ -186,6 +185,7 @@ u32 syscfg_tbl_masked_8800dc[][3] = { {0x700010A0, (0x1 << 11), (0x1 << 11)}, {0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, {0x70001038, (0x1 << 8), (0x1 << 8)}, + {0x70001084, (0x3 << 13), (0x0 << 13)}, {0x70001094, (0x3 << 2), (0x0 << 2)}, {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, {0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)), @@ -211,6 +211,7 @@ u32 syscfg_tbl_masked_8800dc_h[][3] = { {0x700010A0, (0x1 << 11), (0x1 << 11)}, //{0x70001034, ((0x1 << 20) | (0x7 << 26)), ((0x0 << 20) | (0x2 << 26))}, {0x70001038, (0x1 << 8), (0x1 << 8)}, + {0x70001084, (0x3 << 13), (0x0 << 13)}, {0x70001094, (0x3 << 2), (0x0 << 2)}, {0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))}, #if defined(CONFIG_VRF_DCDC_MODE) @@ -242,7 +243,6 @@ u32 syscfg_tbl_8800dc[][2] = { u32 patch_tbl_wifisetting[][2] = { - {0x0004, 0x00020010}, //wdt_reboot_type, wdt_period_sec #if !defined(CONFIG_FPGA_VERIFICATION) {0x0090, 0x0013FC00}, //rx_ringbuf_start2 #endif @@ -251,10 +251,9 @@ u32 patch_tbl_wifisetting[][2] = {0x0120, 0x140A0100}, //usb agg tx params(total cnt, aggr cnt, out en, global out nak) #endif //CONFIG_USB_TX_AGGR {0x00b0, 0xAD180100}, -#ifdef CONFIG_BAND_STEERING +#ifdef CONFIG_PRBREQ_REPORT {0x0138, 0x00010a00}, //apm probe resp offload en #endif - {0x0084, 0x00000040}, }; u32 jump_tbl[][2] = @@ -1872,104 +1871,104 @@ const uint32_t txgain_map_femkct[96] = const uint32_t txgain_map_femkct_h[96] = { //11b - 0x00ffd872,//15 - 0x00ffd880,//16 - 0x00ffd972,//17 - 0x00ffd980,//18 - 0x00ffd990,//19 - 0x00ffda72,//20 - 0x00ffda80,//21 - 0x00ffdb72,//22 - 0x00ffdb80,//23 - 0x00ffdc72,//24 - 0x00ffdc80,//25 - 0x00ffdd72,//26 - 0x00ffdd80,//27 - 0x00ffde72,//28 - 0x00ffde80,//29 - 0x00ffdf72,//30 - 0x00ffd072,//-1 - 0x00ffd072,//0 - 0x00ffd080,//1 - 0x00ffd172,//2 - 0x00ffd180,//3 - 0x00ffd272,//4 - 0x00ffd280,//5 - 0x00ffd379,//6 - 0x00ffd46d,//7 - 0x00ffd479,//8 - 0x00ffd572,//9 - 0x00ffd580,//10 - 0x00ffd672,//11 - 0x00ffd680,//12 - 0x00ffd772,//13 - 0x00ffd780,//14 + 0x00ffd86c,//15 + 0x00ffd879,//16 + 0x00ffd96c,//17 + 0x00ffd979,//18 + 0x00ffd988,//19 + 0x00ffda6c,//20 + 0x00ffda79,//21 + 0x00ffdb6c,//22 + 0x00ffdb79,//23 + 0x00ffdc6c,//24 + 0x00ffdc79,//25 + 0x00ffdd6c,//26 + 0x00ffdd79,//27 + 0x00ffde6c,//28 + 0x00ffde79,//29 + 0x00ffdf6c,//30 + 0x00ffd06c,//-1 + 0x00ffd06c,//0 + 0x00ffd079,//1 + 0x00ffd16c,//2 + 0x00ffd179,//3 + 0x00ffd26c,//4 + 0x00ffd279,//5 + 0x00ffd372,//6 + 0x00ffd467,//7 + 0x00ffd472,//8 + 0x00ffd56c,//9 + 0x00ffd579,//10 + 0x00ffd66c,//11 + 0x00ffd679,//12 + 0x00ffd76c,//13 + 0x00ffd779,//14 //high - 0x00ffc880,//11 - 0x00ffc972,//12 - 0x00ffc980,//13 - 0x00ffca72,//14 - 0x00ffca80,//15 - 0x00ffcb72,//16 - 0x00ffcb80,//17 - 0x00ffcc72,//18 - 0x00ffcc80,//19 - 0x00ffcc90,//20 - 0x00ffcd72,//21 - 0x00ffcd80,//22 - 0x00ffce72,//23 - 0x00ffce80,//24 - 0x00ffcf72,//25 - 0x00ffcf80,//26 - 0x00ffc080,//-5 - 0x00ffc172,//-4 - 0x00ffc180,//-3 - 0x00ffc272,//-2 - 0x00ffc280,//-1 - 0x00ffc372,//0 - 0x00ffc380,//1 - 0x00ffc472,//2 - 0x00ffc480,//3 - 0x00ffc572,//4 - 0x00ffc580,//5 - 0x00ffc672,//6 - 0x00ffc680,//7 - 0x00ffc772,//8 - 0x00ffc780,//9 - 0x00ffc872,//10 + 0x00ffc879,//11 + 0x00ffc96c,//12 + 0x00ffc979,//13 + 0x00ffca6c,//14 + 0x00ffca79,//15 + 0x00ffcb6c,//16 + 0x00ffcb79,//17 + 0x00ffcc6c,//18 + 0x00ffcc79,//19 + 0x00ffcc88,//20 + 0x00ffcd6c,//21 + 0x00ffcd79,//22 + 0x00ffce6c,//23 + 0x00ffce79,//24 + 0x00ffcf6c,//25 + 0x00ffcf79,//26 + 0x00ffc079,//-5 + 0x00ffc16c,//-4 + 0x00ffc179,//-3 + 0x00ffc26c,//-2 + 0x00ffc279,//-1 + 0x00ffc36c,//0 + 0x00ffc379,//1 + 0x00ffc46c,//2 + 0x00ffc479,//3 + 0x00ffc56c,//4 + 0x00ffc579,//5 + 0x00ffc66c,//6 + 0x00ffc679,//7 + 0x00ffc76c,//8 + 0x00ffc779,//9 + 0x00ffc86c,//10 //low - 0x00ffc880,//11 - 0x00ffc972,//12 - 0x00ffc980,//13 - 0x00ffca72,//14 - 0x00ffca80,//15 - 0x00ffcb72,//16 - 0x00ffcb80,//17 - 0x00ffcc72,//18 - 0x00ffcc80,//19 - 0x00ffcc90,//20 - 0x00ffcd72,//21 - 0x00ffcd80,//22 - 0x00ffce72,//23 - 0x00ffce80,//24 - 0x00ffcf72,//25 - 0x00ffcf80,//26 - 0x00ffc080,//-5 - 0x00ffc172,//-4 - 0x00ffc180,//-3 - 0x00ffc272,//-2 - 0x00ffc280,//-1 - 0x00ffc372,//0 - 0x00ffc380,//1 - 0x00ffc472,//2 - 0x00ffc480,//3 - 0x00ffc572,//4 - 0x00ffc580,//5 - 0x00ffc672,//6 - 0x00ffc680,//7 - 0x00ffc772,//8 - 0x00ffc780,//9 - 0x00ffc872,//10 + 0x00ffc879,//11 + 0x00ffc96c,//12 + 0x00ffc979,//13 + 0x00ffca6c,//14 + 0x00ffca79,//15 + 0x00ffcb6c,//16 + 0x00ffcb79,//17 + 0x00ffcc6c,//18 + 0x00ffcc79,//19 + 0x00ffcc88,//20 + 0x00ffcd6c,//21 + 0x00ffcd79,//22 + 0x00ffce6c,//23 + 0x00ffce79,//24 + 0x00ffcf6c,//25 + 0x00ffcf79,//26 + 0x00ffc079,//-5 + 0x00ffc16c,//-4 + 0x00ffc179,//-3 + 0x00ffc26c,//-2 + 0x00ffc279,//-1 + 0x00ffc36c,//0 + 0x00ffc379,//1 + 0x00ffc46c,//2 + 0x00ffc479,//3 + 0x00ffc56c,//4 + 0x00ffc579,//5 + 0x00ffc66c,//6 + 0x00ffc679,//7 + 0x00ffc76c,//8 + 0x00ffc779,//9 + 0x00ffc86c,//10 }; #endif @@ -2205,6 +2204,141 @@ uint32_t wifi_txgain_table_24g_1_8800dcdw_femkct[32] = { }; #endif +#ifdef CONFIG_5M10M +u32 wifi_rxgain_table_24g_dcdw_5m[64] = { + 0x82f282d1,//index 0 + 0x9591a200, + 0x80808419, + 0x000000f0, + 0x42f282d1,//index 1 + 0x95923400, + 0x80808419, + 0x000000f0, + 0x22f282d1,//index 2 + 0x9592c600, + 0x80808419, + 0x000000f0, + 0x02f282d1,//index 3 + 0x9591a200, + 0x80808419, + 0x000000f0, + 0x06f282d1,//index 4 + 0x9591a200, + 0x80808419, + 0x000000f0, + 0x0ef282d1,//index 5 + 0x9591a200, + 0x80808419, + 0x000000f0, + 0x0ef282d3,//index 6 + 0x95923400, + 0x80808419, + 0x000000f0, + 0x0ef282d7,//index 7 + 0x9595a200, + 0x80808419, + 0x000000f0, + 0x02f282d2,//index 8 + 0x95951000, + 0x80808419, + 0x000000f0, + 0x02f282f4,//index 9 + 0x95951000, + 0x80808419, + 0x000000f0, + 0x02f282e6,//index 10 + 0x9595a200, + 0x80808419, + 0x000000f0, + 0x02f282e6,//index 11 + 0x9599a200, + 0x80808419, + 0x000000f0, + 0x02f282e6,//index 12 + 0x959da200, + 0x80808419, + 0x000000f0, + 0x02f282e6,//index 13 + 0x959f5800, + 0x80808419, + 0x000000f0, + 0x06f282e6,//index 14 + 0x959f5800, + 0x80808419, + 0x000000f0, + 0x0ef282e6,//index 15 + 0x959f5800, + 0x80808419, + 0x000000f0 +}; + +u32 wifi_rxgain_table_24g_dcdw_10m[64] = { + 0x82f282d1,//index 0 + 0x9591a320, + 0x80808419, + 0x000000f0, + 0x42f282d1,//index 1 + 0x95923520, + 0x80808419, + 0x000000f0, + 0x22f282d1,//index 2 + 0x9592c720, + 0x80808419, + 0x000000f0, + 0x02f282d1,//index 3 + 0x9591a320, + 0x80808419, + 0x000000f0, + 0x06f282d1,//index 4 + 0x9591a320, + 0x80808419, + 0x000000f0, + 0x0ef282d1,//index 5 + 0x9591a320, + 0x80808419, + 0x000000f0, + 0x0ef282d3,//index 6 + 0x95923520, + 0x80808419, + 0x000000f0, + 0x0ef282d7,//index 7 + 0x9595a320, + 0x80808419, + 0x000000f0, + 0x02f282d2,//index 8 + 0x95951120, + 0x80808419, + 0x000000f0, + 0x02f282f4,//index 9 + 0x95951120, + 0x80808419, + 0x000000f0, + 0x02f282e6,//index 10 + 0x9595a320, + 0x80808419, + 0x000000f0, + 0x02f282e6,//index 11 + 0x9599a320, + 0x80808419, + 0x000000f0, + 0x02f282e6,//index 12 + 0x959da320, + 0x80808419, + 0x000000f0, + 0x02f282e6,//index 13 + 0x959f5920, + 0x80808419, + 0x000000f0, + 0x06f282e6,//index 14 + 0x959f5920, + 0x80808419, + 0x000000f0, + 0x0ef282e6,//index 15 + 0x959f5920, + 0x80808419, + 0x000000f0 +}; +#endif u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = { 0x82f282d1,//index 0 0x9591a324, @@ -2923,7 +3057,13 @@ int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_c if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32, 0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256))) return -1; +#ifdef CONFIG_5M10M + if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 0, (u8_l *)wifi_rxgain_table_24g_dcdw_5m, 256))) + return -1; + if ((ret = rwnx_send_rf_config_req(rwnx_hw, 48, 0, (u8_l *)wifi_rxgain_table_24g_dcdw_10m, 256))) + return -1; +#endif if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) { return -1; } @@ -3038,81 +3178,61 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out) uint32_t misc_ram_addr; uint32_t ram_base_addr, ram_word_cnt; uint32_t bit_mask[4]; - uint32_t dpd_info_read_addr = 0xfe004; - uint32_t boot_argc_read_addr = 0x1220f0; - uint32_t flash_size_mem_addr = 0x40038030; - uint8_t flash_size = 0; int i; if (valid_out) { *valid_out = 0; } - - ret = rwnx_send_dbg_mem_read_req(rwnx_hw, boot_argc_read_addr, &cfm); - if (ret) { - AICWFDBG(LOGERROR, "boot argc [0x%x] rd fail: %d\n", boot_argc_read_addr, ret); - return ret; + if (testmode == FW_RFTEST_MODE) { + uint32_t vect1 = 0; + uint32_t vect2 = 0; + cfg_base = RAM_LMAC_FW_ADDR + 0x0004; + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm); + if (ret) { + AICWFDBG(LOGERROR, "cfg_base:%x vcet1 rd fail: %d\n", cfg_base, ret); + return ret; + } + vect1 = cfm.memdata; + if ((vect1 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) { + AICWFDBG(LOGERROR, "vect1 invalid: %x\n", vect1); + return ret; + } + cfg_base = RAM_LMAC_FW_ADDR + 0x0008; + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm); + if (ret) { + AICWFDBG(LOGERROR, "cfg_base:%x vcet2 rd fail: %d\n", cfg_base, ret); + return ret; + } + vect2 = cfm.memdata; + if ((vect2 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) { + AICWFDBG(LOGERROR, "vect2 invalid: %x\n", vect2); + return ret; + } + cfg_base = RAM_LMAC_FW_ADDR + 0x0164; } - printk("boot argc %x\n", cfm.memdata); - if (cfm.memdata & 0x10) { - *valid_out = 1; + // init misc ram + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm); + if (ret) { + AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); return ret; } - if (chip_mcu_id) { - ret = rwnx_send_dbg_mem_read_req(rwnx_hw, flash_size_mem_addr, &cfm); + misc_ram_addr = cfm.memdata; + AICWFDBG(LOGERROR, "misc_ram_addr=%x\n", misc_ram_addr); + // bit_mask + ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask); + ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4; + for (i = 0; i < ram_word_cnt; i++) { + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm); if (ret) { - AICWFDBG(LOGERROR, "flash size[0x%x] rd fail: %d\n", flash_size_mem_addr, ret); + AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); return ret; } - flash_size = cfm.memdata & 0xff; - printk("flash size %x\n", flash_size); - if (flash_size == 0x16) { - dpd_info_read_addr += 0x4300000; - } else if (flash_size == 0x15) { - dpd_info_read_addr += 0x4100000; - } else if (flash_size == 0x18) { - dpd_info_read_addr += 0x4700000; - } else { - dpd_info_read_addr += 0x4100000; - } - ret = rwnx_send_dbg_mem_read_req(rwnx_hw, dpd_info_read_addr, &cfm); - if (ret) { - AICWFDBG(LOGERROR, "dpd info [0x%x] rd fail: %d\n", dpd_info_read_addr, ret); - return ret; - } - if (cfm.memdata & (1<<7)) { - if (valid_out) { - *valid_out = 1; - } - } - } else { - if (testmode == FW_RFTEST_MODE) { - cfg_base = RAM_LMAC_FW_ADDR + 0x0164; - } - // init misc ram - ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm); - if (ret) { - AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); - return ret; - } - misc_ram_addr = cfm.memdata; - AICWFDBG(LOGERROR, "misc_ram_addr=%x\n", misc_ram_addr); - // bit_mask - ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask); - ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4; - for (i = 0; i < ram_word_cnt; i++) { - ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm); - if (ret) { - AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); - return ret; - } - bit_mask[i] = cfm.memdata; - } - AICWFDBG(LOGTRACE, "bit_mask:%x,%x,%x,%x\n",bit_mask[0],bit_mask[1],bit_mask[2],bit_mask[3]); - if ((bit_mask[0] == 0) && ((bit_mask[1] & 0xFFF00000) == 0x80000000) && - (bit_mask[2] == 0) && ((bit_mask[3] & 0xFFFFFF00) == 0x00000000)) { - if (valid_out) { - *valid_out = 1; - } + bit_mask[i] = cfm.memdata; + } + AICWFDBG(LOGTRACE, "bit_mask:%x,%x,%x,%x\n",bit_mask[0],bit_mask[1],bit_mask[2],bit_mask[3]); + if ((bit_mask[0] == 0) && ((bit_mask[1] & 0xFFF00000) == 0x80000000) && + (bit_mask[2] == 0) && ((bit_mask[3] & 0xFFFFFF00) == 0x00000000)) { + if (valid_out) { + *valid_out = 1; } } return ret; @@ -3511,17 +3631,6 @@ 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 - || 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_CUS4) { - filename = FW_USERCONFIG_NAME_8800DW_U2; - } AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); @@ -3575,7 +3684,7 @@ int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id /* Copy the file on the Embedded side */ AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); - rwnx_plat_powerlimit_parsing((char *)dst, size, country_code); + rwnx_plat_powerlimit_parsing((char *)dst, size); rwnx_release_firmware_common(&dst); @@ -3630,7 +3739,6 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){ array3_tbl_t p_syscfg_msk_tbl; int ret, cnt; const u32 mem_addr = 0x40500000; - const u32 cache_mem_addr = 0x40100020; struct dbg_mem_read_cfm rd_mem_addr_cfm; ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm); @@ -3644,21 +3752,6 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){ chip_mcu_id = 1; } - if (chip_mcu_id) { - ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cache_mem_addr, &rd_mem_addr_cfm); - if (ret) { - AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret); - return; - } - rd_mem_addr_cfm.memdata |= 0x01; - ret = rwnx_send_dbg_mem_write_req(rwnx_hw, cache_mem_addr, rd_mem_addr_cfm.memdata); - - if (ret) { - AICWFDBG(LOGERROR, "%x write fail: %d\n", cache_mem_addr, ret); - return; - } - } - ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm); if (ret) { AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h index c0e53cb..69bd2d7 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h @@ -60,3 +60,6 @@ int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw); int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id); #endif void system_config_8800dc(struct rwnx_hw *rwnx_hw); +int aicwf_patch_var_config_8800dc(struct rwnx_hw *rwnx_hw); +int set_bbpll_config(struct rwnx_hw *rwnx_hw); + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dln.c b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dln.c new file mode 100644 index 0000000..d44d362 --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dln.c @@ -0,0 +1,330 @@ +#include "rwnx_main.h" +#include "rwnx_msg_tx.h" +#include "reg_access.h" +#include "rwnx_platform.h" +#include "aicwf_compat_8800dln.h" + +#define FW_USERCONFIG_NAME_8800DLN "aic_userconfig_8800dln.txt" +#define FW_POWERLIMIT_NAME_8800DLN "aic_powerlimit_8800dln.txt" +#define RWNX_MAC_FW_RF_BASE_NAME_8800DLN "lmacfw_rf_8800dln.bin" +#define RWNX_MAC_FW_INITVAR_NAME_8800DLN "fmacfw_initvar_8800dln.bin" +#define RWNX_MAC_FW_GAINTBL_NAME_8800DLN "fmacfw_gaintbl_8800dln.bin" + +#define WF_RXGAIN_TBL_IDX_MAX 20 +#define WF_RXGAIN_TBL_SIZE 256 +#define WF_TXGAIN_TBL_IDX_MAX 21 +#define WF_TXGAIN_TBL_SIZE 128 + +extern char aic_fw_path[200]; + +int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr, + char *filename); +int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw, + u32** buffer, const char *filename); +void rwnx_plat_userconfig_parsing(char *buffer, int size); +void rwnx_release_firmware_common(u32** buffer); + +extern int get_adap_test(void); + +typedef u32 (*array2_tbl_t)[2]; +typedef u32 (*array3_tbl_t)[3]; + + +u32 syscfg_tbl_masked_8800dln[][3] = { + // {Address, mask, value} + {0x00000000, 0x00000000, 0x00000000}, // last one +}; + +u32 patch_tbl_wifisetting_8800dln[][2] = +{ +}; + +//adap test +u32 adaptivity_patch_tbl_8800dln[][2] = { +}; + +u32 patch_tbl_rf_func_8800dln[][2] = +{ +}; + +extern int testmode; +extern u8 chip_id; +extern u8 chip_mcu_id; + +void system_config_8800dln(struct rwnx_hw *rwnx_hw) +{ + int syscfg_num; + array3_tbl_t p_syscfg_msk_tbl; + int ret, cnt; + const u32 mem_addr = 0x40500000; + struct dbg_mem_read_cfm rd_mem_addr_cfm; + + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm); + if (ret) { + AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret); + return; + } + chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16); + //printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata); + if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL) { + chip_mcu_id = 1; + } + + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm); + if (ret) { + AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret); + return; + } + chip_sub_id = (u8)(rd_mem_addr_cfm.memdata); + //printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata); + AICWFDBG(LOGINFO, "chip_id=%x, chip_sub_id=%x\n", chip_id, chip_sub_id); + + syscfg_num = sizeof(syscfg_tbl_masked_8800dln) / sizeof(u32) / 3; + p_syscfg_msk_tbl = syscfg_tbl_masked_8800dln; + + for (cnt = 0; cnt < syscfg_num; cnt++) { + if (p_syscfg_msk_tbl[cnt][0] == 0x00000000) { + break; + } + + ret = rwnx_send_dbg_mem_mask_write_req(rwnx_hw, + p_syscfg_msk_tbl[cnt][0], p_syscfg_msk_tbl[cnt][1], p_syscfg_msk_tbl[cnt][2]); + if (ret) { + AICWFDBG(LOGERROR, "%x mask write fail: %d\n", p_syscfg_msk_tbl[cnt][0], ret); + return; + } + } +} + +void aicwf_patch_config_8800dln(struct rwnx_hw *rwnx_hw) +{ + #ifdef CONFIG_ROM_PATCH_EN + int ret = 0; + int cnt = 0; + +//adap test + int adap_test = 0; + int adap_patch_num = 0; + + adap_test = get_adap_test(); +//adap test + + if (testmode == 0) { + const u32 cfg_base = 0x8150; + struct dbg_mem_read_cfm cfm; + u32 wifisetting_cfg_addr; + u32 agc_cfg_addr; + u32 txgain_cfg_24g_addr; + u32 jump_tbl_addr = 0; + + u32 patch_tbl_num; + + //array2_tbl_t jump_tbl_base = NULL; + array2_tbl_t patch_tbl_base = NULL; + + if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm))) { + AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", cfg_base, ret); + } + wifisetting_cfg_addr = cfm.memdata; + + if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 4, &cfm))) { + AICWFDBG(LOGERROR, "jump_tbl base[0x%x] rd fail: %d\n", cfg_base + 4, ret); + } + jump_tbl_addr = cfm.memdata; + + if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x10, &cfm))) { + AICWFDBG(LOGERROR, "agc_cfg base[0x%x] rd fail: %d\n", cfg_base + 0xc, ret); + } + agc_cfg_addr = cfm.memdata; + + if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) { + AICWFDBG(LOGERROR, "txgain_cfg_24g base[0x%x] rd fail: %d\n", cfg_base + 0x10, ret); + } + txgain_cfg_24g_addr = cfm.memdata; + + AICWFDBG(LOGINFO, "wifisetting_cfg_addr=%x, jump_tbl_addr=%x, agc_cfg_addr=%x, txgain_cfg_24g_addr=%x\n", + wifisetting_cfg_addr, jump_tbl_addr, agc_cfg_addr, txgain_cfg_24g_addr); + + patch_tbl_num = sizeof(patch_tbl_wifisetting_8800dln)/sizeof(u32)/2; + patch_tbl_base = patch_tbl_wifisetting_8800dln; + for (cnt = 0; cnt < patch_tbl_num; cnt++) { + if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + patch_tbl_base[cnt][0], patch_tbl_base[cnt][1]))) { + AICWFDBG(LOGERROR, "wifisetting %x write fail\n", patch_tbl_base[cnt][0]); + } + } + + //adap test + if (adap_test) { + adap_patch_num = sizeof(adaptivity_patch_tbl_8800dln)/sizeof(u32)/2; + patch_tbl_base = adaptivity_patch_tbl_8800dln; + for(cnt = 0; cnt < adap_patch_num; cnt++) + { + if((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, wifisetting_cfg_addr + patch_tbl_base[cnt][0], patch_tbl_base[cnt][1]))) { + AICWFDBG(LOGERROR, "%x write fail\n", wifisetting_cfg_addr + patch_tbl_base[cnt][0]); + } + } + } + //adap test + + ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, txgain_cfg_24g_addr, RWNX_MAC_FW_INITVAR_NAME_8800DLN); + if (ret) { + AICWFDBG(LOGINFO, "load initvar bin fail: %d\n", ret); + return; + } + } + else { + u32 patch_tbl_rf_func_num = sizeof(patch_tbl_rf_func_8800dln)/sizeof(u32)/2; + for (cnt = 0; cnt < patch_tbl_rf_func_num; cnt++) { + if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_rf_func_8800dln[cnt][0], patch_tbl_rf_func_8800dln[cnt][1]))) { + AICWFDBG(LOGERROR, "patch_tbl_rf_func %x write fail\n", patch_tbl_rf_func_8800dln[cnt][0]); + } + } + } + #endif +} + +int aicwf_plat_rftest_load_8800dln(struct rwnx_hw *rwnx_hw) +{ + int ret = 0; + ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, RAM_LMAC_FW_ADDR, RWNX_MAC_FW_RF_BASE_NAME_8800DLN); + if (ret) { + AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret); + return ret; + } + return ret; +} + +int aicwf_plat_gain_table_load_8800dln(struct rwnx_hw *rwnx_hw) +{ + int size, desired_size, idx, ret; + u32 *dst=NULL; + u8_l *tbl_base; + char *filename = RWNX_MAC_FW_GAINTBL_NAME_8800DLN; + + AICWFDBG(LOGINFO, "gaintbl file path:%s\n", filename); + + /* load file */ + size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); + desired_size = WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE + WF_TXGAIN_TBL_IDX_MAX * WF_TXGAIN_TBL_SIZE; + if ((size <= 0) || (size != desired_size)) { + AICWFDBG(LOGERROR, "wrong size of firmware file, desired=%d, size=%d\n", desired_size, size); + if (dst) { + rwnx_release_firmware_common(&dst); + dst = NULL; + } + return 0; + } + + /* Copy the file on the Embedded side */ + AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); + + /* RX gain */ + tbl_base = (u8_l *)dst; + for (idx = 0; idx < WF_RXGAIN_TBL_IDX_MAX; idx++) { + u16_l ofst = idx * 16; + u8_l *tbl_ptr = tbl_base + idx * WF_RXGAIN_TBL_SIZE; + ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 0, tbl_ptr, WF_RXGAIN_TBL_SIZE); + if (ret) { + AICWFDBG(LOGERROR, "rx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst); + break; + } + } + + /* TX gain */ + tbl_base = (u8_l *)dst + WF_RXGAIN_TBL_IDX_MAX * WF_RXGAIN_TBL_SIZE; + for (idx = 0; idx < WF_TXGAIN_TBL_IDX_MAX; idx++) { + u16_l ofst = idx * 16; + u8_l *tbl_ptr = tbl_base + idx * WF_TXGAIN_TBL_SIZE; + ret = rwnx_send_rf_config_v2_req(rwnx_hw, ofst, 2, tbl_ptr, WF_TXGAIN_TBL_SIZE); + if (ret) { + AICWFDBG(LOGERROR, "tx gain rf_config_req fail, ret=%d, ofst=%d\n", ret, ofst); + break; + } + } + + rwnx_release_firmware_common(&dst); + + AICWFDBG(LOGINFO, "gaintbl download complete\n\n"); + return 0; +} + +int aicwf_set_rf_config_8800dln(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm) +{ + int ret = 0; + + if ((ret = rwnx_send_txpwr_lvl_req(rwnx_hw))) { + return -1; + } + if ((ret = rwnx_send_txpwr_lvl_adj_v2_req(rwnx_hw))) { + return -1; + } + if ((ret = rwnx_send_txpwr_ofst2x_v3_req(rwnx_hw))) { + return -1; + } + if (testmode == FW_NORMAL_MODE) { + aicwf_plat_gain_table_load_8800dln(rwnx_hw); + } + if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) { + return -1; + } + return 0 ; +} + + +int rwnx_plat_userconfig_load_8800dln(struct rwnx_hw *rwnx_hw){ + int size; + u32 *dst=NULL; + char *filename = FW_USERCONFIG_NAME_8800DLN; + + AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); + + /* load file */ + size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); + if (size <= 0) { + AICWFDBG(LOGERROR, "wrong size of firmware file\n"); + dst = NULL; + return 0; + } + + /* Copy the file on the Embedded side */ + AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); + + rwnx_plat_userconfig_parsing((char *)dst, size); + + rwnx_release_firmware_common(&dst); + + AICWFDBG(LOGINFO, "userconfig download complete\n\n"); + return 0; + +} + +#ifdef CONFIG_POWER_LIMIT +extern char country_code[]; +int rwnx_plat_powerlimit_load_8800dln(struct rwnx_hw *rwnx_hw) +{ + int size; + u32 *dst=NULL; + char *filename = FW_POWERLIMIT_NAME_8800DLN; + + AICWFDBG(LOGINFO, "powerlimit file path:%s \r\n", filename); + + /* load file */ + size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); + if (size <= 0) { + AICWFDBG(LOGERROR, "wrong size of cfg file\n"); + dst = NULL; + return 0; + } + + AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); + + /* parsing the file */ + rwnx_plat_powerlimit_parsing((char *)dst, size); + + rwnx_release_firmware_common(&dst); + + AICWFDBG(LOGINFO, "powerlimit download complete\n\n"); + return 0; +} +#endif + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dln.h b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dln.h new file mode 100644 index 0000000..8536268 --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dln.h @@ -0,0 +1,17 @@ +#include + +void system_config_8800dln(struct rwnx_hw *rwnx_hw); + +void aicwf_patch_config_8800dln(struct rwnx_hw *rwnx_hw); + +int aicwf_plat_rftest_load_8800dln(struct rwnx_hw *rwnx_hw); + +int aicwf_plat_gain_table_load_8800dln(struct rwnx_hw *rwnx_hw); + +int rwnx_plat_userconfig_load_8800dln(struct rwnx_hw *rwnx_hw); +#ifdef CONFIG_POWER_LIMIT +int rwnx_plat_powerlimit_load_8800dln(struct rwnx_hw *rwnx_hw); +#endif +int aicwf_set_rf_config_8800dln(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm); + + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_debug.h b/drivers/aic8800/aic8800_fdrv/aicwf_debug.h index bec2500..9bd1e7d 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_debug.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_debug.h @@ -1,5 +1,3 @@ - - #define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__ @@ -11,6 +9,7 @@ #define LOGDEBUG 0x0008 #define LOGDATA 0x0010 #define LOGSTEER 0x0020 +#define LOGFW 0x0200 extern int aicwf_dbg_level; void rwnx_data_dump(char* tag, void* data, unsigned long len); @@ -48,6 +47,3 @@ do { \ } \ } while (0) #endif - - - diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_manager.c b/drivers/aic8800/aic8800_fdrv/aicwf_manager.c index 289e108..f966e71 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_manager.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_manager.c @@ -49,7 +49,7 @@ static int freq_to_channel(int freq) } else if (freq >= FREQ_6G_MIN && freq <= FREQ_6G_MAX) { return (freq - 5950) / 5; } else { - AICWFDBG(LOGERROR, MANAGER_STR"aic Unsupported frequency: %d MHz\n", freq); + AICWFDBG(LOGERROR, MANAGER_STR"Unsupported frequency: %d MHz\n", freq); return -1; } } @@ -91,7 +91,7 @@ void aicwf_nl_recv_msg(struct sk_buff *skb) rwnx_hook = nl_hook[band][ssid]; if (!rwnx_hook) { - AICWFDBG(LOGSTEER, MANAGER_STR"%s, !rwnx_hook, %d,%d\n", __func__, band, ssid); + AICWFDBG(LOGSTEER, MANAGER_STR"%s, search for the next rwnx_hook, %d,%d\n", __func__, band, ssid); continue; } if (rwnx_vif == NULL || rwnx_vif->up == false) { @@ -144,7 +144,7 @@ void aicwf_nl_recv_msg(struct sk_buff *skb) rwnx_hook = nl_hook[band][ssid]; if (!rwnx_hook) { - AICWFDBG(LOGSTEER, MANAGER_STR"rwnx_hook is null p1.\n"); + //AICWFDBG(LOGSTEER, MANAGER_STR"Not this driver's msg p1.\n"); break; } if (rwnx_vif == NULL || rwnx_vif->up == false) { @@ -185,7 +185,7 @@ void aicwf_nl_recv_msg(struct sk_buff *skb) rwnx_hook = nl_hook[band][ssid]; if (!rwnx_hook) { - AICWFDBG(LOGERROR, MANAGER_STR"rwnx_hook is null p2.\n"); + //AICWFDBG(LOGERROR, MANAGER_STR"Not this driver's msg p2.\n"); break; } if (rwnx_vif == NULL || rwnx_vif->up == false) { diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c b/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c index 100ad6f..610468d 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c @@ -527,11 +527,7 @@ static void aicwf_sdio_bus_stop(struct device *dev) aicwf_sdio_pwrctl_timer(sdiodev, 0); if(timer_pending(&sdiodev->rwnx_hw->p2p_alive_timer)){ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - ret = timer_delete(&sdiodev->rwnx_hw->p2p_alive_timer);} -#else ret = del_timer(&sdiodev->rwnx_hw->p2p_alive_timer);} -#endif sdio_dbg("%s\n",__func__); if (sdiodev->pwrctl_tsk) { complete(&sdiodev->pwrctrl_trgg); @@ -1001,7 +997,8 @@ 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 @@ -1085,11 +1082,7 @@ void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration) spin_lock_bh(&sdiodev->pwrctl_lock); if (!duration) { if (timer_pending(&sdiodev->timer)) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - timer_delete_sync(&sdiodev->timer); -#else del_timer_sync(&sdiodev->timer); -#endif } else { sdiodev->active_duration = duration; timeout = msecs_to_jiffies(sdiodev->active_duration); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.h b/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.h index 542023f..5e5e53f 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.h @@ -8,6 +8,7 @@ #include #include #include +#include #define TCP_ACK_NUM 32 @@ -89,4 +90,29 @@ int filter_send_tcp_ack(struct rwnx_hw *priv, struct msg_buf *msgbuf,unsigned ch void filter_rx_tcp_ack(struct rwnx_hw *priv,unsigned char *buf, unsigned plen); void move_tcpack_msg(struct rwnx_hw *priv, struct msg_buf * msg); +void intf_tcp_drop_msg(struct rwnx_hw *priv, struct msg_buf *msg); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) +void tcp_ack_timeout(unsigned long data); +#else +void tcp_ack_timeout(struct timer_list *t); +#endif +int tcp_check_quick_ack(unsigned char *buf, struct tcp_ack_msg *msg); +int tcp_check_ack(unsigned char *buf, + struct tcp_ack_msg *msg, + unsigned short *win_scale); +int tcp_ack_match(struct tcp_ack_manage *ack_m, struct tcp_ack_msg *ack_msg); +void tcp_ack_update(struct tcp_ack_manage *ack_m); +int tcp_ack_alloc_index(struct tcp_ack_manage *ack_m); +int tcp_ack_handle(struct msg_buf *new_msgbuf, + struct tcp_ack_manage *ack_m, + struct tcp_ack_info *ack_info, + struct tcp_ack_msg *ack_msg, + int type); +int tcp_ack_handle_new(struct msg_buf *new_msgbuf, + struct tcp_ack_manage *ack_m, + struct tcp_ack_info *ack_info, + struct tcp_ack_msg *ack_msg, + int type); + + #endif diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.h b/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.h index 71c306b..920a53f 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.h @@ -23,7 +23,7 @@ #define DATA_BUF_MAX 2048 #define TXPKT_BLOCKSIZE 512 #define MAX_AGGR_TXPKT_LEN (1536*64) -#define CMD_TX_TIMEOUT 2000 +#define CMD_TX_TIMEOUT 5000 #define TX_ALIGNMENT 4 #ifdef CONFIG_USB_TX_AGGR @@ -155,7 +155,7 @@ struct aicwf_tx_priv { #define DEFRAG_MAX_WAIT 40 //100 #ifdef AICWF_RX_REORDER #define MAX_REORD_RXFRAME 250 -#define REORDER_UPDATE_TIME 500//50 +#define REORDER_UPDATE_TIME 50 #define AICWF_REORDER_WINSIZE 64 //SN_LESS(a, b) a-b<0 is ture #define SN_LESS(a, b) (((a-b)&0x800)!=0) @@ -307,6 +307,7 @@ void aicwf_rxframe_queue_init_2(struct rx_frame_queue *pq, int max_len); void rxbuff_free(struct rx_buff *rxbuff); struct rx_buff *rxbuff_dequeue(struct rx_frame_queue *pq); bool aicwf_rxbuff_enqueue(struct device *dev, struct rx_frame_queue *rxq, struct rx_buff *pkt); +struct rx_buff *rxbuff_queue_penq(struct rx_frame_queue *pq, struct rx_buff *p); extern struct aicwf_rx_buff_list aic_rx_buff_list; #endif diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_usb.c b/drivers/aic8800/aic8800_fdrv/aicwf_usb.c index 9adcb61..97a39e0 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_usb.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_usb.c @@ -155,22 +155,24 @@ static void aicwf_usb_msg_rx_buf_put(struct aic_usb_dev *usb_dev, struct aicwf_u } #endif -void rwnx_stop_sta_all_queues(struct rwnx_sta *sta, struct rwnx_hw *rwnx_hw) +void rwnx_stop_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw) { u8 tid; struct rwnx_txq *txq; + struct rwnx_sta *sta_tmp = (struct rwnx_sta *)sta; for(tid=0; tid<8; tid++) { - txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); + txq = rwnx_txq_sta_get(sta_tmp, tid, rwnx_hw); netif_stop_subqueue(txq->ndev, txq->ndev_idx); } } -void rwnx_wake_sta_all_queues(struct rwnx_sta *sta, struct rwnx_hw *rwnx_hw) +void rwnx_wake_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw) { u8 tid; struct rwnx_txq *txq; + struct rwnx_sta *sta_tmp = (struct rwnx_sta *)sta; for(tid=0; tid<8; tid++) { - txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); + txq = rwnx_txq_sta_get(sta_tmp, tid, rwnx_hw); netif_wake_subqueue(txq->ndev, txq->ndev_idx); } } @@ -200,7 +202,7 @@ static void usb_txc_sta_flowctrl(struct aicwf_usb_buf *usb_buf, struct aic_usb_d usb_dev->rwnx_hw->sta_flowctrl[sta_idx].flowctrl) { //AICWFDBG(LOGDEBUG, "sta 0x%x:0x%x, %d pending %d, wake\n", sta->mac_addr[4], sta->mac_addr[5], sta->sta_idx, atomic_read(&usb_dev->rwnx_hw->sta_flowctrl[sta_idx].tx_pending_cnt)); if(!usb_dev->tbusy) - rwnx_wake_sta_all_queues(sta, usb_dev->rwnx_hw); + rwnx_wake_sta_all_queues((void *)sta, usb_dev->rwnx_hw); usb_dev->rwnx_hw->sta_flowctrl[sta_idx].flowctrl = 0; } } @@ -781,7 +783,7 @@ static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev, aicwf_prealloc_rxbuff_free(rx_buff, &usb_dev->rx_priv->rxbuff_lock); aicwf_usb_rx_buf_put(usb_dev, usb_buf); - msleep(100); + mdelay(100); return -1; }else{ atomic_inc(&rx_urb_cnt); @@ -840,7 +842,7 @@ static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev, usb_buf->skb = NULL; aicwf_usb_rx_buf_put(usb_dev, usb_buf); - msleep(100); + mdelay(100); return -1; }else{ atomic_inc(&rx_urb_cnt); @@ -913,7 +915,7 @@ static int aicwf_usb_submit_msg_rx_urb(struct aic_usb_dev *usb_dev, usb_buf->skb = NULL; aicwf_usb_msg_rx_buf_put(usb_dev, usb_buf); - msleep(100); + mdelay(100); } return 0; } @@ -1214,9 +1216,6 @@ 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 } } @@ -1677,7 +1676,7 @@ static void usb_tx_flow_ctrl(struct rwnx_txhdr *txhdr, struct aic_usb_dev *usb_d rwnx_hw->sta_flowctrl[sta_idx].flowctrl) { //AICWFDBG(LOGDEBUG, "sta 0x%x:0x%x, %d pending %d, stop\n", sta->mac_addr[4], sta->mac_addr[5], sta->sta_idx, atomic_read(&rwnx_hw->sta_flowctrl[sta_idx].tx_pending_cnt)); if(!usb_dev->tbusy) - rwnx_stop_sta_all_queues(sta, usb_dev->rwnx_hw); + rwnx_stop_sta_all_queues((void *)sta, usb_dev->rwnx_hw); rwnx_hw->sta_flowctrl[sta_idx].flowctrl = 1; } } @@ -1903,15 +1902,14 @@ static int aicwf_usb_bus_start(struct device *dev) aicwf_usb_state_change(usb_dev, USB_UP_ST); usb_dev->rx_prepare_ready = false; + aicwf_usb_rx_prepare(usb_dev); aicwf_usb_tx_prepare(usb_dev); #ifdef CONFIG_USB_MSG_IN_EP if(usb_dev->msg_in_pipe){ aicwf_usb_msg_rx_prepare(usb_dev); - } else { - aicwf_usb_rx_prepare(usb_dev); } #endif - if(!usb_dev->msg_in_pipe && !usb_dev->rx_prepare_ready){ + if(!usb_dev->rx_prepare_ready){ AICWFDBG(LOGERROR, "%s rx prepare fail\r\n", __func__); return -1; }else{ @@ -2154,12 +2152,13 @@ static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *in AICWFDBG(LOGERROR, "AIC8800DC change to AIC8800DW\n"); usb_dev->chipid = PRODUCT_ID_AIC8800DW; }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 || - usb_dev->chipid == PRODUCT_ID_AIC8800D81){ + AICWFDBG(LOGINFO, "AIC8800DW\n"); + } else if (usb_dev->chipid == PRODUCT_ID_AIC8800D80N) { + AICWFDBG(LOGERROR, "AIC8800D80N change to AIC8800D80WN\n"); + } else if (usb_dev->chipid == PRODUCT_ID_AIC8800DLN) { + AICWFDBG(LOGERROR, "AIC8800DLN change to AIC8800DWN\n"); + }else if(usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 || + usb_dev->chipid == PRODUCT_ID_AIC8800D89X2){ //TODO }else{ ret = -ENODEV; @@ -2393,7 +2392,23 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid } AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__); return 0; - }else{ + } else if ((pid == USB_PRODUCT_ID_AIC8800D80N) || + (pid == USB_PRODUCT_ID_AIC8800D80LN) || + (pid == USB_PRODUCT_ID_AIC8800D80WN) || + (pid == USB_PRODUCT_ID_AIC8800D40N) || + (pid == USB_PRODUCT_ID_AIC8800D40LN) || + (pid == USB_PRODUCT_ID_AIC8800D40WN)) { + usb_dev->chipid = PRODUCT_ID_AIC8800D80N; + aicwf_usb_rx_aggr = true; + AICWFDBG(LOGINFO, "%s USE AIC8800D80N\r\n", __func__); + return 0; + } else if ((pid == USB_PRODUCT_ID_AIC8800DLN) || + (pid == USB_PRODUCT_ID_AIC8800DWN)) { + usb_dev->chipid = PRODUCT_ID_AIC8800DLN; + aicwf_usb_rx_aggr = true; + AICWFDBG(LOGINFO, "%s USE AIC8800DLN\r\n", __func__); + return 0; + } else{ return -1; } } @@ -2457,9 +2472,6 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i usb_dev->dev = &usb->dev; usb_set_intfdata(intf, usb_dev); - usb_dev->vid = id->idVendor; - usb_dev->pid = id->idProduct; - ret = aicwf_usb_chipmatch(usb_dev, id->idVendor, id->idProduct); if (ret < 0) { @@ -2531,9 +2543,6 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i AICWFDBG(LOGERROR, "aicwf_rwnx_usb_platform_init err %d\n", ret); goto out_free_bus; } - if(usb_dev->msg_in_pipe){ - aicwf_usb_rx_prepare(usb_dev); - } aicwf_hostif_ready(); #ifdef CONFIG_GPIO_WAKEUP @@ -2601,8 +2610,10 @@ static int aicwf_usb_suspend(struct usb_interface *intf, pm_message_t state) struct rwnx_vif *rwnx_vif, *tmp; AICWFDBG(LOGINFO, "%s enter\r\n", __func__); -#ifdef CONFIG_WOWLAN +#ifdef CONFIG_WOWLAN +#ifndef ANDROID_PLATFORM rwnx_send_dummy_reboot(usb_dev->rwnx_hw); +#endif #endif list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) { if (rwnx_vif->ndev){ @@ -2633,7 +2644,8 @@ static int aicwf_usb_resume(struct usb_interface *intf) } if (usb_dev->state != USB_UP_ST){ - aicwf_bus_start(usb_dev->bus_if); + aicwf_bus_start(usb_dev->bus_if); + g_rwnx_plat->wait_disconnect_cb = false; } list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) { @@ -2641,10 +2653,7 @@ static int aicwf_usb_resume(struct usb_interface *intf) netif_tx_wake_all_queues(rwnx_vif->ndev); } } - if(usb_dev->msg_in_pipe){ - aicwf_usb_rx_prepare(usb_dev); - } - return 0; + return 0; } static int aicwf_usb_reset_resume(struct usb_interface *intf) @@ -2665,6 +2674,14 @@ static struct usb_device_id aicwf_usb_id_table[] = { {USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800M80_CUS1)}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D81X2, 0xff, 0xff, 0xff)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D89X2)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80N, 0xff, 0xff, 0xff)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80LN, 0xff, 0xff, 0xff)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80WN, 0xff, 0xff, 0xff)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D40N, 0xff, 0xff, 0xff)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D40LN, 0xff, 0xff, 0xff)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D40WN, 0xff, 0xff, 0xff)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800DLN, 0xff, 0xff, 0xff)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800DWN, 0xff, 0xff, 0xff)}, {USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA)}, {USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U2)}, {USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U11)}, diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_usb.h b/drivers/aic8800/aic8800_fdrv/aicwf_usb.h index 84403bc..88956dc 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_usb.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_usb.h @@ -37,6 +37,14 @@ #define USB_PRODUCT_ID_AIC8800D41 0x8d41 #define USB_PRODUCT_ID_AIC8800D81X2 0x8d91 #define USB_PRODUCT_ID_AIC8800D89X2 0x8d99 +#define USB_PRODUCT_ID_AIC8800D80N 0x8d45 +#define USB_PRODUCT_ID_AIC8800D80LN 0x8d46 +#define USB_PRODUCT_ID_AIC8800D80WN 0x8d47 +#define USB_PRODUCT_ID_AIC8800D40N 0x8d48 +#define USB_PRODUCT_ID_AIC8800D40LN 0x8d49 +#define USB_PRODUCT_ID_AIC8800D40WN 0x8d4a +#define USB_PRODUCT_ID_AIC8800DWN 0x8870 +#define USB_PRODUCT_ID_AIC8800DLN 0x8871 #define USB_PRODUCT_ID_TENDA 0x0013 #define USB_PRODUCT_ID_TENDA_U2 0x0014 #define USB_PRODUCT_ID_TENDA_U11 0x001f @@ -64,6 +72,8 @@ enum AICWF_IC{ PRODUCT_ID_AIC8801 = 0, PRODUCT_ID_AIC8800DC, PRODUCT_ID_AIC8800DW, + PRODUCT_ID_AIC8800DLN, + PRODUCT_ID_AIC8800D80N, PRODUCT_ID_AIC8800D81, PRODUCT_ID_AIC8800D81X2, PRODUCT_ID_AIC8800D89X2 @@ -78,7 +88,7 @@ enum AICWF_IC{ #define TXQLEN (2048*4) #define AICWF_USB_TX_URBS (50) #else -#define AICWF_USB_TX_URBS 50//(100) +#define AICWF_USB_TX_URBS 200//(100) #endif #define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4)//25% #define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3)//75% @@ -202,8 +212,6 @@ struct aic_usb_dev { #endif u16 chipid; bool tbusy; - u16_l vid; - u16_l pid; }; extern void aicwf_usb_exit(void); @@ -214,7 +222,9 @@ int usb_msg_busrx_thread(void *data); #endif int usb_bustx_thread(void *data); int usb_busrx_thread(void *data); - +void rwnx_stop_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw); +void rwnx_wake_sta_all_queues(void *sta, struct rwnx_hw *rwnx_hw); +void aicwf_usb_cancel_all_urbs(struct aic_usb_dev *usb_dev); extern void aicwf_hostif_ready(void); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.c b/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.c index d97a82f..5f09e85 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.c @@ -400,7 +400,7 @@ static char *aicwf_get_iwe_stream_mac_addr(struct rwnx_hw* rwnx_hw, iwe->cmd = SIOCGIWAP; iwe->u.ap_addr.sa_family = ARPHRD_ETHER; - if(scan_re->bss && &scan_re->bss->bssid[0]){ + if(scan_re->bss){ memcpy(iwe->u.ap_addr.sa_data, scan_re->bss->bssid, ETH_ALEN); } @@ -616,8 +616,10 @@ static inline char *aicwf_get_iwe_stream_rate(struct rwnx_hw* rwnx_hw, u16 vht_data_rate = 0; u16 he_cap = false; - u8 he_ch_width_set = 0; u8 he_bw = 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)|| defined(CONFIG_HE_FOR_OLD_KERNEL) + u8 he_ch_width_set = 0; +#endif /* parsing HT_CAP_IE */ ie_content = NULL; diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.h b/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.h index 4a9c4ec..1afab40 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.h @@ -8,4 +8,6 @@ struct scanu_result_wext{ void aicwf_set_wireless_ext( struct net_device *ndev, struct rwnx_hw *rwnx_hw); void aicwf_scan_complete_event(struct net_device *dev); +int aic_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len); +u8 aicwf_get_is_wps_ie(u8 *ie_ptr, uint *wps_ielen); diff --git a/drivers/aic8800/aic8800_fdrv/lmac_msg.h b/drivers/aic8800/aic8800_fdrv/lmac_msg.h index b0b51df..ba08b9c 100644 --- a/drivers/aic8800/aic8800_fdrv/lmac_msg.h +++ b/drivers/aic8800/aic8800_fdrv/lmac_msg.h @@ -413,6 +413,13 @@ enum mm_msg_tag MM_SET_TXPWR_PER_STA_REQ, MM_SET_TXPWR_PER_STA_CFM, + MM_GET_STATISTIC_REQ, + MM_GET_STATISTIC_CFM, + + MM_VENDOR_SWCONFIG_IND, + MM_FW_PANIC_IND, + MM_FW_ASSERT_IND, + /// MAX number of messages MM_MAX, }; @@ -892,6 +899,7 @@ struct mm_ba_add_cfm u8_l tid; /// Status of ba establishment u8_l status; + u8_l alligned; }; /// Structure containing the parameters of the @ref MM_BA_DEL_REQ message. @@ -1345,6 +1353,12 @@ struct mm_get_sta_info_req u8_l sta_idx; }; +struct mm_get_sta_info_compat_req +{ + u8_l sta_idx; + char pattern[3]; +}; + struct mm_get_sta_info_cfm { u32_l rate_info; @@ -1412,6 +1426,12 @@ typedef struct s8_l pwrlvl_adj_tbl_5g[6]; } txpwr_lvl_adj_conf_t; +typedef struct +{ + u8_l enable; + s8_l pwrlvl_adj_tbl_2g4[3]; +} txpwr_lvl_adj_conf_v2_t; + struct mm_set_txpwr_lvl_req { union { @@ -1424,7 +1444,10 @@ struct mm_set_txpwr_lvl_req struct mm_set_txpwr_lvl_adj_req { + union { txpwr_lvl_adj_conf_t txpwr_lvl_adj; + txpwr_lvl_adj_conf_v2_t txpwr_lvl_adj_v2; + }; }; typedef struct @@ -1538,12 +1561,33 @@ typedef struct s8_l pwrofst2x_tbl_6g_ant1[15]; } txpwr_ofst2x_conf_v2_t; +/* + * pwrofst2x_tbl_2g4[3][3]: + * +---------------+----------+----------+----------+ + * | RateTyp\ChGrp | CH_1_4 | CH_5_9 | CH_10_13 | + * +---------------+----------+----------+----------+ + * | DSSS | [0][0] | [0][1] | [0][2] | + * +---------------+----------+----------+----------+ + * | OFDM_HIGHRATE | [1][0] | [1][1] | [1][2] | + * +---------------+----------+----------+----------+ + * | OFDM_LOWRATE | [2][0] | [2][1] | [2][2] | + * +---------------+----------+----------+----------+ + */ + +typedef struct +{ + u8_l enable; + s8_l pwrofst2x_tbl_2g4[3][3]; + u8_l RESERVED[2]; +} txpwr_ofst2x_conf_v3_t; + struct mm_set_txpwr_ofst_req { union { txpwr_ofst_conf_t txpwr_ofst; txpwr_ofst2x_conf_t txpwr_ofst2x; txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2; + txpwr_ofst2x_conf_v3_t txpwr_ofst2x_v3; }; }; @@ -1664,6 +1708,18 @@ struct mm_csa_traffic_ind bool_l enable; }; +struct fw_panic_info_ind +{ + uint32_t len; + uint8_t info[384]; +}; + +struct fw_assert_info_ind +{ + uint32_t len; + uint8_t info[384]; +}; + /// Structure containing the parameters of the @ref MM_MU_GROUP_UPDATE_REQ message. /// Size allocated for the structure depends of the number of group struct mm_mu_group_update_req @@ -2038,6 +2094,7 @@ struct me_sta_add_cfm u8_l status; /// PM state of the station u8_l pm_state; + u8_l alligned; }; /// Structure containing the parameters of the @ref ME_STA_DEL_REQ message. @@ -3463,37 +3520,4 @@ struct mm_set_wakeup_info_req { u16_l length; u8_l mask_and_pattern[]; }; - -struct dbg_pwm_init_req -{ - /// PWM_CHANNEL_GPIO - u8 pwm_gpidx; - /// 0 normal 1 breath - u8 mode; - /// 0 config only 1 run after config - u8 run; - u32 tmr_cnt; - u32 dty_cnt; - u32 step_val; - /// 0 disable 1 enable - u8 gpio_en; - /// 0 input 1 output - u8 gpio_dir; - /// 0 low 1 high - u8 gpio_val; -}; - -struct dbg_pwm_deinit_req -{ - /// PWM_CHANNEL_GPIO - u8 pwm_gpidx; - /// 0 disable 1 enable - u8 gpio_en; - /// 0 input 1 output - u8 gpio_dir; - /// 0 low 1 high - u8 gpio_val; -}; - - #endif // LMAC_MSG_H_ diff --git a/drivers/aic8800/aic8800_fdrv/regdb.c b/drivers/aic8800/aic8800_fdrv/regdb.c index d3ac7ac..cd878bf 100644 --- a/drivers/aic8800/aic8800_fdrv/regdb.c +++ b/drivers/aic8800/aic8800_fdrv/regdb.c @@ -7,7 +7,7 @@ * * @brief country code Dependent document * https://mirrors.edge.kernel.org/pub/software/network/wireless-regdb/ - * wireless-regdb-2024.05.08 + * wireless-regdb-2025.02.20 * ****************************************************************************** */ @@ -41,23 +41,17 @@ static const struct ieee80211_regdomain regdom_00 = { } }; -#if 0 +#if 0 //for the purpose of testing and verification static const struct ieee80211_regdomain regdom_00 = { .n_reg_rules = 8, .alpha2 = "00", .reg_rules = { REG_RULE_EXT(2402, 2472, 40, 0, 20, 0, 0), - // 12 - 13 REG_RULE_EXT(2457, 2482, 20, 0, 20, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_IR | 0), - // 14 REG_RULE_EXT(2474, 2494, 20, 0, 20, 0, NL80211_RRF_NO_IR | NL80211_RRF_NO_OFDM | 0), - // 36 - 48 REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_IR | 0), - // 52 - 64 REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_IR | NL80211_RRF_DFS | 0), - // 100 - 144 REG_RULE_EXT(5490, 5730, 160, 0, 20, 0, NL80211_RRF_NO_IR | NL80211_RRF_DFS | 0), - //149 - 165 REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, NL80211_RRF_NO_IR | 0), REG_RULE_EXT(57240, 63720, 2160, 0, 0, 0, 0), }}; @@ -89,8 +83,9 @@ static const struct ieee80211_regdomain regdom_AE = { NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 24, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_AF = { .alpha2 = "AF", @@ -138,9 +133,9 @@ static const struct ieee80211_regdomain regdom_AM = { .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 20, 0, 18, 0, 0), - REG_RULE_EXT(5250, 5330, 20, 0, 18, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5350, 160, 0, 17, 0, NL80211_RRF_DFS | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5470, 5875, 160, 0, 17, 0, NL80211_RRF_DFS | NL80211_RRF_NO_OUTDOOR | 0), }, .n_reg_rules = 3}; @@ -168,8 +163,9 @@ static const struct ieee80211_regdomain regdom_AR = { NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 7125, 320, 0, 12, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_AS = { .alpha2 = "AS", @@ -196,8 +192,8 @@ static const struct ieee80211_regdomain regdom_AT = { NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 71000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -241,8 +237,9 @@ static const struct ieee80211_regdomain regdom_AZ = { REG_RULE_EXT(5170, 5250, 80, 0, 18, 0, NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5250, 5330, 80, 0, 18, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 3}; + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_BA = { .alpha2 = "BA", @@ -272,24 +269,15 @@ static const struct ieee80211_regdomain regdom_BB = { }, .n_reg_rules = 4}; -//Certified laboratory requirements static const struct ieee80211_regdomain regdom_BD = { .alpha2 = "BD", .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_BE = { .alpha2 = "BE", @@ -303,7 +291,7 @@ static const struct ieee80211_regdomain regdom_BE = { NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -333,22 +321,24 @@ static const struct ieee80211_regdomain regdom_BG = { NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_BH = { .alpha2 = "BH", - .dfs_region = NL80211_DFS_JP, + .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 20, 0, 20, 0, 0), - REG_RULE_EXT(5250, 5330, 20, 0, 20, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 20, 0, 20, 0, 0), + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5350, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | 0), + REG_RULE_EXT(5470, 5725, 80, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 4}; + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_BL = { .alpha2 = "BL", @@ -451,17 +441,9 @@ static const struct ieee80211_regdomain regdom_BW = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5725, 5825, 80, 0, 33, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_BY = { .alpha2 = "BY", @@ -529,7 +511,7 @@ static const struct ieee80211_regdomain regdom_CH = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 71000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -558,8 +540,9 @@ static const struct ieee80211_regdomain regdom_CL = { REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 12, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 4}; + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_CN = { .alpha2 = "CN", @@ -567,14 +550,15 @@ static const struct ieee80211_regdomain regdom_CN = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5350, 80, 0, 20, 0, + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(5725, 5850, 80, 0, 33, 0, 0), REG_RULE_EXT(57240, 59400, 2160, 0, 28, 0, 0), REG_RULE_EXT(59400, 63720, 2160, 0, 44, 0, 0), REG_RULE_EXT(63720, 65880, 2160, 0, 28, 0, 0), }, - .n_reg_rules = 6}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_CO = { .alpha2 = "CO", @@ -587,21 +571,24 @@ static const struct ieee80211_regdomain regdom_CO = { NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 7125, 320, 0, 12, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_CR = { .alpha2 = "CR", .dfs_region = NL80211_DFS_FCC, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 20, 0, 17, 0, 0), - REG_RULE_EXT(5250, 5330, 20, 0, 24, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5730, 20, 0, 24, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 20, 0, 30, 0, 0), + REG_RULE_EXT(2402, 2482, 40, 0, 36, 0, 0), + REG_RULE_EXT(5170, 5250, 20, 0, 30, 0, 0), + REG_RULE_EXT(5250, 5330, 20, 0, 30, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5490, 5730, 20, 0, 30, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 20, 0, 36, 0, 0), + REG_RULE_EXT(5875, 5925, 20, 0, 30, 0, 0), + REG_RULE_EXT(5925, 7125, 320, 0, 30, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_CU = { .alpha2 = "CU", @@ -642,7 +629,7 @@ static const struct ieee80211_regdomain regdom_CY = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -660,7 +647,7 @@ static const struct ieee80211_regdomain regdom_CZ = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -678,7 +665,7 @@ static const struct ieee80211_regdomain regdom_DE = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -696,7 +683,7 @@ static const struct ieee80211_regdomain regdom_DK = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -724,27 +711,21 @@ static const struct ieee80211_regdomain regdom_DO = { REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 7125, 320, 0, 15, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 4}; + .n_reg_rules = 5}; -//Certified laboratory requirements static const struct ieee80211_regdomain regdom_DZ = { .alpha2 = "DZ", - .dfs_region = NL80211_DFS_ETSI, + .dfs_region = NL80211_DFS_JP, .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5670, 160, 0, 23, 0, NL80211_RRF_DFS | 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_EC = { .alpha2 = "EC", @@ -772,7 +753,7 @@ static const struct ieee80211_regdomain regdom_EE = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -802,7 +783,7 @@ static const struct ieee80211_regdomain regdom_ES = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -833,7 +814,7 @@ static const struct ieee80211_regdomain regdom_FI = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -926,24 +907,18 @@ static const struct ieee80211_regdomain regdom_GF = { }, .n_reg_rules = 4}; -//Certified laboratory requirements static const struct ieee80211_regdomain regdom_GH = { .alpha2 = "GH", - .dfs_region = NL80211_DFS_ETSI, + .dfs_region = NL80211_DFS_FCC, .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 5}; //kernel undefined static const struct ieee80211_regdomain regdom_GI = { @@ -952,17 +927,9 @@ static const struct ieee80211_regdomain regdom_GI = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5725, 5825, 80, 0, 33, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_GL = { .alpha2 = "GL", @@ -1002,23 +969,26 @@ static const struct ieee80211_regdomain regdom_GR = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_GT = { .alpha2 = "GT", - .dfs_region = NL80211_DFS_FCC, .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(2400, 2483, 40, 0, 27, 0, 0), + REG_RULE_EXT(5150, 5350, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 24, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 27, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(6425, 6525, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(6525, 6875, 320, 0, 22, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(6875, 7125, 160, 0, 22, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 13, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 4}; + .n_reg_rules = 9}; static const struct ieee80211_regdomain regdom_GU = { .alpha2 = "GU", @@ -1071,8 +1041,10 @@ static const struct ieee80211_regdomain regdom_HN = { NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 12, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_NO_IR | 0), + REG_RULE_EXT(57240, 71000, 2160, 0, 40, 0, 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_HR = { .alpha2 = "HR", @@ -1084,7 +1056,7 @@ static const struct ieee80211_regdomain regdom_HR = { REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -1116,7 +1088,7 @@ static const struct ieee80211_regdomain regdom_HU = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -1145,7 +1117,7 @@ static const struct ieee80211_regdomain regdom_IE = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -1155,17 +1127,18 @@ static const struct ieee80211_regdomain regdom_IL = { .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_IN = { .alpha2 = "IN", @@ -1186,27 +1159,21 @@ static const struct ieee80211_regdomain regdom_IQ = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5725, 5825, 80, 0, 33, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_IR = { .alpha2 = "IR", - .dfs_region = NL80211_DFS_JP, + .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, 0), + REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_NO_INDOOR | NL80211_RRF_DFS | 0), }, - .n_reg_rules = 2}; + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_IS = { .alpha2 = "IS", @@ -1219,9 +1186,10 @@ static const struct ieee80211_regdomain regdom_IS = { NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, - .n_reg_rules = 6}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_IT = { .alpha2 = "IT", @@ -1236,7 +1204,7 @@ static const struct ieee80211_regdomain regdom_IT = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 5}; @@ -1257,14 +1225,18 @@ static const struct ieee80211_regdomain regdom_JM = { static const struct ieee80211_regdomain regdom_JO = { .alpha2 = "JO", - .dfs_region = NL80211_DFS_JP, + .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, 0), - REG_RULE_EXT(5735, 5835, 80, 0, 23, 0, 0), + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 80, 0, 27, 0, NL80211_RRF_DFS | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 71000, 2160, 0, 40, 0, 0), }, - .n_reg_rules = 3}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_JP = { .alpha2 = "JP", @@ -1285,15 +1257,17 @@ static const struct ieee80211_regdomain regdom_JP = { static const struct ieee80211_regdomain regdom_KE = { .alpha2 = "KE", - .dfs_region = NL80211_DFS_JP, + .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, 0), - REG_RULE_EXT(5490, 5570, 80, 0, 30, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5775, 40, 0, 23, 0, 0), + REG_RULE_EXT(2400, 2483, 40, 0, 33, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 17, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 80, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 40, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 4}; + .n_reg_rules = 6}; //kernel undefined static const struct ieee80211_regdomain regdom_KG = { @@ -1302,17 +1276,9 @@ static const struct ieee80211_regdomain regdom_KG = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5725, 5825, 80, 0, 33, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_KH = { .alpha2 = "KH", @@ -1375,26 +1341,30 @@ static const struct ieee80211_regdomain regdom_KW = { .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 17, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5825, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 3}; + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_KY = { .alpha2 = "KY", .dfs_region = NL80211_DFS_FCC, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + REG_RULE_EXT(2400, 2483, 40, 0, 30, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 24, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5470, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 12, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 71000, 2160, 0, 40, 0, 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_KZ = { .alpha2 = "KZ", @@ -1452,9 +1422,10 @@ static const struct ieee80211_regdomain regdom_LI = { NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, - .n_reg_rules = 6}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_LK = { .alpha2 = "LK", @@ -1495,7 +1466,7 @@ static const struct ieee80211_regdomain regdom_LT = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -1513,7 +1484,7 @@ static const struct ieee80211_regdomain regdom_LU = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -1531,7 +1502,7 @@ static const struct ieee80211_regdomain regdom_LV = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -1543,17 +1514,9 @@ static const struct ieee80211_regdomain regdom_LY = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5725, 5825, 80, 0, 33, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_MA = { .alpha2 = "MA", @@ -1564,8 +1527,9 @@ static const struct ieee80211_regdomain regdom_MA = { REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 3}; + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_MC = { .alpha2 = "MC", @@ -1594,8 +1558,9 @@ static const struct ieee80211_regdomain regdom_MD = { NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_ME = { .alpha2 = "ME", @@ -1667,21 +1632,24 @@ static const struct ieee80211_regdomain regdom_MN = { NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 30, 0, 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_MO = { .alpha2 = "MO", .dfs_region = NL80211_DFS_FCC, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 23, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 30, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(2400, 2483, 40, 0, 23, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5730, 160, 0, 30, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 24, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_MP = { .alpha2 = "MP", @@ -1736,7 +1704,7 @@ static const struct ieee80211_regdomain regdom_MT = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -1752,8 +1720,9 @@ static const struct ieee80211_regdomain regdom_MU = { NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_MV = { .alpha2 = "MV", @@ -1792,29 +1761,24 @@ static const struct ieee80211_regdomain regdom_MX = { NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 12, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 6}; -//Certified laboratory requirements static const struct ieee80211_regdomain regdom_MY = { .alpha2 = "MY", - .dfs_region = NL80211_DFS_ETSI, + .dfs_region = NL80211_DFS_FCC, .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(2402, 2482, 40, 0, 27, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 30, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 30, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5650, 160, 0, 30, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 6}; -//kernel undefined static const struct ieee80211_regdomain regdom_NA = { .alpha2 = "NA", .dfs_region = NL80211_DFS_ETSI, @@ -1826,10 +1790,10 @@ static const struct ieee80211_regdomain regdom_NA = { REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5470, 5725, 160, 0, 21, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, NL80211_RRF_NO_OUTDOOR | 0), }, .n_reg_rules = 7}; @@ -1871,7 +1835,7 @@ static const struct ieee80211_regdomain regdom_NL = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -1889,7 +1853,7 @@ static const struct ieee80211_regdomain regdom_NO = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 71000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -1912,27 +1876,32 @@ static const struct ieee80211_regdomain regdom_NZ = { .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + REG_RULE_EXT(2400, 2483, 40, 0, 36, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 30, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 27, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5470, 5730, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 36, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 24, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 5}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_OM = { .alpha2 = "OM", .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 28, 0, NL80211_RRF_DFS | NL80211_RRF_NO_INDOOR | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 4}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_PA = { .alpha2 = "PA", @@ -1948,24 +1917,19 @@ static const struct ieee80211_regdomain regdom_PA = { }, .n_reg_rules = 6}; -//Certified laboratory requirements static const struct ieee80211_regdomain regdom_PE = { .alpha2 = "PE", - .dfs_region = NL80211_DFS_ETSI, + .dfs_region = NL80211_DFS_FCC, .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 7125, 320, 0, 12, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_PF = { .alpha2 = "PF", @@ -1994,44 +1958,30 @@ static const struct ieee80211_regdomain regdom_PG = { }, .n_reg_rules = 5}; -//Certified laboratory requirements static const struct ieee80211_regdomain regdom_PH = { .alpha2 = "PH", - .dfs_region = NL80211_DFS_ETSI, + .dfs_region = NL80211_DFS_FCC, .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 24, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 24, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_PK = { .alpha2 = "PK", - .dfs_region = NL80211_DFS_JP, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5270, 80, 0, 23, 0, - NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(5270, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5470, 5610, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5610, 5725, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(2400, 2500, 40, 0, 30, 0, 0), REG_RULE_EXT(5725, 5875, 80, 0, 30, 0, 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 3}; static const struct ieee80211_regdomain regdom_PL = { .alpha2 = "PL", @@ -2046,7 +1996,7 @@ static const struct ieee80211_regdomain regdom_PL = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -2091,7 +2041,7 @@ static const struct ieee80211_regdomain regdom_PT = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -2138,9 +2088,10 @@ static const struct ieee80211_regdomain regdom_QA = { REG_RULE_EXT(5470, 5725, 160, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 6}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_RE = { .alpha2 = "RE", @@ -2168,7 +2119,7 @@ static const struct ieee80211_regdomain regdom_RO = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -2179,16 +2130,15 @@ static const struct ieee80211_regdomain regdom_RS = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | - NL80211_RRF_DFS | 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_DFS | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5725, 5850, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_DFS | 0), + REG_RULE_EXT(5850, 5875, 20, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, - .n_reg_rules = 6}; + .n_reg_rules = 8}; static const struct ieee80211_regdomain regdom_RU = { .alpha2 = "RU", @@ -2227,8 +2177,9 @@ static const struct ieee80211_regdomain regdom_SA = { REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5925, 7125, 320, 0, 24, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 4}; + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_SE = { .alpha2 = "SE", @@ -2243,7 +2194,7 @@ static const struct ieee80211_regdomain regdom_SE = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -2277,7 +2228,7 @@ static const struct ieee80211_regdomain regdom_SI = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -2295,7 +2246,7 @@ static const struct ieee80211_regdomain regdom_SK = { NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 7}; @@ -2307,17 +2258,9 @@ static const struct ieee80211_regdomain regdom_SM = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5725, 5825, 80, 0, 33, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_SN = { .alpha2 = "SN", @@ -2355,16 +2298,28 @@ static const struct ieee80211_regdomain regdom_SV = { REG_RULE_EXT(5170, 5250, 20, 0, 17, 0, 0), REG_RULE_EXT(5250, 5330, 20, 0, 23, 0, NL80211_RRF_DFS | 0), REG_RULE_EXT(5735, 5835, 20, 0, 30, 0, 0), + REG_RULE_EXT(5925, 7125, 320, 0, 12, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 4}; + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_SY = { .alpha2 = "SY", + .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5850, 5875, 20, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 1}; + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_TC = { .alpha2 = "TC", @@ -2398,31 +2353,27 @@ static const struct ieee80211_regdomain regdom_TG = { .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 40, 0, 20, 0, 0), - REG_RULE_EXT(5250, 5330, 40, 0, 20, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5710, 40, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5150, 5350, 80, 0, 20, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5470, 5850, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, NL80211_RRF_DFS | 0), }, - .n_reg_rules = 4}; + .n_reg_rules = 5}; -//Certified laboratory requirements static const struct ieee80211_regdomain regdom_TH = { .alpha2 = "TH", - .dfs_region = NL80211_DFS_ETSI, + .dfs_region = NL80211_DFS_FCC, .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 24, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 6}; //kernel undefined static const struct ieee80211_regdomain regdom_TJ = { @@ -2431,17 +2382,9 @@ static const struct ieee80211_regdomain regdom_TJ = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5725, 5825, 80, 0, 33, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; //kernel undefined static const struct ieee80211_regdomain regdom_TM = { @@ -2450,17 +2393,9 @@ static const struct ieee80211_regdomain regdom_TM = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5725, 5825, 80, 0, 33, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_TN = { .alpha2 = "TN", @@ -2485,7 +2420,7 @@ static const struct ieee80211_regdomain regdom_TR = { REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5495, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), }, .n_reg_rules = 6}; @@ -2522,12 +2457,19 @@ static const struct ieee80211_regdomain regdom_TW = { static const struct ieee80211_regdomain regdom_TZ = { .alpha2 = "TZ", + .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_NO_OUTDOOR | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), }, - .n_reg_rules = 2}; + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_UA = { @@ -2588,24 +2530,17 @@ static const struct ieee80211_regdomain regdom_US = { }, .n_reg_rules = 8}; -//Certified laboratory requirements static const struct ieee80211_regdomain regdom_UY = { .alpha2 = "UY", .dfs_region = NL80211_DFS_ETSI, .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_UZ = { .alpha2 = "UZ", @@ -2718,17 +2653,9 @@ static const struct ieee80211_regdomain regdom_FK = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5725, 5825, 80, 0, 33, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; //kernel undefined static const struct ieee80211_regdomain regdom_FO = { @@ -2737,17 +2664,9 @@ static const struct ieee80211_regdomain regdom_FO = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5725, 5825, 80, 0, 33, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_YE = { .alpha2 = "YE", @@ -2780,8 +2699,9 @@ static const struct ieee80211_regdomain regdom_ZA = { REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), REG_RULE_EXT(5490, 5710, 160, 0, 30, 0, 0), + REG_RULE_EXT(5925, 6425, 320, 0, 14, 0, 0), }, - .n_reg_rules = 4}; + .n_reg_rules = 5}; //kernel undefined static const struct ieee80211_regdomain regdom_ZM = { @@ -2790,17 +2710,9 @@ static const struct ieee80211_regdomain regdom_ZM = { .reg_rules = { REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), - REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), - REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + REG_RULE_EXT(5725, 5825, 80, 0, 33, 0, 0), }, - .n_reg_rules = 7}; + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_ZW = { .alpha2 = "ZW", @@ -2839,7 +2751,6 @@ static const struct ieee80211_regdomain regdom_XX = { }, }; -//Keep "XX" at the end when inserting const struct ieee80211_regdomain *reg_regdb[] = { ®dom_00, ®dom_AD, ®dom_AE, ®dom_AF, ®dom_AI, ®dom_AL, ®dom_AM, ®dom_AN, ®dom_AR, ®dom_AS, ®dom_AT, ®dom_AU, diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_cmds.c b/drivers/aic8800/aic8800_fdrv/rwnx_cmds.c index 68ddcea..8dbb88e 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_cmds.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_cmds.c @@ -139,9 +139,13 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) #endif if(cmd->e2a_msg != NULL) { do { - if(cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) - break; - spin_lock_bh(&cmd_mgr->lock); + spin_lock_bh(&cmd_mgr->lock); + if(cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) { + AICWFDBG(LOGERROR, "cmd queue crashed\n"); + cmd->result = -EPIPE; + spin_unlock_bh(&cmd_mgr->lock); + return -EPIPE; + } empty = list_empty(&cmd_mgr->cmds); if(!empty) { spin_unlock_bh(&cmd_mgr->lock); @@ -155,16 +159,14 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) } } while(!empty);//wait for cmd queue empty } else { - spin_lock_bh(&cmd_mgr->lock); - } - - - if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) { - printk(KERN_CRIT"cmd queue crashed\n"); - cmd->result = -EPIPE; - spin_unlock_bh(&cmd_mgr->lock); - return -EPIPE; - } + spin_lock_bh(&cmd_mgr->lock); + if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) { + printk(KERN_CRIT"cmd queue crashed\n"); + cmd->result = -EPIPE; + spin_unlock_bh(&cmd_mgr->lock); + return -EPIPE; + } + } #ifndef CONFIG_RWNX_FHOST if (!list_empty(&cmd_mgr->cmds)) { @@ -221,8 +223,9 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) //printk("defer push: tkn=%d\r\n", cmd->tkn); } - spin_unlock_bh(&cmd_mgr->lock); + //spin_unlock_bh(&cmd_mgr->lock); if (!defer_push) { + spin_unlock_bh(&cmd_mgr->lock); AICWFDBG(LOGTRACE, "queue:id=%x, param_len=%u\n",cmd->a2e_msg->id, cmd->a2e_msg->param_len); #ifdef AICWF_SDIO_SUPPORT @@ -234,9 +237,12 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) kfree(cmd->a2e_msg); } else { - if(cmd_mgr->queue_sz <= 1){ - WAKE_CMD_WORK(cmd_mgr); - } + if(cmd_mgr->queue_sz <= 1) { + spin_unlock_bh(&cmd_mgr->lock); + WAKE_CMD_WORK(cmd_mgr); + } else { + spin_unlock_bh(&cmd_mgr->lock); + } return 0; } @@ -559,7 +565,6 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len) { u8 *buffer = NULL; u16 index = 0; - int ret = 0; #ifdef AICWF_SDIO_SUPPORT struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev; struct aicwf_bus *bus = sdiodev->bus_if; @@ -594,9 +599,6 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len) index += 2; memcpy(&buffer[index], (u8 *)msg->param, msg->param_len); - ret = aicwf_bus_txmsg(bus, buffer, len + 8); - if (ret == -EIO) { - ret = aicwf_bus_txmsg(bus, buffer, len + 8); - } + aicwf_bus_txmsg(bus, buffer, len + 8); } diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_cmds.h b/drivers/aic8800/aic8800_fdrv/rwnx_cmds.h index 8862a86..1a60e3f 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_cmds.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_cmds.h @@ -116,5 +116,6 @@ void rwnx_cmd_mgr_init(struct rwnx_cmd_mgr *cmd_mgr); void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr); int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd); void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len); +void cmd_mgr_task_process(struct work_struct *work); #endif /* _RWNX_CMDS_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_compat.h b/drivers/aic8800/aic8800_fdrv/rwnx_compat.h index 7c26d0f..0719b20 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, 18, 0) +#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 15, 60) #define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE #endif @@ -380,6 +380,7 @@ enum { rwnx_ops_hw_scan(hw, vif, struct cfg80211_scan_request *req) #endif +u16 rwnx_select_txq(struct rwnx_vif *rwnx_vif, struct sk_buff *skb); /* NET */ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) #define rwnx_select_queue(dev, skb, sb_dev) \ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.c b/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.c index 7d4c82e..0b6032b 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.c @@ -1777,7 +1777,7 @@ static ssize_t rwnx_dbgfs_dbg_level_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct rwnx_hw *priv = file->private_data; + //struct rwnx_hw *priv = file->private_data; char buf[32]; int ret; ssize_t read; @@ -1796,7 +1796,7 @@ static ssize_t rwnx_dbgfs_dbg_level_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { - struct rwnx_hw *priv = file->private_data; + //struct rwnx_hw *priv = file->private_data; char buf[32]; int val; size_t len = min_t(size_t, count, sizeof(buf) - 1); @@ -2019,7 +2019,7 @@ static void idx_to_rate_cfg1(unsigned int formatmod, case FORMATMOD_NON_HT: { r_cfg->formatModTx = formatmod; - r_cfg->giAndPreTypeTx = 1; + r_cfg->giAndPreTypeTx = 2; r_cfg->mcsIndexTx = mcs; break; } @@ -2236,8 +2236,7 @@ static ssize_t rwnx_dbgfs_rc_fixed_rate_idx_write(struct file *file, /* Get the station index from MAC address */ sscanf(file->f_path.dentry->d_parent->d_iname, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); - if (&mac[0] == NULL) - return 0; + sta = rwnx_get_sta(priv, mac); if (sta == NULL) return 0; diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.h b/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.h index 5d93f12..5e1a939 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.h @@ -198,6 +198,7 @@ static inline void rwnx_dbgfs_register_rc_stat(struct rwnx_hw *rwnx_hw, struct r static inline void rwnx_dbgfs_unregister_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) {} #endif #endif /* CONFIG_RWNX_DEBUGFS */ +void _rwnx_dbgfs_rc_stat_write(struct rwnx_debugfs *rwnx_debugfs, uint8_t sta_idx); #endif /* _RWNX_DEBUGFS_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_defs.h b/drivers/aic8800/aic8800_fdrv/rwnx_defs.h index 643b45f..bd811e2 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_defs.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_defs.h @@ -79,20 +79,11 @@ #if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION -#ifndef IEEE80211_MAX_AMPDU_BUF #define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE -#endif -#ifndef IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB #define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB -#endif -#ifndef IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB #define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB -#endif -#ifndef IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA #define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU #endif -#endif - #ifndef IEEE80211_MAX_AMPDU_BUF #define IEEE80211_MAX_AMPDU_BUF 0x100 @@ -107,6 +98,7 @@ #define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40 #endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) enum nl80211_ac { NL80211_AC_VO, @@ -237,6 +229,7 @@ struct tmp_feature_sta { u8_l supported_band; }; +#if 0 #define MAX_PENDING_PROBES 3 struct ap_probe_rsp { u8_l da[6]; @@ -244,6 +237,7 @@ struct ap_probe_rsp { bool in_use; }; #endif +#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) #define NL80211_MESHCONF_POWER_MODE 26 @@ -388,6 +382,18 @@ enum rwnx_ap_flags { RWNX_AP_ISOLATE = BIT(0), }; +#ifdef CONFIG_DYNAMIC_PERPWR +struct sta_pwrthd { + s8_l rssi_thd_0; //rssi 0 (dBm) + s8_l rssi_thd_1; //rssi 1 (dBm) + s8_l rssi_thd_2; //rssi 2 (dBm) + s8_l pwr_loss_lvl_0; //RSSI > RSSI_THD_0 + s8_l pwr_loss_lvl_1; //RSSI_THD_1 < RSSI <= RSSI_THD_0 + s8_l pwr_loss_lvl_2; //RSSI_THD_2 < RSSI <= RSSI_THD_1 + s8_l pwr_loss_lvl_3; //RSSI <= RSSI_THD_2 +}; +#endif + /* * Structure used to save information relative to the managed interfaces. * This is also linked within the rwnx_hw vifs list. @@ -402,6 +408,7 @@ struct rwnx_vif { struct rwnx_key key[6]; unsigned long drv_flags; atomic_t drv_conn_state; + spinlock_t conn_state_lock; u8 drv_vif_index; /* Identifier of the VIF in driver */ u8 vif_index; /* Identifier of the station in FW */ u8 ch_index; /* Channel context identifier */ @@ -458,6 +465,7 @@ struct rwnx_vif { u32_l freq; bool start; #endif + u32_l ap_freq; enum nl80211_mesh_power_mode mesh_pm; /* mesh power save mode currently set in firmware */ enum nl80211_mesh_power_mode next_mesh_pm; /* mesh power save mode for next peer */ } ap; @@ -487,12 +495,14 @@ struct rwnx_vif { struct br_ext_info ethBrExtInfo; #endif /* CONFIG_BR_SUPPORT */ #ifdef CONFIG_BAND_STEERING - struct workqueue_struct *rsp_wq; struct timer_list steer_timer; struct work_struct steer_work; struct b_steer_priv bsteerpriv; +#if 0 + struct workqueue_struct *rsp_wq; struct ap_probe_rsp pb_pool[MAX_PENDING_PROBES]; #endif +#endif }; @@ -724,7 +734,7 @@ struct amsdu_subframe_hdr { }; /* rwnx driver status */ -void rwnx_set_conn_state(atomic_t *drv_conn_state, int state); +void rwnx_set_conn_state(struct rwnx_vif *vif, atomic_t *drv_conn_state, int state); enum rwnx_drv_connect_status { RWNX_DRV_STATUS_DISCONNECTED = 0, @@ -885,6 +895,7 @@ struct rwnx_hw { char wext_essid[33]; int support_freqs[SCAN_CHANNEL_MAX]; int support_freqs_number; +#endif #ifdef CONFIG_DYNAMIC_PWR struct timer_list pwrloss_timer; struct work_struct pwrloss_work; @@ -892,11 +903,22 @@ struct rwnx_hw { s8 pwrloss_lvl; u8 sta_rssi_idx; #endif +#ifdef CONFIG_TEMP_CONTROL + struct timer_list tc_timer; + struct work_struct tc_work; + s8 tc_range; #endif #ifdef CONFIG_BAND_STEERING u8_l iface_idx; struct tmp_feature_sta feature_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX]; #endif +#ifdef CONFIG_DYNAMIC_PERPWR + struct sta_pwrthd pwrth; +#endif + + ktime_t last_time; + char last_alpha2[3]; + }; u8 *rwnx_build_bcn(struct rwnx_bcn *bcn, struct cfg80211_beacon_data *new); diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_dini.h b/drivers/aic8800/aic8800_fdrv/rwnx_dini.h index 2d8cf35..49df1f4 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_dini.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_dini.h @@ -16,5 +16,7 @@ int rwnx_dini_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_plat); +int rwnx_cfpga_irq_enable(struct rwnx_hw *rwnx_hw); +int rwnx_cfpga_irq_disable(struct rwnx_hw *rwnx_hw); #endif /* _RWNX_DINI_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_irqs.c b/drivers/aic8800/aic8800_fdrv/rwnx_irqs.c index 65e2493..3c32fa8 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_irqs.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_irqs.c @@ -12,7 +12,7 @@ #include "rwnx_defs.h" #include "ipc_host.h" #include "rwnx_prof.h" - +#include "rwnx_irqs.h" /** * rwnx_irq_hdlr - IRQ handler * diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_main.c b/drivers/aic8800/aic8800_fdrv/rwnx_main.c index 2b1d07a..8d0cf58 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_main.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_main.c @@ -44,9 +44,12 @@ #include "aicwf_compat_8800dc.h" #include "aicwf_compat_8800d80.h" #include "aicwf_compat_8800d80x2.h" +#include "aicwf_compat_8800d80n.h" +#include "aicwf_compat_8800dln.h" #include "aic_priv_cmd.h" #include "rwnx_wakelock.h" #include "rwnx_msg_tx.h" +#include "aic_vendor.h" #ifdef CONFIG_BAND_STEERING #include "aicwf_manager.h" #endif @@ -491,6 +494,12 @@ static u32 cipher_suites[] = { WLAN_CIPHER_SUITE_TKIP, WLAN_CIPHER_SUITE_CCMP, WLAN_CIPHER_SUITE_AES_CMAC, // reserved entries to enable AES-CMAC and/or SMS4 + WLAN_CIPHER_SUITE_GCMP, + WLAN_CIPHER_SUITE_GCMP_256, + WLAN_CIPHER_SUITE_CCMP_256, + WLAN_CIPHER_SUITE_BIP_GMAC_128, + WLAN_CIPHER_SUITE_BIP_GMAC_256, + WLAN_CIPHER_SUITE_BIP_CMAC_256, WLAN_CIPHER_SUITE_SMS4, 0, }; @@ -539,12 +548,16 @@ static const int rwnx_hwq2uapsd[NL80211_NUM_ACS] = { struct semaphore aicwf_deinit_sem; atomic_t aicwf_deinit_atomic; -int aicwf_dbg_level = LOGERROR|LOGINFO; +int aicwf_dbg_level = LOGERROR|LOGINFO|LOGFW; module_param(aicwf_dbg_level, int, 0660); #ifdef CONFIG_DYNAMIC_PWR int dynamic_pwr = 1; module_param(dynamic_pwr, int, 0660); #endif +#ifdef CONFIG_TEMP_CONTROL +int temp_control = 1; +module_param(temp_control, int, 0660); +#endif int testmode = 0; char aic_fw_path[200]; @@ -775,7 +788,7 @@ struct rwnx_sta *rwnx_get_sta(struct rwnx_hw *rwnx_hw, const u8 *mac_addr) void rwnx_enable_wapi(struct rwnx_hw *rwnx_hw) { //cipher_suites[rwnx_hw->wiphy->n_cipher_suites] = WLAN_CIPHER_SUITE_SMS4; - rwnx_hw->wiphy->n_cipher_suites ++; + //rwnx_hw->wiphy->n_cipher_suites ++; rwnx_hw->wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; } @@ -977,8 +990,14 @@ void rwnx_chanctx_unlink(struct rwnx_vif *vif) { struct rwnx_chanctx *ctxt; - if (vif->ch_index == RWNX_CH_NOT_SET) + if (vif->ch_index == RWNX_CH_NOT_SET) { return; + } + + if (vif->ch_index >= NX_CHAN_CTXT_CNT) { + WARN(1, "Invalid channel ctxt id %d", vif->ch_index); + return; + } ctxt = &vif->rwnx_hw->chanctx_table[vif->ch_index]; @@ -1287,8 +1306,8 @@ void netdev_br_init(struct net_device *netdev) } #endif /* CONFIG_BR_SUPPORT */ -void rwnx_set_conn_state(atomic_t *drv_conn_state, int state){ - +void rwnx_set_conn_state(struct rwnx_vif *vif, atomic_t *drv_conn_state, int state){ + spin_lock_bh(&vif->conn_state_lock); if((int)atomic_read(drv_conn_state) != state){ AICWFDBG(LOGDEBUG, "%s drv_conn_state:%p %s --> %s \r\n", __func__, drv_conn_state, @@ -1297,6 +1316,7 @@ void rwnx_set_conn_state(atomic_t *drv_conn_state, int state){ atomic_set(drv_conn_state, state); } + spin_unlock_bh(&vif->conn_state_lock); } @@ -1357,7 +1377,7 @@ static int rwnx_open(struct net_device *dev) } set_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags); - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED); AICWFDBG(LOGDEBUG, "%s rwnx_vif->drv_flags:%d\r\n", __func__, (int)rwnx_vif->drv_flags); @@ -1448,19 +1468,20 @@ static int rwnx_open(struct net_device *dev) #if defined(CONFIG_RWNX_MON_RXFILTER) rwnx_send_set_filter(rwnx_hw, (FIF_BCN_PRBRESP_PROMISC | FIF_OTHER_BSS | FIF_PSPOLL | FIF_PROBE_REQ)); #endif - } - //netif_carrier_off(dev); - #if defined(CONFIG_RWNX_MON_XMIT) - netif_carrier_on(dev); - AICWFDBG(LOGINFO, "monitor xmit: netif_carrier_on\n"); - #endif + #if defined(CONFIG_RWNX_MON_XMIT) + netif_carrier_on(dev); + AICWFDBG(LOGINFO, "monitor xmit: netif_carrier_on\n"); + #endif + } #ifdef CONFIG_BR_SUPPORT netdev_br_init(dev); #endif /* CONFIG_BR_SUPPORT */ - //netif_carrier_off(dev); + if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MONITOR) + netif_carrier_off(dev); + netif_start_queue(dev); return error; @@ -1505,7 +1526,7 @@ static int rwnx_close(struct net_device *dev) test_counter--; if(test_counter == 0){ AICWFDBG(LOGERROR, "%s connecting or disconnecting, not finish\r\n", __func__); - //WARN_ON(1); + WARN_ON(1); break; } } @@ -1565,7 +1586,7 @@ static int rwnx_close(struct net_device *dev) RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT){ test_counter = waiting_counter; if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED){ - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); rwnx_send_sm_disconnect_req(rwnx_hw, rwnx_vif, 3); while (atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING) { AICWFDBG(LOGDEBUG, "%s wifi is disconnecting, waiting 100ms for state to stable\r\n", __func__); @@ -1655,14 +1676,16 @@ static int rwnx_close(struct net_device *dev) if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801 || ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81 || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2)&& testmode == 0)) { + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N)&& testmode == 0)) { #endif // Set parameters to firmware rwnx_send_me_config_req(rwnx_hw); // Set channel parameters to firmware - rwnx_send_me_chan_config_req(rwnx_hw, country_code); + rwnx_send_me_chan_config_req(rwnx_hw, (char *)rwnx_hw->wiphy->regd->alpha2); #if defined(AICWF_USB_SUPPORT) } #endif @@ -1972,13 +1995,19 @@ static struct rwnx_vif *rwnx_interface_add(struct rwnx_hw *rwnx_hw, #if LINUX_VERSION_CODE > KERNEL_VERSION(5, 17, 0) unsigned char mac_addr[6]; memcpy(mac_addr, rwnx_hw->wiphy->perm_addr, ETH_ALEN); - mac_addr[5] ^= vif_idx; + if (vif_idx > 0) { + mac_addr[0] |= 0x02; + mac_addr[0] ^= (vif_idx << 2); + } //memcpy(ndev->dev_addr, mac_addr, ETH_ALEN); eth_hw_addr_set(ndev, mac_addr); memcpy(vif->wdev.address, mac_addr, ETH_ALEN); #else memcpy(ndev->dev_addr, rwnx_hw->wiphy->perm_addr, ETH_ALEN); - ndev->dev_addr[5] ^= vif_idx; + if (vif_idx > 0) { + ndev->dev_addr[0] |= 0x02; + ndev->dev_addr[0] ^= (vif_idx << 2); + } memcpy(vif->wdev.address, ndev->dev_addr, ETH_ALEN); #endif } @@ -2015,6 +2044,8 @@ static struct rwnx_vif *rwnx_interface_add(struct rwnx_hw *rwnx_hw, spin_unlock_bh(&rwnx_hw->cb_lock); rwnx_hw->avail_idx_map &= ~BIT(vif_idx); + spin_lock_init(&vif->conn_state_lock); + return vif; err: @@ -2093,49 +2124,92 @@ void aicwf_p2p_alive_timeout(struct timer_list *t) } #ifdef CONFIG_DYNAMIC_PERPWR -void rssi_update_txpwrloss(struct rwnx_sta *sta, s8_l rssi) +static int custom_abs_diff(int a, int b) { + int diff = a - b; + return (diff < 0) ? -diff : diff; +} + +void rssi_update_txpwrloss(struct rwnx_sta *sta, s8_l rssi, struct rwnx_vif *vif) { int rssi_avg; + uint8_t r_idx; + bool lp_freq = false; + struct rwnx_hw *rwnx_hw = vif->rwnx_hw; + unsigned long current_jiffies = jiffies; + unsigned long elapsed_time; + + r_idx = get_ccode_region(rwnx_hw->wiphy->regd->alpha2); + //printk("r_idx: %d, ap_freq: %d\n", r_idx, vif->ap.ap_freq); + if ((r_idx == REGIONS_ETSI || r_idx == REGIONS_DEFAULT) && vif->ap.ap_freq >= 5735) + lp_freq = true; rssi_avg = (sta->rssi_save + rssi) / 2; sta->rssi_save = rssi_avg; //printk("New RSSI: %d, Average RSSI: %d\n", rssi, rssi_avg); - if(rssi_avg > RSSI_THD_0) { - if (sta->per_pwrloss != PWR_LOSS_LVL0) { - if ((jiffies_to_msecs(jiffies - sta->last_jiffies) < PWR_DELAY_TIME) && (sta->per_pwrloss >= PWR_LOSS_LVL0)) { + elapsed_time = jiffies_to_msecs(current_jiffies - sta->last_jiffies); + if (elapsed_time < PWR_FAST_SWITCH_PROTECT_TIME) { + if (custom_abs_diff(rssi_avg, sta->rssi_save) < RSSI_HYSTERESIS_THRESHOLD) { + return; + } + } + + if (sta->per_pwrloss == rwnx_hw->pwrth.pwr_loss_lvl_0 && + rssi_avg > (rwnx_hw->pwrth.rssi_thd_0 - RSSI_HYSTERESIS_OFFSET)) { + return; + } else if (sta->per_pwrloss == rwnx_hw->pwrth.pwr_loss_lvl_1 && + ((rssi_avg > (rwnx_hw->pwrth.rssi_thd_1 - RSSI_HYSTERESIS_OFFSET)) && + (rssi_avg < (rwnx_hw->pwrth.rssi_thd_0 + RSSI_HYSTERESIS_OFFSET)))) { + return; + } else if (sta->per_pwrloss == rwnx_hw->pwrth.pwr_loss_lvl_2 && + ((rssi_avg > (rwnx_hw->pwrth.rssi_thd_2 - RSSI_HYSTERESIS_OFFSET)) && + (rssi_avg < (rwnx_hw->pwrth.rssi_thd_1 + RSSI_HYSTERESIS_OFFSET)))) { + return; + } + + if(rssi_avg > rwnx_hw->pwrth.rssi_thd_0) { + if (sta->per_pwrloss != rwnx_hw->pwrth.pwr_loss_lvl_0) { + if (lp_freq) { + //printk("lp_freq p1\n"); + return; + } + if ((jiffies_to_msecs(jiffies - sta->last_jiffies) < PWR_DELAY_TIME) && (sta->per_pwrloss >= rwnx_hw->pwrth.pwr_loss_lvl_0)) { //printk("delay p1\n"); return; } schedule_work(&sta->per_pwr_work); - sta->per_pwrloss = PWR_LOSS_LVL0; + sta->per_pwrloss = rwnx_hw->pwrth.pwr_loss_lvl_0; sta->last_jiffies = jiffies; } - } else if ((rssi_avg > RSSI_THD_1) && (rssi_avg <= RSSI_THD_0)) { - if (sta->per_pwrloss != PWR_LOSS_LVL1) { - if ((jiffies_to_msecs(jiffies - sta->last_jiffies) < PWR_DELAY_TIME) && (sta->per_pwrloss >= PWR_LOSS_LVL1)) { + } else if ((rssi_avg > rwnx_hw->pwrth.rssi_thd_1) && (rssi_avg <= rwnx_hw->pwrth.rssi_thd_0)) { + if (sta->per_pwrloss != rwnx_hw->pwrth.pwr_loss_lvl_1) { + if (lp_freq) { + //printk("lp_freq p2\n"); + return; + } + if ((jiffies_to_msecs(jiffies - sta->last_jiffies) < PWR_DELAY_TIME) && (sta->per_pwrloss >= rwnx_hw->pwrth.pwr_loss_lvl_1)) { //printk("delay p2\n"); return; } schedule_work(&sta->per_pwr_work); - sta->per_pwrloss = PWR_LOSS_LVL1; + sta->per_pwrloss = rwnx_hw->pwrth.pwr_loss_lvl_1; sta->last_jiffies = jiffies; } - } else if ((rssi_avg > RSSI_THD_2) && (rssi_avg <= RSSI_THD_1)) { - if (sta->per_pwrloss != PWR_LOSS_LVL2) { - if ((jiffies_to_msecs(jiffies - sta->last_jiffies) < PWR_DELAY_TIME) && (sta->per_pwrloss >= PWR_LOSS_LVL2)) { + } else if ((rssi_avg > rwnx_hw->pwrth.rssi_thd_2) && (rssi_avg <= rwnx_hw->pwrth.rssi_thd_1)) { + if (sta->per_pwrloss != rwnx_hw->pwrth.pwr_loss_lvl_2) { + if ((jiffies_to_msecs(jiffies - sta->last_jiffies) < PWR_DELAY_TIME) && (sta->per_pwrloss >= rwnx_hw->pwrth.pwr_loss_lvl_2)) { //printk("delay p3\n"); return; } schedule_work(&sta->per_pwr_work); - sta->per_pwrloss = PWR_LOSS_LVL2; + sta->per_pwrloss = rwnx_hw->pwrth.pwr_loss_lvl_2; sta->last_jiffies = jiffies; } - } else if (rssi_avg <= RSSI_THD_2) { - if (sta->per_pwrloss != PWR_LOSS_LVL3) { + } else if (rssi_avg <= rwnx_hw->pwrth.rssi_thd_2) { + if (sta->per_pwrloss != rwnx_hw->pwrth.pwr_loss_lvl_3) { schedule_work(&sta->per_pwr_work); - sta->per_pwrloss = PWR_LOSS_LVL3; + sta->per_pwrloss = rwnx_hw->pwrth.pwr_loss_lvl_3; sta->last_jiffies = jiffies; } } @@ -2151,15 +2225,16 @@ void aicwf_txpwer_per_sta_worker(struct work_struct *work) } #endif -#ifdef CONFIG_DYNAMIC_PWR void set_txpwrloss_ctrl(struct rwnx_hw *rwnx_hw, s8 value) { AICWFDBG(LOGINFO, "set_txpwrloss_ctrl: %d\n", value); set_txpwr_loss_ofst(value); if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW) { + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN) { rwnx_send_txpwr_lvl_req(rwnx_hw); - } else if ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81)) { + } else if ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81) || + (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N)) { rwnx_send_txpwr_lvl_v3_req(rwnx_hw); } else if ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2) || (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2)) { @@ -2167,6 +2242,7 @@ void set_txpwrloss_ctrl(struct rwnx_hw *rwnx_hw, s8 value) } } +#ifdef CONFIG_DYNAMIC_PWR void aicwf_pwrloss_worker(struct work_struct *work) { struct rwnx_hw *rwnx_hw; @@ -2231,6 +2307,7 @@ static void aicwf_pwrloss_timer(struct timer_list *t) struct rwnx_hw *rwnx_hw; #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) + struct rwnx_vif *rwnx_vif; rwnx_vif = (struct rwnx_vif *)data; rwnx_hw = rwnx_vif->rwnx_hw; #elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0) @@ -2243,6 +2320,76 @@ static void aicwf_pwrloss_timer(struct timer_list *t) return; } +#endif +#ifdef CONFIG_TEMP_CONTROL +void aicwf_tcloss_worker(struct work_struct *work) +{ + struct rwnx_hw *rwnx_hw; + s8_l t; + s8_l temp = 0; + int ret = 0; + + rwnx_hw = container_of(work, struct rwnx_hw, tc_work); + if (!temp_control) { + if (rwnx_hw->tc_range != 0) { + set_txpwrloss_ctrl(rwnx_hw, 0); + } + mod_timer(&rwnx_hw->tc_timer, jiffies + msecs_to_jiffies(TEMP_GET_INTERVAL)); + return; + } + ret = rwnx_send_get_temp_req(rwnx_hw, &temp); + if(ret < 0) { + AICWFDBG(LOGINFO, "rwnx_send_get_temp_req: %d\n", ret); + return; + } + AICWFDBG(LOGINFO, "%s: temp :%d range : %d\n", __func__, temp, rwnx_hw->tc_range); + if(temp > TEMP_THD_0) { + if (rwnx_hw->tc_range != TC_LOSS_LVL0) { + set_txpwrloss_ctrl(rwnx_hw, TC_LOSS_LVL0); + rwnx_hw->tc_range = TC_LOSS_LVL0; + } + } else if ((temp > TEMP_THD_1) && (temp <= TEMP_THD_0)) { + if (rwnx_hw->tc_range != TC_LOSS_LVL1) { + set_txpwrloss_ctrl(rwnx_hw, TC_LOSS_LVL1); + rwnx_hw->tc_range = TC_LOSS_LVL1; + } + } else if ((temp > TEMP_THD_2) && (temp <= TEMP_THD_1)) { + if (rwnx_hw->tc_range != TC_LOSS_LVL2) { + set_txpwrloss_ctrl(rwnx_hw, TC_LOSS_LVL2); + rwnx_hw->tc_range = TC_LOSS_LVL2; + } + } else if (temp <= TEMP_THD_2) { + if (rwnx_hw->tc_range != TC_LOSS_LVL3) { + set_txpwrloss_ctrl(rwnx_hw, TC_LOSS_LVL3); + rwnx_hw->tc_range = TC_LOSS_LVL3; + } + } + mod_timer(&rwnx_hw->tc_timer, jiffies + msecs_to_jiffies(TEMP_GET_INTERVAL)); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) +static void aicwf_tcloss_timer(ulong data) +#else +static void aicwf_tcloss_timer(struct timer_list *t) +#endif +{ + struct rwnx_hw *rwnx_hw; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) + struct rwnx_vif *rwnx_vif; + rwnx_vif = (struct rwnx_vif *)data; + rwnx_hw = rwnx_vif->rwnx_hw; +#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0) + rwnx_hw = from_timer(rwnx_hw, t, tc_timer); +#else + rwnx_hw = timer_container_of(rwnx_hw, t, tc_timer); +#endif + if (!work_pending(&rwnx_hw->tc_work)) + schedule_work(&rwnx_hw->tc_work); + return; + +} + #endif /********************************************************************* @@ -2325,7 +2472,8 @@ static struct wireless_dev *rwnx_virtual_interface_add(struct rwnx_hw *rwnx_hw, rwnx_hw->avail_idx_map &= ~BIT(vif_idx); memcpy(vif->wdev.address, rwnx_hw->wiphy->perm_addr, ETH_ALEN); - vif->wdev.address[5] ^= vif_idx; + vif->wdev.address[0] |= 0x02; + vif->wdev.address[0] ^= (vif_idx << 2); AICWFDBG(LOGERROR, "p2p dev addr=%x %x %x %x %x %x\n", vif->wdev.address[0], vif->wdev.address[1], \ vif->wdev.address[2], vif->wdev.address[3], vif->wdev.address[4], vif->wdev.address[5]); @@ -2752,6 +2900,11 @@ static int rwnx_cfg80211_scan(struct wiphy *wiphy, return -EBUSY; } + if(g_rwnx_plat->wait_disconnect_cb == true){ + AICWFDBG(LOGERROR, "%s wait usb disconnect return busy\r\n", __func__); + return -EBUSY; + } + #ifndef CONFIG_STA_SCAN_WHEN_P2P_WORKING if (rwnx_hw->p2p_working && RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_P2P_CLIENT && !rwnx_send_check_p2p(request)) { @@ -2837,6 +2990,25 @@ static int rwnx_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, case WLAN_CIPHER_SUITE_AES_CMAC: cipher = MAC_CIPHER_BIP_CMAC_128; break; + case WLAN_CIPHER_SUITE_GCMP: + cipher = MAC_CIPHER_GCMP_128; + break; + case WLAN_CIPHER_SUITE_GCMP_256: + cipher = MAC_CIPHER_GCMP_256; + break; + case WLAN_CIPHER_SUITE_CCMP_256: + cipher = MAC_CIPHER_CCMP_256; + break; + case WLAN_CIPHER_SUITE_BIP_GMAC_128: + cipher = MAC_CIPHER_BIP_GMAC_128; + break; + case WLAN_CIPHER_SUITE_BIP_GMAC_256: + cipher = MAC_CIPHER_BIP_GMAC_256; + break; + case WLAN_CIPHER_SUITE_BIP_CMAC_256: + cipher = MAC_CIPHER_BIP_CMAC_256; + break; + case WLAN_CIPHER_SUITE_SMS4: { // Need to reverse key order @@ -3007,9 +3179,9 @@ static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, #endif if(rwnx_vif->sta.is_roam){ - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_ROAMING); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_ROAMING); }else{ - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTING); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTING); } @@ -3128,7 +3300,7 @@ static int rwnx_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTING|| atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_ROAMING){ - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); #ifdef CONFIG_USE_WIRELESS_EXT memset(rwnx_hw->wext_essid, 0, 33); @@ -3140,7 +3312,7 @@ static int rwnx_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, else{ cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0, reason_code?reason_code:WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC); - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED); rwnx_external_auth_disable(rwnx_vif); return 0; } @@ -3382,7 +3554,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy, #ifdef CONFIG_BAND_STEERING struct tmp_feature_sta *f_sta = &rwnx_hw->feature_table[rwnx_vif->ap.tmp_sta_idx]; AICWFDBG(LOGSTEER, "usb %s idx: %d, supp_band: %d\n ", __func__, rwnx_vif->ap.tmp_sta_idx, f_sta->supported_band); - if (rwnx_vif->ap.tmp_sta_idx < NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX) + if (rwnx_vif->ap.tmp_sta_idx < (NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX) - 1) rwnx_vif->ap.tmp_sta_idx++; else rwnx_vif->ap.tmp_sta_idx = 0; @@ -3923,6 +4095,7 @@ static int rwnx_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, rwnx_vif->ap.freq = ((settings->chandef).chan)->center_freq; rwnx_vif->ap.tmp_sta_idx = 0; #endif + rwnx_vif->ap.ap_freq = ((settings->chandef).chan)->center_freq; sta = &rwnx_hw->sta_table[apm_start_cfm.bcmc_idx]; sta->valid = true; sta->aid = 0; @@ -3991,6 +4164,7 @@ static int rwnx_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, aicwf_nl_hook(rwnx_vif, rwnx_vif->ap.band, rwnx_vif->rwnx_hw->iface_idx); INIT_WORK(&rwnx_vif->steer_work, aicwf_steering_work); +#if 0 for (int i = 0; i < MAX_PENDING_PROBES; i++) { rwnx_vif->pb_pool[i].in_use = false; INIT_WORK(&rwnx_vif->pb_pool[i].rsp_work, rwnx_probersp_work); @@ -4000,7 +4174,8 @@ static int rwnx_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, AICWFDBG(LOGERROR, "%s create rsp_wq fail\n", __func__); return -ENOBUFS; } - rwnx_vif->ap.start = true; +#endif + rwnx_vif->ap.start = true; mod_timer(&rwnx_vif->steer_timer, jiffies + msecs_to_jiffies(STEER_UPFATE_TIME)); } #endif @@ -4100,8 +4275,10 @@ static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) #endif } cancel_work_sync(&rwnx_vif->steer_work); +#if 0 flush_workqueue(rwnx_vif->rsp_wq); destroy_workqueue(rwnx_vif->rsp_wq); +#endif #endif if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) @@ -4333,6 +4510,28 @@ int radio_idx, return res; } +static int rwnx_cfg80211_get_tx_power(struct wiphy *wiphy, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + struct wireless_dev *wdev, +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) +int radio_idx, +unsigned int changed, +#endif + int *mbm) +{ + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) + struct wireless_dev *wdev = NULL; + #endif + //struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); + //struct rwnx_vif *vif; + s8 pwr = 0; + int res = 0; + + *mbm = get_txpwr_max(pwr); + + return res; +} /** * @set_power_mgmt: set the power save to one of those two modes: @@ -5071,6 +5270,7 @@ int rwnx_cfg80211_channel_switch(struct wiphy *wiphy, vif->ap.band = (enum band_type)((params->chandef).chan)->band; vif->ap.freq = ((params->chandef).chan)->center_freq; #endif + vif->ap.ap_freq = ((params->chandef).chan)->center_freq; end: return error; @@ -6231,7 +6431,7 @@ static struct cfg80211_ops rwnx_cfg80211_ops = { .set_wiphy_params = rwnx_cfg80211_set_wiphy_params, .set_txq_params = rwnx_cfg80211_set_txq_params, .set_tx_power = rwnx_cfg80211_set_tx_power, -// .get_tx_power = rwnx_cfg80211_get_tx_power, + .get_tx_power = rwnx_cfg80211_get_tx_power, .set_power_mgmt = rwnx_cfg80211_set_power_mgmt, .get_station = rwnx_cfg80211_get_station, .remain_on_channel = rwnx_cfg80211_remain_on_channel, @@ -6296,8 +6496,34 @@ static void rwnx_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) { struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); + const char *alpha2 = request->alpha2; + enum nl80211_reg_initiator initiator = request->initiator; - printk("%s Enter\r\n", __func__); + int delta_min = 100; + ktime_t now = ktime_get(); + + AICWFDBG(LOGINFO, "%s\n", __func__); + + if (!rwnx_hw->mod_params->custregd) { + AICWFDBG(LOGINFO, "regulatory domain set to %c%c, initiator: %d\n", alpha2[0], alpha2[1], initiator); + + if (rwnx_hw->last_alpha2[0]) { + s64 delta = ktime_ms_delta(now, rwnx_hw->last_time); + if (delta < 0 || delta > INT_MAX) + delta = delta_min + 1; + if (delta < delta_min) { + AICWFDBG(LOGDEBUG, "suspicious rapid reg change: %s -> %s\n", rwnx_hw->last_alpha2, request->alpha2); + return; + } + } + + regulatory_hint(wiphy, alpha2); + memcpy(rwnx_hw->last_alpha2, request->alpha2, 2); + rwnx_hw->last_time = now; + + if (testmode == 0) + rwnx_send_me_chan_config_req(rwnx_hw, &request->alpha2[0]); + } // For now trust all initiator #ifdef CONFIG_RADAR_OR_IR_DETECT @@ -6310,9 +6536,11 @@ static void rwnx_reg_notifier(struct wiphy *wiphy, if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801 || ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81 || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && testmode == 0)){ + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) && testmode == 0)){ rwnx_send_me_chan_config_req(rwnx_hw, &request->alpha2[0]); } } @@ -8304,7 +8532,11 @@ static void system_config(struct rwnx_hw *rwnx_hw) }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){ system_config_8800dc(rwnx_hw); - } + } else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) { + system_config_8800d80n(rwnx_hw); + } else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN) { + system_config_8800dln(rwnx_hw); + } } static int wdt_config(struct rwnx_hw *rwnx_hw) @@ -8459,6 +8691,9 @@ int rwnx_ic_system_init(struct rwnx_hw *rwnx_hw){ return -1; #endif }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){ + if (system_config_8800d80(rwnx_hw)) { + return -1; + } rwnx_plat_userconfig_load_8800d80(rwnx_hw); #ifdef CONFIG_POWER_LIMIT rwnx_plat_powerlimit_load_8800d80(rwnx_hw); @@ -8469,6 +8704,30 @@ int rwnx_ic_system_init(struct rwnx_hw *rwnx_hw){ #ifdef CONFIG_POWER_LIMIT rwnx_plat_powerlimit_load_8800d80x2(rwnx_hw); #endif + } else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N){ + system_config(rwnx_hw); + if (rwnx_platform_on(rwnx_hw, NULL)) + return -1; + if (testmode == 0) { + if (start_from_bootrom(rwnx_hw)) { + return -1; + } + } else { + int ret; + AICWFDBG(LOGINFO, "%s exec rftest bin\n", __func__); + ret = aicwf_plat_rftest_exec_8800d80n(rwnx_hw); + if (ret) { + AICWFDBG(LOGERROR, "exec rftest bin fail: %d\n", ret); + return ret; + } + } + } else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN){ + system_config(rwnx_hw); + if (rwnx_platform_on(rwnx_hw, NULL)) + return -1; + if (start_from_bootrom(rwnx_hw)) { + return -1; + } } return 0; @@ -8508,6 +8767,12 @@ int rwnx_ic_rf_init(struct rwnx_hw *rwnx_hw){ rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ if ((ret = aicwf_set_rf_config_8800d80x2(rwnx_hw, &cfm))) return -1; + } else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) { + if ((ret = aicwf_set_rf_config_8800d80n(rwnx_hw, &cfm))) + return -1; + } else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN) { + if ((ret = aicwf_set_rf_config_8800dln(rwnx_hw, &cfm))) + return -1; } #ifdef CONFIG_5M10M rwnx_send_vendor_hwconfig_req(rwnx_hw, hwconfig_id, param, NULL); @@ -8530,7 +8795,6 @@ void aic_ipc_setting(struct rwnx_vif *rwnx_vif){ extern int get_adap_test(void); extern void *aicwf_prealloc_txq_alloc(size_t size); -extern int aicwf_vendor_init(struct wiphy *wiphy); extern char default_ccode[]; int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data) { @@ -8643,6 +8907,9 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || rwnx_hw->scan_ie.addr = NULL; + rwnx_hw->last_time = ktime_get(); + memset(rwnx_hw->last_alpha2, 0, sizeof(rwnx_hw->last_alpha2)); + for (i = 0; i < NX_VIRT_DEV_MAX + nx_remote_sta_max; i++){ rwnx_hw->avail_idx_map |= BIT(i); } @@ -8695,7 +8962,8 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || #ifdef USE_5G if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){ + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN){ ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, 0, 0, rwnx_hw->fwlog_en, &set_start_cfm); } else { ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, 0, CO_BIT(5), rwnx_hw->fwlog_en, &set_start_cfm); @@ -8703,7 +8971,8 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || #else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81 || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N){ ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, 0, CO_BIT(5), rwnx_hw->fwlog_en, &set_start_cfm); } else { ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, get_hardware_info(), feature.hwinfo, rwnx_hw->fwlog_en, &set_start_cfm); @@ -8721,12 +8990,17 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || memcpy(wiphy->fw_version, fw_version.fw_version, fw_version.fw_version_len>32? 32 : fw_version.fw_version_len>32); AICWFDBG(LOGINFO, "Firmware Version: %s\r\n", fw_version.fw_version); - wiphy->bands[NL80211_BAND_2GHZ] = &rwnx_band_2GHz; -//#ifdef USE_5G - if(rwnx_hw->band_5g_support){ - wiphy->bands[NL80211_BAND_5GHZ] = &rwnx_band_5GHz; + wiphy->bands[NL80211_BAND_2GHZ] = &rwnx_band_2GHz; + for(i = 0; i < wiphy->bands[NL80211_BAND_2GHZ]->n_channels; i++) { + wiphy->bands[NL80211_BAND_2GHZ]->channels[i].flags = 0; } -//#endif + if (rwnx_hw->band_5g_support) { + wiphy->bands[NL80211_BAND_5GHZ] = &rwnx_band_5GHz; + for(i = 0; i < wiphy->bands[NL80211_BAND_5GHZ]->n_channels; i++) { + wiphy->bands[NL80211_BAND_5GHZ]->channels[i].flags = 0; + } + } + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | @@ -8859,9 +9133,11 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801 || ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81 || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && testmode == 0)) { + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) && testmode == 0)) { rwnx_send_me_config_req(rwnx_hw); } @@ -8878,21 +9154,17 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || goto err_register_wiphy; } - if ((rwnx_hw->usbdev->vid == 0x2604 && rwnx_hw->usbdev->pid == 0x001f) - || (rwnx_hw->usbdev->vid == 0x2604 && rwnx_hw->usbdev->pid == 0x0020)) { - rwnx_send_pwm_init_req(rwnx_hw, 8, 1, 1, 400000, 400000, 100, 1, 1, 1); - rwnx_send_pwm_deinit_req(rwnx_hw, 8, 1, 1, 1); - } - /* Update regulatory (if needed) and set channel parameters to firmware (must be done after WiPHY registration) */ rwnx_custregd(rwnx_hw, wiphy); if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801 || ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81 || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && testmode == 0)) { + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) && testmode == 0)) { rwnx_send_me_chan_config_req(rwnx_hw, default_ccode); } *platform_data = rwnx_hw; @@ -8974,6 +9246,30 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || mod_timer(&rwnx_hw->pwrloss_timer, jiffies + msecs_to_jiffies(RSSI_GET_INTERVAL)); #endif +#ifdef CONFIG_TEMP_CONTROL + rwnx_hw->tc_range = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + init_timer(&rwnx_hw->tc_timer); + rwnx_hw->tc_timer.data = (ulong) vif; + rwnx_hw->tc_timer.function = aicwf_tcloss_timer; +#else + timer_setup(&rwnx_hw->tc_timer, aicwf_tcloss_timer, 0); +#endif + INIT_WORK(&rwnx_hw->tc_work, aicwf_tcloss_worker); + mod_timer(&rwnx_hw->tc_timer, jiffies + msecs_to_jiffies(TEMP_GET_INTERVAL)); +#endif + + +#ifdef CONFIG_DYNAMIC_PERPWR + rwnx_hw->pwrth.rssi_thd_0 = RSSI_THD_0; + rwnx_hw->pwrth.rssi_thd_1 = RSSI_THD_1; + rwnx_hw->pwrth.rssi_thd_2 = RSSI_THD_2; + rwnx_hw->pwrth.pwr_loss_lvl_0 = PWR_LOSS_LVL0; + rwnx_hw->pwrth.pwr_loss_lvl_1 = PWR_LOSS_LVL1; + rwnx_hw->pwrth.pwr_loss_lvl_2 = PWR_LOSS_LVL2; + rwnx_hw->pwrth.pwr_loss_lvl_3 = PWR_LOSS_LVL3; +#endif + #ifdef CONFIG_FOR_IPCAM if(!testmode && !get_adap_test()) { aic_ipc_setting(vif); @@ -9044,14 +9340,19 @@ void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw) del_timer_sync(&rwnx_hw->pwrloss_timer); #endif } - cancel_work_sync(&rwnx_hw->pwrloss_work); #endif +#ifdef CONFIG_TEMP_CONTROL + if(timer_pending(&rwnx_hw->tc_timer)){ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)) + timer_delete_sync(&rwnx_hw->tc_timer); +#else + del_timer_sync(&rwnx_hw->tc_timer); +#endif + } + cancel_work_sync(&rwnx_hw->tc_work); +#endif - if ((rwnx_hw->usbdev->vid == 0x2604 && rwnx_hw->usbdev->pid == 0x001f) - || (rwnx_hw->usbdev->vid == 0x2604 && rwnx_hw->usbdev->pid == 0x0020)) { - rwnx_set_pwm_tbl(rwnx_hw); - } spin_lock_bh(&rwnx_hw->defrag_lock); if (!list_empty(&rwnx_hw->defrag_list)) { diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_main.h b/drivers/aic8800/aic8800_fdrv/rwnx_main.h index ad4e2fc..d9081f6 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_main.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_main.h @@ -37,6 +37,21 @@ extern u8 chip_mcu_id; #define PWR_LOSS_LVL3 (0)//(2) //RSSI = TEMP_THD_0 +#define TC_LOSS_LVL1 (-5) //TEMP_THD_1 < TEMP <= TEMP_THD_0 +#define TC_LOSS_LVL2 (-2) //TEMP_THD_2 < TEMP <= TEMP_THD_1 +#define TC_LOSS_LVL3 (0) //TEMP <= TEMP_THD_2 +#endif struct rwnx_sta *rwnx_retrieve_sta(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, u8 *addr, @@ -53,13 +68,56 @@ void aicwf_steering_timeout(struct timer_list *t); #endif #ifdef CONFIG_DYNAMIC_PERPWR -void rssi_update_txpwrloss(struct rwnx_sta *sta, s8_l rssi); +void rssi_update_txpwrloss(struct rwnx_sta *sta, s8_l rssi, struct rwnx_vif *vif); void aicwf_txpwer_per_sta_worker(struct work_struct *work); #endif -#ifdef CONFIG_DYNAMIC_PWR + void set_txpwrloss_ctrl(struct rwnx_hw *rwnx_hw, s8 value); +#ifdef CONFIG_DYNAMIC_PWR void aicwf_pwrloss_worker(struct work_struct *work); #endif +#ifdef CONFIG_TEMP_CONTROL +void aicwf_tcloss_worker(struct work_struct *work); +#endif +void rwnx_skb_align_8bytes(struct sk_buff *skb); +void rwnx_frame_parser(char* tag, char* data, unsigned long len); +void rwnx_update_mesh_power_mode(struct rwnx_vif *vif); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) +void aicwf_p2p_alive_timeout(ulong data); +#else +void aicwf_p2p_alive_timeout(struct timer_list *t); +#endif +int rwnx_send_check_p2p(struct cfg80211_scan_request *param); +void apm_staloss_work_process(struct work_struct *work); +void apm_probe_sta_work_process(struct work_struct *work); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef); +#else +int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef); +#endif +int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev, + const u8 *peer, u64 *cookie); +void rwnx_cfg80211_mgmt_frame_register(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#else + struct wireless_dev *wdev, +#endif + u16 frame_type, bool reg); + +int rwnx_cfg80211_channel_switch(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_csa_settings *params); +int rwnx_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, + struct bss_parameters *params); +int rwnx_ic_system_init(struct rwnx_hw *rwnx_hw); +int rwnx_ic_rf_init(struct rwnx_hw *rwnx_hw); +void aic_ipc_setting(struct rwnx_vif *rwnx_vif); +u16 rwnx_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev); #endif /* _RWNX_MAIN_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.c b/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.c index 132b8ef..d386706 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.c @@ -55,6 +55,7 @@ struct rwnx_mod_params rwnx_mod_params = { COMMON_PARAM(mutx, true, true) COMMON_PARAM(mutx_on, true, true) COMMON_PARAM(use_80, true, true) +/* false: use crda(iw reg set CN); true: drive self-management(wifi_test wlan0 country_set CN) */ COMMON_PARAM(custregd, true, true) COMMON_PARAM(custchan, false, false) COMMON_PARAM(roc_dur_max, 500, 500) @@ -1781,6 +1782,8 @@ int rwnx_handle_dynparams(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 && rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 && rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 && + rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D80N && + rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800DLN && rwnx_hw->mod_params->he_mcs_map > IEEE80211_HE_MCS_SUPPORT_0_9){ rwnx_hw->mod_params->he_mcs_map = IEEE80211_HE_MCS_SUPPORT_0_9; } else { @@ -1791,6 +1794,7 @@ int rwnx_handle_dynparams(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 && rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 && rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 && + rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D80N && rwnx_hw->mod_params->use_80 == true){ rwnx_hw->mod_params->use_80 = false; } else { @@ -1836,28 +1840,33 @@ void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) // registration (in rwnx_set_wiphy_params()), so nothing has to be done here #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) - wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; - wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED; + wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; +#endif + if (!rwnx_hw->mod_params->custregd) + return; - if (!rwnx_hw->mod_params->custregd) - return; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) + wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED; - rtnl_lock(); + rtnl_lock(); #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) - if (regulatory_set_wiphy_regd_sync(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){ - wiphy_err(wiphy, "Failed to set custom regdomain\n"); - } + if (regulatory_set_wiphy_regd_sync(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){ + wiphy_err(wiphy, "Failed to set custom regdomain\n"); + } #else - if (regulatory_set_wiphy_regd_sync_rtnl(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){ - wiphy_err(wiphy, "Failed to set custom regdomain\n"); - } + if (regulatory_set_wiphy_regd_sync_rtnl(wiphy, getRegdomainFromRwnxDB(wiphy, default_ccode))){ + wiphy_err(wiphy, "Failed to set custom regdomain\n"); + } #endif - else{ - wiphy_err(wiphy,"\n" - "*******************************************************\n" - "** CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES **\n" - "*******************************************************\n"); - } - rtnl_unlock(); + + else{ + wiphy_err(wiphy,"\n" + "*******************************************************\n" + "** CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES **\n" + "*******************************************************\n"); + } + rtnl_unlock(); #endif + } + diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.h b/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.h index 64aa62d..5bc75b6 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.h @@ -71,6 +71,8 @@ struct ieee80211_regdomain *getRegdomainFromRwnxDB(struct wiphy *wiphy, struct ieee80211_regdomain *getRegdomainFromRwnxDBIndex(struct wiphy *wiphy, int index); +void rwnx_get_countrycode_channels(struct wiphy *wiphy, + struct ieee80211_regdomain *regdomain); #endif /* _RWNX_MOD_PARAM_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.c b/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.c index 3402681..b02a116 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.c @@ -28,6 +28,8 @@ #ifdef CONFIG_USE_WIRELESS_EXT #include "aicwf_wext_linux.h" #endif +#include "rwnx_msg_rx.h" + void rwnx_cfg80211_unlink_bss(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif); static int rwnx_freq_to_idx(struct rwnx_hw *rwnx_hw, int freq) @@ -789,13 +791,21 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw, #endif #ifdef CONFIG_USE_WIRELESS_EXT - if(rwnx_hw->wext_scan){ - list_for_each_entry(scan_re_wext, &rwnx_hw->wext_scanre_list, scanu_re_list) { - if (!memcmp(scan_re_wext->bss->bssid, bss->bssid, ETH_ALEN)) { - AICWFDBG(LOGDEBUG, "%s: BSSID already exists, no need to add again\r\n", __func__); - goto putbss; - } + if(rwnx_hw->wext_scan){ + if (!bss ) { + AICWFDBG(LOGERROR, "%s: Invalid BSS structure\n", __func__); + goto putbss; + } + list_for_each_entry(scan_re_wext, &rwnx_hw->wext_scanre_list, scanu_re_list) { + if (!scan_re_wext || !scan_re_wext->bss ) { + AICWFDBG(LOGDEBUG, "%s: Corrupted list entry detected\n", __func__); + continue; } + if (!memcmp(scan_re_wext->bss->bssid, bss->bssid, ETH_ALEN)) { + AICWFDBG(LOGDEBUG, "%s: BSSID already exists, no need to add again\r\n", __func__); + goto putbss; + } + } scan_re_wext = (struct scanu_result_wext *)vmalloc(sizeof(struct scanu_result_wext)); scan_re_wext->ind = (struct scanu_result_ind *)vmalloc(sizeof(struct scanu_result_ind)); scan_re_wext->payload = (u32_l *)vmalloc(sizeof(u32_l) * ind->length); @@ -811,7 +821,7 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw, INIT_LIST_HEAD(&scan_re_wext->scanu_re_list); list_add_tail(&scan_re_wext->scanu_re_list, &rwnx_hw->wext_scanre_list); return 0; - } + } #endif } @@ -1043,9 +1053,9 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, rwnx_vif->wep_auth_err = true; AICWFDBG(LOGINFO, "con ind wep_auth_err %d\n", rwnx_vif->wep_auth_err); } - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); }else{ - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); } @@ -1067,9 +1077,13 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, ind->assoc_rsp_ie_len, ind->status_code, GFP_ATOMIC); if (ind->status_code == 0) { - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); } else { - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); + if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED) { + AICWFDBG(LOGINFO, "%s roaming fail no roamed ind \r\n", __func__); + cfg80211_disconnected(dev, 0, NULL, 0, 1, GFP_ATOMIC); + } + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); rwnx_external_auth_disable(rwnx_vif); } AICWFDBG(LOGINFO, "%s cfg80211_connect_result pass, rwnx_vif->drv_conn_state:%d\r\n", __func__, (int)atomic_read(&rwnx_vif->drv_conn_state)); @@ -1078,7 +1092,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, if(ind->status_code != 0){ AICWFDBG(LOGINFO, "%s roaming fail to notify disconnect \r\n", __func__); cfg80211_disconnected(dev, 0, NULL, 0,1, GFP_ATOMIC); - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); rwnx_external_auth_disable(rwnx_vif); }else{ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) @@ -1116,7 +1130,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, , ind->assoc_rsp_ie_len , GFP_ATOMIC); #endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)*/ - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); } rwnx_vif->sta.is_roam = false; } @@ -1263,7 +1277,7 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw, //msleep(200); if (rwnx_vif->sta.is_roam == false) { - rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(rwnx_vif, &rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); } return 0; @@ -1577,6 +1591,68 @@ static inline int rwnx_rx_dbg_error_ind(struct rwnx_hw *rwnx_hw, return 0; } +struct fault_ctxt { + uint32_t reg_i[13]; + uint32_t SP; + uint32_t LR; + uint32_t PC; + uint32_t xPSR; + uint32_t PSP; + uint32_t MSP; + uint32_t EXC_RETURN; + uint32_t CONTROL; +}; + +static inline int rwnx_fw_panic_ind(struct rwnx_hw *rwnx_hw, + struct rwnx_cmd *cmd, + struct ipc_e2a_msg *msg) +{ + struct fw_panic_info_ind *ind = (struct fw_panic_info_ind *)msg->param; + uint8_t version[36]; + struct fault_ctxt fault; + uint32_t msp[64]; + uint8_t i; + memcpy(version, ind->info, 36); + version[35] = '\0'; + memcpy(&fault, &ind->info[36], sizeof(struct fault_ctxt)); + memcpy(msp, &ind->info[36+sizeof(struct fault_ctxt)], 64*4); + + printk("fw_panic: len=%d\n", ind->len); + printk("firmware: %s\n", version); + + for(i=0; i<13; i++) + printk("REG %d = [%x]\n", i, fault.reg_i[i]); + printk("SP = [%x]\n", fault.SP); + printk("LR = [%x]\n", fault.LR); + printk("PC = [%x]\n", fault.PC); + printk("PSP = [%x]\n", fault.PSP); + printk("xPSR = [%x]\n", fault.xPSR); + printk("EXC_RETURN = [%x]\n", fault.EXC_RETURN); + printk("CONTROL = [%x]\n", fault.CONTROL); + + printk("STACK:\n"); + for(i=0; i<64; i+=4) { + printk("%08x, %08x, %08x, %08x\n", msp[i], msp[i+1], msp[i+2], msp[i+3]); + } + + return 0; +} + +static inline int rwnx_fw_assert_ind(struct rwnx_hw *rwnx_hw, + struct rwnx_cmd *cmd, + struct ipc_e2a_msg *msg) +{ + struct fw_assert_info_ind *ind = (struct fw_assert_info_ind *)msg->param; + uint8_t buffer[256]; + + memcpy(buffer, ind->info, ind->len); + buffer[ind->len] = '\0'; + + printk("%s: %s\n", __func__, buffer); + + return 0; +} + #ifdef CONFIG_RWNX_FULLMAC static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = { @@ -1595,6 +1671,8 @@ static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = { [MSG_I(MM_PKTLOSS_IND)] = rwnx_rx_pktloss_notify_ind, [MSG_I(MM_APM_STALOSS_IND)] = rwnx_apm_staloss_ind, [MSG_I(MM_RADAR_DETECT_IND)] = rwnx_radar_detect_ind, + [MSG_I(MM_FW_PANIC_IND)] = rwnx_fw_panic_ind, + [MSG_I(MM_FW_ASSERT_IND)] = rwnx_fw_assert_ind, }; static msg_cb_fct scan_hdlrs[MSG_I(SCANU_MAX)] = { @@ -1669,12 +1747,14 @@ void rwnx_rx_handle_print(struct rwnx_hw *rwnx_hw, u8 *msg, u32 len) u8 *data_end = NULL; (void)data_end; + msg[len-1] = '\0'; + if (!rwnx_hw || !rwnx_hw->fwlog_en) { pr_err("FWLOG-OVFL: %s", msg); return; } - printk("FWLOG: %s", msg); + AICWFDBG(LOGFW, "%s", msg); #ifdef CONFIG_RWNX_DEBUGFS data_end = rwnx_hw->debugfs.fw_log.buf.dataend; diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.c b/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.c index 91b2a14..b977555 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.c @@ -205,6 +205,7 @@ void rwnx_cmd_free(struct rwnx_cmd *cmd){ spin_lock_irqsave(&cmd_array_lock, flags); cmd->used = 0; + cmd->flags = 0; AICWFDBG(LOGTRACE, "%s cmd_array[%d]:%p \r\n", __func__, cmd->array_id, cmd); spin_unlock_irqrestore(&cmd_array_lock, flags); } @@ -1150,6 +1151,34 @@ int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l * return (error); } +int rwnx_send_rf_config_v2_req(struct rwnx_hw *rwnx_hw, u16_l ofst, u8_l sel, u8_l *tbl, u16_l len) +{ + struct mm_set_rf_config_req *rf_config_req; + int error; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the MM_SET_RF_CONFIG_REQ message */ + rf_config_req = rwnx_msg_zalloc(MM_SET_RF_CONFIG_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_set_rf_config_req)); + + if (!rf_config_req) { + return -ENOMEM; + } + + rf_config_req->table_sel = sel; + rf_config_req->table_ofst = 0; + rf_config_req->table_num = 16; + rf_config_req->deft_page = ofst / 16; + + memcpy(rf_config_req->data, tbl, len); + + /* Send the MM_SET_RF_CONFIG_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, rf_config_req, 1, MM_SET_RF_CONFIG_CFM, NULL); + + return (error); +} + #ifdef RF_WRITE_FILE #define FW_PATH_MAX_LEN_RF 200 @@ -1271,6 +1300,9 @@ int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm * rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ rf_calib_req->cal_cfg_24g = 0x0f8f; rf_calib_req->cal_cfg_5g = 0x0f0f; + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N){ + rf_calib_req->cal_cfg_24g = 0x0f8f; + rf_calib_req->cal_cfg_5g = 0x0f0f; } rf_calib_req->param_alpha = 0x0c34c008; @@ -1444,6 +1476,9 @@ int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm * rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ rf_calib_req->cal_cfg_24g = 0x0f8f; rf_calib_req->cal_cfg_5g = 0x0f0f; + } else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N){ + rf_calib_req->cal_cfg_24g = 0x0f8f; + rf_calib_req->cal_cfg_5g = 0x0f0f; } rf_calib_req->param_alpha = 0x0c34c008; @@ -1494,21 +1529,36 @@ int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cf int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_get_sta_info_cfm *cfm) { struct mm_get_sta_info_req *get_info_req; + struct mm_get_sta_info_compat_req *get_info_compat_req; int error; - /* Build the MM_GET_STA_INFO_REQ message */ - get_info_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID, - sizeof(struct mm_get_sta_info_req)); + if(rwnx_hw->usbdev->chipid < PRODUCT_ID_AIC8800D81X2) { + /* Build the MM_GET_STA_INFO_REQ message */ + get_info_compat_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_get_sta_info_compat_req)); + if (!get_info_compat_req) { + return -ENOMEM; + } - if (!get_info_req) { - return -ENOMEM; + get_info_compat_req->sta_idx = sta_idx; + memcpy(get_info_compat_req->pattern, "sta", 3); + /* Send the MM_GET_STA_INFO_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, get_info_compat_req, 1, MM_GET_STA_INFO_CFM, cfm); + + } else { + /* Build the MM_GET_STA_INFO_REQ message */ + get_info_req = rwnx_msg_zalloc(MM_GET_STA_INFO_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_get_sta_info_req)); + + if (!get_info_req) { + return -ENOMEM; + } + + get_info_req->sta_idx = sta_idx; + + /* Send the MM_GET_STA_INFO_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, get_info_req, 1, MM_GET_STA_INFO_CFM, cfm); } - - get_info_req->sta_idx = sta_idx; - - /* Send the MM_GET_STA_INFO_REQ message to UMAC FW */ - error = rwnx_send_msg(rwnx_hw, get_info_req, 1, MM_GET_STA_INFO_CFM, cfm); - return error; }; @@ -1709,6 +1759,7 @@ int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, printk("get_chip_temp err=%d\n", error); } } + break; case CUSTOMIZED_FREQ_REQ: /* Build the CUSTOMIZED_FREQ_REQ message */ req5 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_customized_freq_req)); @@ -2386,7 +2437,8 @@ int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw) txpwr_lvl_v2->pwrlvl_11ax_2g4[i] -= txpwr_loss->loss_value_2g4; } - if ((testmode == 0) && (chip_sub_id == 0)) { + if ((rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800DLN) && + (testmode == 0) && (chip_sub_id == 0)) { txpwr_lvl_req->txpwr_lvl.enable = txpwr_lvl_v2->enable; txpwr_lvl_req->txpwr_lvl.dsss = txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]; // 11M txpwr_lvl_req->txpwr_lvl.ofdmlowrate_2g4= txpwr_lvl_v2->pwrlvl_11ax_2g4[4]; // MCS4 @@ -2753,6 +2805,45 @@ int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw) } } +int rwnx_send_txpwr_lvl_adj_v2_req(struct rwnx_hw *rwnx_hw) +{ + struct mm_set_txpwr_lvl_adj_req *txpwr_lvl_adj_req; + txpwr_lvl_adj_conf_v2_t txpwr_lvl_adj_v2_tmp; + txpwr_lvl_adj_conf_v2_t *txpwr_lvl_adj_v2; + int error; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the MM_SET_TXPWR_LVL_REQ message */ + txpwr_lvl_adj_req = rwnx_msg_zalloc(MM_SET_TXPWR_LVL_ADJ_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_set_txpwr_lvl_adj_req)); + + if (!txpwr_lvl_adj_req) { + return -ENOMEM; + } + + txpwr_lvl_adj_v2 = &txpwr_lvl_adj_v2_tmp; + + get_userconfig_txpwr_lvl_adj_v2_in_fdrv(txpwr_lvl_adj_v2); + + if (txpwr_lvl_adj_v2->enable == 0) { + rwnx_msg_free(rwnx_hw, txpwr_lvl_adj_req); + return 0; + } else { + AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_adj_v2->enable); + AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_1_4:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[0]); + AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_5_9:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[1]); + AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_10_13:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[2]); + + txpwr_lvl_adj_req->txpwr_lvl_adj_v2 = *txpwr_lvl_adj_v2; + + /* Send the MM_SET_TXPWR_LVL_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, txpwr_lvl_adj_req, 1, MM_SET_TXPWR_LVL_ADJ_CFM, NULL); + + return (error); + } +} + extern void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst); int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw) @@ -2839,6 +2930,8 @@ int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw) } else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x); + } else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) { + get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x); } if (txpwr_ofst2x->enable){ AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_ofst2x->enable); @@ -2922,6 +3015,53 @@ int rwnx_send_txpwr_ofst2x_v2_req(struct rwnx_hw *rwnx_hw) return (error); } +int rwnx_send_txpwr_ofst2x_v3_req(struct rwnx_hw *rwnx_hw) +{ + struct mm_set_txpwr_ofst_req *txpwr_ofst_req; + txpwr_ofst2x_conf_v3_t *txpwr_ofst2x_v3; + int error = 0; + int type, ch_grp; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the MM_SET_TXPWR_OFST_REQ message */ + txpwr_ofst_req = rwnx_msg_zalloc(MM_SET_TXPWR_OFST_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_set_txpwr_ofst_req)); + + if (!txpwr_ofst_req) { + return -ENOMEM; + } + + txpwr_ofst2x_v3 = &txpwr_ofst_req->txpwr_ofst2x_v3; + txpwr_ofst2x_v3->enable = 0; + for (type = 0; type < 3; type++) { + for (ch_grp = 0; ch_grp < 3; ch_grp++) { + txpwr_ofst2x_v3->pwrofst2x_tbl_2g4[type][ch_grp] = 0; + } + } + get_userconfig_txpwr_ofst2x_v3_in_fdrv(txpwr_ofst2x_v3); + if (txpwr_ofst2x_v3->enable){ + AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_ofst2x_v3->enable); + AICWFDBG(LOGINFO, "pwrofst2x 2.4g: [0]:11b, [1]:ofdm_highrate, [2]:ofdm_lowrate\n" + " chan=" "\t1-4" "\t5-9" "\t10-13"); + for (type = 0; type < 3; type++) { + AICWFDBG(LOGINFO, "\n [%d] =", type); + for (ch_grp = 0; ch_grp < 3; ch_grp++) { + AICWFDBG(LOGINFO, "\t%d", txpwr_ofst2x_v3->pwrofst2x_tbl_2g4[type][ch_grp]); + } + } + AICWFDBG(LOGINFO, "\n"); + + /* Send the MM_SET_TXPWR_OFST_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, txpwr_ofst_req, 1, MM_SET_TXPWR_OFST_CFM, NULL); + }else{ + AICWFDBG(LOGINFO, "%s:Do not use txpwr_ofst2x_v3\r\n", __func__); + rwnx_msg_free(rwnx_hw, txpwr_ofst_req); + } + + return (error); +} + int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter) { struct mm_set_filter_req *set_filter_req_param; @@ -3279,7 +3419,7 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par #if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL) struct aic_sta *sta = &rwnx_hw->aic_table[rwnx_vif->ap.aic_index]; printk("assoc_req idx %d, he: %d, vht: %d\n ", rwnx_vif->ap.aic_index, sta->he, sta->vht); - if (rwnx_vif->ap.aic_index < NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX) + if (rwnx_vif->ap.aic_index < (NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX - 1)) rwnx_vif->ap.aic_index++; else rwnx_vif->ap.aic_index = 0; @@ -3406,10 +3546,15 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par req->flags |= STA_MFP_CAPA; #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) - if (link_sta_params->opmode_notif_used) { - req->opmode = link_sta_params->opmode_notif_used; - req->flags |= STA_OPMOD_NOTIF; - } +#if LINUX_VERSION_CODE < HIGH_KERNEL_VERSION + if (params->opmode_notif_used) { + req->opmode = params->opmode_notif; +#else + if (params->link_sta_params.opmode_notif_used) { + req->opmode = params->link_sta_params.opmode_notif; +#endif//LINUX_VERSION_CODE < HIGH_KERNEL_VERSION + req->flags |= STA_OPMOD_NOTIF; + } #endif req->aid = cpu_to_le16(params->aid); @@ -5038,6 +5183,54 @@ int rwnx_send_cfg_rssi_req(struct rwnx_hw *rwnx_hw, u8 vif_index, int rssi_thold return rwnx_send_msg(rwnx_hw, req, 1, MM_CFG_RSSI_CFM, NULL); } +int rwnx_send_get_temp_req(struct rwnx_hw *rwnx_hw, s8_l *temp) +{ + struct mm_get_chip_temp_req *hwreq; + struct mm_set_vendor_swconfig_req *swreq; + struct mm_set_vendor_hwconfig_cfm hwcfm; + struct mm_set_vendor_swconfig_cfm swcfm; + int ret = 0; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){ + /* Build the CHIP_TEMP_GET_REQ message */ + hwreq = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_get_chip_temp_req)); + if (!hwreq) + return -ENOMEM; + hwreq->hwconfig_id = CHIP_TEMP_GET_REQ; + /* Send the MM_SET_VENDOR_HWCONFIG_REQ message to UMAC FW */ + ret = rwnx_send_msg(rwnx_hw, hwreq, 1, MM_SET_VENDOR_HWCONFIG_CFM, &hwcfm); + if (!ret) { + AICWFDBG(LOGINFO, "get_chip_temp degree=%d\n", hwcfm.chip_temp_cfm.degree); + *temp = hwcfm.chip_temp_cfm.degree; + } else { + AICWFDBG(LOGINFO, "get_chip_temp err=%d\n", ret); + return ret; + } + return ret; + } else if (rwnx_hw->usbdev->chipid >= PRODUCT_ID_AIC8800D80N) { + /* Build the TEMP_COMP_GET_REQ message */ + swreq = rwnx_msg_zalloc(MM_SET_VENDOR_SWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_vendor_swconfig_req)); + if (!swreq) { + AICWFDBG(LOGINFO, "%s msg_alloc fail\n", __func__); + return -ENOMEM; + } + swreq->swconfig_id = TEMP_COMP_GET_REQ; + + ret = rwnx_send_msg(rwnx_hw, swreq, 1, MM_SET_VENDOR_SWCONFIG_CFM, &swcfm); + if (!ret) { + AICWFDBG(LOGINFO, "status=%d, temp=%d\n", swcfm.temp_comp_get_cfm.status, swcfm.temp_comp_get_cfm.degree); + *temp = swcfm.temp_comp_get_cfm.degree; + } else { + AICWFDBG(LOGINFO, "%s msg_fail\n", __func__); + return ret; + } + } + return ret; +} + //#ifdef CONFIG_USB_BT int rwnx_send_reboot(struct rwnx_hw *rwnx_hw) { @@ -5049,70 +5242,9 @@ int rwnx_send_reboot(struct rwnx_hw *rwnx_hw) ret = rwnx_send_dbg_start_app_req(rwnx_hw, delay, HOST_START_APP_REBOOT); return ret; } - -int rwnx_send_pwm_init_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 mode, u8 run, u32 tmr_cnt, - u32 dty_cnt, u32 step_val, u8 gpio_en, u8 gpio_dir, u8 gpio_val) -{ - struct dbg_pwm_init_req *pwm_init_req; - - pwm_init_req = rwnx_msg_zalloc(DBG_PWM_INIT_REQ, TASK_DBG, DRV_TASK_ID, - sizeof(struct dbg_pwm_init_req)); - if (!pwm_init_req) - return -ENOMEM; - - pwm_init_req->pwm_gpidx = pwm_gpidx; - pwm_init_req->mode = mode; - pwm_init_req->run = run; - pwm_init_req->tmr_cnt = tmr_cnt; - pwm_init_req->dty_cnt = dty_cnt; - pwm_init_req->step_val = step_val; - pwm_init_req->gpio_en = gpio_en; - pwm_init_req->gpio_dir = gpio_dir; - pwm_init_req->gpio_val = gpio_val; - - - return rwnx_send_msg(rwnx_hw, pwm_init_req, 1, DBG_PWM_INIT_CFM, NULL); -} - -int rwnx_send_pwm_deinit_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 gpio_en, u8 gpio_dir, u8 gpio_val) -{ - struct dbg_pwm_deinit_req *pwm_deinit_req; - - pwm_deinit_req = rwnx_msg_zalloc(DBG_PWM_DEINIT_REQ, TASK_DBG, DRV_TASK_ID, - sizeof(struct dbg_pwm_deinit_req)); - if (!pwm_deinit_req) - return -ENOMEM; - - pwm_deinit_req->pwm_gpidx = pwm_gpidx; - pwm_deinit_req->gpio_en = gpio_en; - pwm_deinit_req->gpio_dir = gpio_dir; - pwm_deinit_req->gpio_val = gpio_val; - - return rwnx_send_msg(rwnx_hw, pwm_deinit_req, 1, DBG_PWM_DEINIT_CFM, NULL); -} - -u32 pwm_tbl[][2] = { - {0x40504088, 4}, -}; - -void rwnx_set_pwm_tbl(struct rwnx_hw *rwnx_hw) -{ - int patch_num = 0; - int cnt = 0; - int ret = 0; - - patch_num = sizeof(pwm_tbl) / sizeof(u32) / 2; - for (cnt = 0; cnt < patch_num; cnt++) { - ret = rwnx_send_dbg_mem_write_req(rwnx_hw, pwm_tbl[cnt][0], pwm_tbl[cnt][1]); - if (ret) { - break; - } - } -} - - //#endif // CONFIG_USB_BT #ifdef CONFIG_WOWLAN +#ifndef ANDROID_PLATFORM int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw) { int ret = 0; @@ -5124,3 +5256,4 @@ int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw) return ret; } #endif +#endif diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.h b/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.h index 99277dc..56261c8 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.h @@ -67,6 +67,7 @@ int rwnx_send_arpoffload_en_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_v u32_l ipaddr, u8_l enable); #endif int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l *tbl, u16_l len); +int rwnx_send_rf_config_v2_req(struct rwnx_hw *rwnx_hw, u16_l ofst, u8_l sel, u8_l *tbl, u16_l len); int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm); int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cfm *cfm); @@ -184,11 +185,13 @@ int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_ofst2x_v2_req(struct rwnx_hw *rwnx_hw); +int rwnx_send_txpwr_ofst2x_v3_req(struct rwnx_hw *rwnx_hw); int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter); int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_lvl_v3_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_lvl_v4_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw); +int rwnx_send_txpwr_lvl_adj_v2_req(struct rwnx_hw *rwnx_hw); #ifdef CONFIG_WOWLAN int rwnx_send_set_pkt_filter_req(struct rwnx_hw *rwnx_hw, u8_l *param); int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw); @@ -196,15 +199,14 @@ int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw); #ifdef CONFIG_DYNAMIC_PERPWR int rwnx_send_txpwr_per_sta_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta); #endif - +int rwnx_send_get_temp_req(struct rwnx_hw *rwnx_hw, s8_l *temp); //#ifdef CONFIG_USB_BT int rwnx_send_reboot(struct rwnx_hw *rwnx_hw); //#endif // CONFIG_USB_BT - -int rwnx_send_pwm_init_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 mode, u8 run, u32 tmr_cnt, - u32 dty_cnt, u32 step_val, u8 gpio_en, u8 gpio_dir, u8 gpio_val); -int rwnx_send_pwm_deinit_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 gpio_en, u8 gpio_dir, u8 gpio_val); -void rwnx_set_pwm_tbl(struct rwnx_hw *rwnx_hw); +struct rwnx_cmd *rwnx_cmd_malloc(void); +void rwnx_cmd_free(struct rwnx_cmd *cmd); +int rwnx_init_cmd_array(void); +void rwnx_free_cmd_array(void); #endif /* _RWNX_MSG_TX_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_pci.c b/drivers/aic8800/aic8800_fdrv/rwnx_pci.c index cd207c8..a91f8d3 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_pci.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_pci.c @@ -13,6 +13,7 @@ #include "rwnx_defs.h" #include "rwnx_dini.h" #include "rwnx_v7.h" +#include "rwnx_pci.h" #define PCI_VENDOR_ID_DINIGROUP 0x17DF #define PCI_DEVICE_ID_DINIGROUP_DNV6_F2PCIE 0x1907 diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_platform.c b/drivers/aic8800/aic8800_fdrv/rwnx_platform.c index 0392d4c..b85aa5b 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_platform.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_platform.c @@ -34,6 +34,8 @@ #include "aicwf_compat_8800dc.h" #include "aicwf_compat_8800d80.h" #include "aicwf_compat_8800d80x2.h" +#include "aicwf_compat_8800d80n.h" +#include "aicwf_compat_8800dln.h" #ifdef CONFIG_USE_FW_REQUEST #include #endif @@ -190,6 +192,15 @@ userconfig_info_t userconfig_info = { .pwrofst2x_tbl_6g_ant0 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229 .pwrofst2x_tbl_6g_ant1 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229 }, + .txpwr_ofst2x_v3 = { + .enable = 0, + .pwrofst2x_tbl_2g4 = + { // ch1-4, ch5-9, ch10-13 + { 0, 0, 0 }, // 11b + { 0, 0, 0 }, // ofdm_highrate + { 0, 0, 0 }, // ofdm_lowrate + }, + }, .xtal_cap = { .enable = 0, .xtal_cap = 24, @@ -248,6 +259,7 @@ reg_table reg_tables[] = { {.ccode = "CL", .region = REGIONS_ETSI}, {.ccode = "CO", .region = REGIONS_FCC}, {.ccode = "CR", .region = REGIONS_FCC}, + {.ccode = "CU", .region = REGIONS_FCC}, {.ccode = "CX", .region = REGIONS_FCC}, {.ccode = "CY", .region = REGIONS_ETSI}, {.ccode = "CZ", .region = REGIONS_ETSI}, @@ -272,7 +284,7 @@ reg_table reg_tables[] = { {.ccode = "GL", .region = REGIONS_ETSI}, {.ccode = "GP", .region = REGIONS_ETSI}, {.ccode = "GR", .region = REGIONS_ETSI}, - {.ccode = "GT", .region = REGIONS_FCC}, + {.ccode = "GT", .region = REGIONS_DEFAULT}, {.ccode = "GU", .region = REGIONS_FCC}, {.ccode = "GY", .region = REGIONS_DEFAULT}, {.ccode = "HK", .region = REGIONS_ETSI}, @@ -285,7 +297,7 @@ reg_table reg_tables[] = { {.ccode = "IL", .region = REGIONS_ETSI}, {.ccode = "IN", .region = REGIONS_ETSI}, {.ccode = "IQ", .region = REGIONS_ETSI}, - {.ccode = "IR", .region = REGIONS_JP}, + {.ccode = "IR", .region = REGIONS_ETSI}, {.ccode = "IS", .region = REGIONS_ETSI}, {.ccode = "IT", .region = REGIONS_ETSI}, {.ccode = "JM", .region = REGIONS_FCC}, @@ -295,7 +307,7 @@ reg_table reg_tables[] = { {.ccode = "KH", .region = REGIONS_ETSI}, {.ccode = "KN", .region = REGIONS_ETSI}, {.ccode = "KP", .region = REGIONS_JP}, - {.ccode = "KR", .region = REGIONS_ETSI}, + {.ccode = "KR", .region = REGIONS_KCC}, {.ccode = "KW", .region = REGIONS_ETSI}, {.ccode = "KY", .region = REGIONS_FCC}, {.ccode = "KZ", .region = REGIONS_DEFAULT}, @@ -339,7 +351,7 @@ reg_table reg_tables[] = { {.ccode = "PF", .region = REGIONS_ETSI}, {.ccode = "PG", .region = REGIONS_FCC}, {.ccode = "PH", .region = REGIONS_FCC}, - {.ccode = "PK", .region = REGIONS_ETSI}, + {.ccode = "PK", .region = REGIONS_DEFAULT}, {.ccode = "PL", .region = REGIONS_ETSI}, {.ccode = "PM", .region = REGIONS_ETSI}, {.ccode = "PR", .region = REGIONS_FCC}, @@ -361,7 +373,7 @@ reg_table reg_tables[] = { {.ccode = "SN", .region = REGIONS_FCC}, {.ccode = "SR", .region = REGIONS_ETSI}, {.ccode = "SV", .region = REGIONS_FCC}, - {.ccode = "SY", .region = REGIONS_DEFAULT}, + {.ccode = "SY", .region = REGIONS_ETSI}, {.ccode = "TC", .region = REGIONS_FCC}, {.ccode = "TD", .region = REGIONS_ETSI}, {.ccode = "TG", .region = REGIONS_ETSI}, @@ -372,6 +384,7 @@ reg_table reg_tables[] = { {.ccode = "TR", .region = REGIONS_ETSI}, {.ccode = "TT", .region = REGIONS_FCC}, {.ccode = "TW", .region = REGIONS_FCC}, + {.ccode = "TZ", .region = REGIONS_ETSI}, {.ccode = "UA", .region = REGIONS_ETSI}, {.ccode = "UG", .region = REGIONS_FCC}, {.ccode = "UY", .region = REGIONS_FCC}, @@ -382,10 +395,13 @@ reg_table reg_tables[] = { {.ccode = "VN", .region = REGIONS_JP}, {.ccode = "VU", .region = REGIONS_FCC}, {.ccode = "WF", .region = REGIONS_ETSI}, + {.ccode = "WS", .region = REGIONS_ETSI}, {.ccode = "YE", .region = REGIONS_DEFAULT}, {.ccode = "YT", .region = REGIONS_ETSI}, {.ccode = "ZA", .region = REGIONS_ETSI}, {.ccode = "ZM", .region = REGIONS_ETSI}, + {.ccode = "FO", .region = REGIONS_ETSI}, + {.ccode = "FK", .region = REGIONS_ETSI}, {.ccode = "ZW", .region = REGIONS_ETSI}, }; @@ -417,6 +433,8 @@ u8 get_region_index(char * name) return REGIONS_ETSI; else if (strncmp(name, "JP", 2) == 0) return REGIONS_JP; + else if (strncmp(name, "KCC", 3) == 0) + return REGIONS_KCC; else if (strncmp(name, "UNSET", 5) == 0) return REGIONS_DEFAULT; @@ -424,6 +442,7 @@ u8 get_region_index(char * name) } + #ifdef CONFIG_POWER_LIMIT #define POWER_LIMIT_INVALID_VAL POWER_LEVEL_INVALID_VAL @@ -431,7 +450,7 @@ u8 get_region_index(char * name) #define MAX_2_4G_BW_NUM 2 #define MAX_5G_BW_NUM 3 -#define MAX_REGION_NUM 5 +#define MAX_REGION_NUM 6 typedef struct @@ -685,7 +704,7 @@ static int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *dev } /* start to read from firmware file */ - buffer = vmalloc(size); + buffer = vmalloc(size + 1); if (!buffer) { *fw_buf = NULL; __putname(path); @@ -700,6 +719,7 @@ static int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *dev rdlen = kernel_read(fp, fp->f_pos, buffer, size); #endif + *((char*)buffer + size) = 0; if (size != rdlen) { AICWFDBG(LOGERROR, "%s: %s file rdlen invalid %d\n", __func__, name, (int)rdlen); *fw_buf = NULL; @@ -836,6 +856,69 @@ int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr, return err; } +int rwnx_plat_bin_fw_upload_2_with_version(struct rwnx_hw *rwnx_hw, u32 fw_addr, + char *filename, char *version_str, int version_size) +{ + int err = 0; + unsigned int i = 0, size; + u32 *dst = NULL; + + /* Copy the file on the Embedded side */ + AICWFDBG(LOGINFO, "### Upload %s firmware, @ = %x\n", filename, fw_addr); + + size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); + if (!dst) { + AICWFDBG(LOGERROR, "No such file or directory\n"); + return -1; + } + if (size <= 0) { + AICWFDBG(LOGERROR, "wrong size of firmware file\n"); + dst = NULL; + err = -1; + return -1; + } + AICWFDBG(LOGINFO, "size=%d, dst[0]=%x\n", size, dst[0]); + // get version if exist + if (version_str) { + char *bin_str = (char *)&dst[4]; + int char_idx = 0; + for (char_idx = 0; char_idx < version_size; char_idx++) { + version_str[char_idx] = bin_str[char_idx]; + if (bin_str[char_idx] == '\0') { + //break; + } + } + if (char_idx == version_size) { + version_str[version_size - 1] = '\0'; + } + AICWFDBG(LOGINFO, "version_str=%s\n", version_str); + } + // upload + if (size > 512) { + for (; i < (size - 512); i += 512) { + //printk("wr blk 0: %p -> %x\r\n", dst + i / 4, fw_addr + i); + err = rwnx_send_dbg_mem_block_write_req(rwnx_hw, fw_addr + i, 512, dst + i / 4); + if (err) { + AICWFDBG(LOGERROR, "bin upload fail: %x, err:%d\r\n", fw_addr + i, err); + break; + } + } + } + if (!err && (i < size)) { + //printk("wr blk 1: %p -> %x\r\n", dst + i / 4, fw_addr + i); + err = rwnx_send_dbg_mem_block_write_req(rwnx_hw, fw_addr + i, size - i, dst + i / 4); + if (err) { + AICWFDBG(LOGERROR, "bin upload fail: %x, err:%d\r\n", fw_addr + i, err); + } + } + + if (dst) { + rwnx_release_firmware_common(&dst); + } + + return err; +} + #ifndef CONFIG_ROM_PATCH_EN @@ -1723,8 +1806,52 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw) return 1; // exit calib mode } } + } else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N) { +#ifndef ANDROID_PLATFORM + sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80N"); +#endif + if (testmode == FW_NORMAL_MODE) { + ret = aicwf_plat_patch_load_8800d80n(rwnx_hw); + if (ret) { + AICWFDBG(LOGERROR, "patch upload fail: %d\n", ret); + return ret; + } + ret = aicwf_plat_patch_table_load_8800d80n(rwnx_hw); + if (ret) { + AICWFDBG(LOGERROR, "patch_tbl upload fail: %d\r\n", ret); + return ret; + } + aicwf_patch_config_8800d80n(rwnx_hw); + #if DEF_PATCH_METHOD_VER_2 + aicwf_plat_cinit_exec_8800d80n(rwnx_hw); + aicwf_plat_calib_exec_8800d80n(rwnx_hw); + #endif + } + else if (testmode == FW_RFTEST_MODE) { + AICWFDBG(LOGINFO, "%s load rftest bin\n", __func__); + ret = aicwf_plat_rftest_load_8800d80n(rwnx_hw); + if (ret) { + AICWFDBG(LOGERROR, "load rftest bin fail: %d\n", ret); + return ret; + } + } + } + else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN) { +#ifndef ANDROID_PLATFORM + sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800DLN"); +#endif + if (testmode == FW_NORMAL_MODE) { + aicwf_patch_config_8800dln(rwnx_hw); + } + else if (testmode == FW_RFTEST_MODE) { + AICWFDBG(LOGINFO, "%s load rftest bin\n", __func__); + ret = aicwf_plat_rftest_load_8800dln(rwnx_hw); + if (ret) { + AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret); + return ret; + } + } } - return ret; } #endif @@ -2242,6 +2369,16 @@ void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj) AICWFDBG(LOGINFO, "%s:lvl_adj_5g_chan_155:%d\r\n", __func__, txpwr_lvl_adj->pwrlvl_adj_tbl_5g[5]); } +void get_userconfig_txpwr_lvl_adj_v2_in_fdrv(txpwr_lvl_adj_conf_v2_t *txpwr_lvl_adj_v2) +{ + *txpwr_lvl_adj_v2 = userconfig_info.txpwr_lvl_adj_v2; + + AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_adj_v2->enable); + AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_1_4:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[0]); + AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_5_9:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[1]); + AICWFDBG(LOGINFO, "%s:lvl_adj_2g4_chan_10_13:%d\r\n", __func__, txpwr_lvl_adj_v2->pwrlvl_adj_tbl_2g4[2]); +} + void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst) { @@ -2311,6 +2448,23 @@ void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x } AICWFDBG(LOGINFO, "\n"); } + +void get_userconfig_txpwr_ofst2x_v3_in_fdrv(txpwr_ofst2x_conf_v3_t *txpwr_ofst2x_v3) +{ + int type, ch_grp; + *txpwr_ofst2x_v3 = userconfig_info.txpwr_ofst2x_v3; + AICWFDBG(LOGINFO, "%s:enable :%d\r\n", __func__, txpwr_ofst2x_v3->enable); + AICWFDBG(LOGINFO, "pwrofst2x 2.4g: [0]:11b, [1]:ofdm_highrate, [2]:ofdm_lowrate\n" + " chan=" "\t1-4" "\t5-9" "\t10-13"); + for (type = 0; type < 3; type++) { + AICWFDBG(LOGINFO, "\n [%d] =", type); + for (ch_grp = 0; ch_grp < 3; ch_grp++) { + AICWFDBG(LOGINFO, "\t%d", txpwr_ofst2x_v3->pwrofst2x_tbl_2g4[type][ch_grp]); + } + } + AICWFDBG(LOGINFO, "\n"); +} + void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss) { txpwr_loss->loss_enable_2g4 = userconfig_info.txpwr_loss.loss_enable_2g4; @@ -2322,6 +2476,101 @@ void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss) txpwr_loss->loss_enable_2g4, txpwr_loss->loss_value_2g4, txpwr_loss->loss_enable_5g, txpwr_loss->loss_value_5g); } +s8_l get_txpwr_max(s8_l power) +{ + int i=0; + + if(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D89X2 ){ + for (i = 0; i <= 11; i++){ + if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[i]) + power = userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[i]; + } + for (i = 0; i <= 9; i++){ + if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[i]) + power = userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[i]; + } + for (i = 0; i <= 11; i++){ + if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[i]) + power = userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[i]; + } + for (i = 0; i <= 7; i++){ + if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[i]) + power = userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[i]; + } + for (i = 0; i <= 9; i++){ + if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[i]) + power = userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[i]; + } + for (i = 0; i <= 11; i++){ + if(power < userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[i]) + power = userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[i]; + } + + if ((userconfig_info.txpwr_loss.loss_enable_2g4 == 1) || + (userconfig_info.txpwr_loss.loss_enable_5g == 1)) { + if (userconfig_info.txpwr_loss.loss_value_2g4 < + userconfig_info.txpwr_loss.loss_value_5g) + power += userconfig_info.txpwr_loss.loss_value_5g; + else + power += userconfig_info.txpwr_loss.loss_value_2g4; + } + } + else if (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81 || + g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D80N){ + for (i = 0; i <= 11; i++){ + if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[i]) + power = userconfig_info.txpwr_lvl_v3.pwrlvl_11b_11ag_2g4[i]; + } + for (i = 0; i <= 9; i++){ + if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[i]) + power = userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_2g4[i]; + } + for (i = 0; i <= 11; i++){ + if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[i]) + power = userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_2g4[i]; + } + for (i = 4; i <= 11; i++){ + if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[i]) + power = userconfig_info.txpwr_lvl_v3.pwrlvl_11a_5g[i]; + } + for (i = 0; i <= 9; i++){ + if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[i]) + power = userconfig_info.txpwr_lvl_v3.pwrlvl_11n_11ac_5g[i]; + } + for (i = 0; i <= 11; i++){ + if(power < userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[i]) + power = userconfig_info.txpwr_lvl_v3.pwrlvl_11ax_5g[i]; + } + + if ((userconfig_info.txpwr_loss.loss_enable_2g4 == 1) || + (userconfig_info.txpwr_loss.loss_enable_5g == 1)) { + if (userconfig_info.txpwr_loss.loss_value_2g4 < + userconfig_info.txpwr_loss.loss_value_5g) + power += userconfig_info.txpwr_loss.loss_value_5g; + else + power += userconfig_info.txpwr_loss.loss_value_2g4; + } + + }else if(g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DC || g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW){ + for (i = 0; i <= 11; i++){ + if(power < userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[i]) + power = userconfig_info.txpwr_lvl_v2.pwrlvl_11b_11ag_2g4[i]; + } + for (i = 0; i <= 9; i++){ + if(power < userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[i]) + power = userconfig_info.txpwr_lvl_v2.pwrlvl_11n_11ac_2g4[i]; + } + for (i = 0; i <= 11; i++){ + if(power < userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[i]) + power = userconfig_info.txpwr_lvl_v2.pwrlvl_11ax_2g4[i]; + } + } + + AICWFDBG(LOGINFO, "%s:txpwr_max:%d \r\n",__func__,power); + return power; +} + void set_txpwr_loss_ofst(s8_l value) { userconfig_info.txpwr_loss.loss_enable_2g4 = 1; @@ -3115,7 +3364,7 @@ int8_t rwnx_plat_powerlimit_save(u8_l band, char *channel, u8_l bw, char *limit, } -void rwnx_plat_powerlimit_parsing(char *buffer, int size, char *cc) +void rwnx_plat_powerlimit_parsing(char *buffer, int size) { #define LD_STAGE_EXC_MAPPING 0 #define LD_STAGE_TAB_DEFINE 1 @@ -3465,11 +3714,21 @@ static int rwnx_plat_userconfig_load(struct rwnx_hw *rwnx_hw) { #ifdef CONFIG_POWER_LIMIT rwnx_plat_powerlimit_load_8800dcdw(rwnx_hw, PRODUCT_ID_AIC8800DW); #endif + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DLN){ + rwnx_plat_userconfig_load_8800dln(rwnx_hw); + #ifdef CONFIG_POWER_LIMIT + rwnx_plat_powerlimit_load_8800dln(rwnx_hw); + #endif }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){ rwnx_plat_userconfig_load_8800d80(rwnx_hw); }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ rwnx_plat_userconfig_load_8800d80x2(rwnx_hw); + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D80N){ + rwnx_plat_userconfig_load_8800d80n(rwnx_hw); +#ifdef CONFIG_POWER_LIMIT + rwnx_plat_powerlimit_load_8800d80n(rwnx_hw); +#endif } return 0; diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_platform.h b/drivers/aic8800/aic8800_fdrv/rwnx_platform.h index 7d54740..b40d62c 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_platform.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_platform.h @@ -71,10 +71,12 @@ typedef struct txpwr_lvl_conf_v3_t txpwr_lvl_v3; txpwr_lvl_conf_v4_t txpwr_lvl_v4; txpwr_lvl_adj_conf_t txpwr_lvl_adj; + txpwr_lvl_adj_conf_v2_t txpwr_lvl_adj_v2; txpwr_loss_conf_t txpwr_loss; txpwr_ofst_conf_t txpwr_ofst; txpwr_ofst2x_conf_t txpwr_ofst2x; txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2; + txpwr_ofst2x_conf_v3_t txpwr_ofst2x_v3; xtal_cap_conf_t xtal_cap; } userconfig_info_t; @@ -85,6 +87,7 @@ typedef enum { REGIONS_FCC, REGIONS_ETSI, REGIONS_JP, + REGIONS_KCC, REGIONS_DEFAULT, } Regions_code; @@ -156,10 +159,13 @@ void get_userconfig_txpwr_lvl_v2_in_fdrv(txpwr_lvl_conf_v2_t *txpwr_lvl_v2); void get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_conf_v3_t *txpwr_lvl_v3); void get_userconfig_txpwr_lvl_v4_in_fdrv(txpwr_lvl_conf_v4_t *txpwr_lvl_v4); void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj); +void get_userconfig_txpwr_lvl_adj_v2_in_fdrv(txpwr_lvl_adj_conf_v2_t *txpwr_lvl_adj_v2); void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst); void get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x_conf_t *txpwr_ofst2x); void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x_v2); +void get_userconfig_txpwr_ofst2x_v3_in_fdrv(txpwr_ofst2x_conf_v3_t *txpwr_ofst2x_v3); void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss); +s8_l get_txpwr_max(s8_l power); void set_txpwr_loss_ofst(s8_l value); void rwnx_plat_userconfig_parsing(char *buffer, int size); @@ -169,7 +175,7 @@ u8 get_region_index(char * name); #ifdef CONFIG_POWER_LIMIT int8_t rwnx_plat_powerlimit_save(u8_l band, char *channel, u8_l bw, char *limit, char *name); -void rwnx_plat_powerlimit_parsing(char *buffer, int size, char *cc); +void rwnx_plat_powerlimit_parsing(char *buffer, int size); int8_t get_powerlimit_by_freq(uint8_t band, uint16_t freq, uint8_t r_idx); int8_t get_powerlimit_by_chnum(uint8_t chnum, uint8_t r_idx, uint8_t bw); #endif @@ -182,5 +188,17 @@ static inline unsigned int rwnx_platform_get_irq(struct rwnx_plat *rwnx_plat) { return rwnx_plat->pci_dev->irq; } +int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw, u32** buffer, const char *filename); +void rwnx_release_firmware_common(u32** buffer); +int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr, + char *filename); +int rwnx_plat_bin_fw_upload_2_with_version(struct rwnx_hw *rwnx_hw, u32 fw_addr, + char *filename, char *version_str, int version_size); +int rwnx_atoi2(char *value, int c_len); +int rwnx_atoi(char *value); +void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap); +void rwnx_plat_nvram_set_value(char *command, char *value); +void rwnx_plat_nvram_set_value_8800d80x2(char *command, char *value); +void rwnx_plat_userconfig_parsing_8800d80x2(char *buffer, int size); #endif /* _RWNX_PLATFORM_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_radar.c b/drivers/aic8800/aic8800_fdrv/rwnx_radar.c index 947b713..0772f47 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_radar.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_radar.c @@ -182,28 +182,27 @@ static const struct radar_types fcc_radar_types = { }; #define JP_PATTERN FCC_PATTERN +//JP_PATTERN(1, 2, 8, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT), static const struct radar_detector_specs jp_radar_ref_types_riu[] = { - JP_PATTERN(0, 0, 8, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT), - JP_PATTERN(1, 2, 8, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT), - JP_PATTERN(2, 0, 8, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT), - JP_PATTERN(3, 0, 8, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT), - JP_PATTERN(4, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT), - JP_PATTERN(5, 6, 20, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT), - JP_PATTERN(6, 10, 28, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT), - JP_PATTERN(7, 50, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG), - JP_PATTERN(8, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT), + JP_PATTERN(0, 0, 4, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT), + JP_PATTERN(1, 0, 4, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT), + JP_PATTERN(2, 0, 4, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT), + JP_PATTERN(3, 0, 6, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT), + JP_PATTERN(4, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT), + JP_PATTERN(5, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT), + JP_PATTERN(6, 48, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG), + JP_PATTERN(7, 0, 4, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT), }; static const struct radar_detector_specs jp_radar_ref_types_fcu[] = { - JP_PATTERN(0, 0, 8, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT), - JP_PATTERN(1, 2, 6, 3846, 3846, 1, 18, RADAR_WAVEFORM_SHORT), - JP_PATTERN(2, 0, 8, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT), - JP_PATTERN(3, 2, 2, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT), - JP_PATTERN(4, 0, 8, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT), - JP_PATTERN(5, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT), - JP_PATTERN(6, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT), - JP_PATTERN(7, 50, 104, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG), - JP_PATTERN(8, 0, 8, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT), + JP_PATTERN(0, 0, 4, 1388, 1388, 1, 18, RADAR_WAVEFORM_SHORT), + JP_PATTERN(1, 0, 4, 1428, 1428, 1, 18, RADAR_WAVEFORM_SHORT), + JP_PATTERN(2, 0, 4, 4000, 4000, 1, 18, RADAR_WAVEFORM_SHORT), + JP_PATTERN(3, 0, 6, 150, 230, 1, 23, RADAR_WAVEFORM_SHORT), + JP_PATTERN(4, 6, 12, 200, 500, 1, 16, RADAR_WAVEFORM_SHORT), + JP_PATTERN(5, 10, 22, 200, 500, 1, 12, RADAR_WAVEFORM_SHORT), + JP_PATTERN(6, 48, 110, 1000, 2000, 1, 8, RADAR_WAVEFORM_LONG), + JP_PATTERN(7, 0, 4, 333, 333, 1, 9, RADAR_WAVEFORM_SHORT), }; static const struct radar_types jp_radar_types = { @@ -219,33 +218,6 @@ static const struct radar_types *dfs_domains[] = { &jp_radar_types, }; - -/** - * struct pri_sequence - sequence of pulses matching one PRI - * @head: list_head - * @pri: pulse repetition interval (PRI) in usecs - * @dur: duration of sequence in usecs - * @count: number of pulses in this sequence - * @count_falses: number of not matching pulses in this sequence - * @first_ts: time stamp of first pulse in usecs - * @last_ts: time stamp of last pulse in usecs - * @deadline_ts: deadline when this sequence becomes invalid (first_ts + dur) - * @ppb_thresh: Number of pulses to validate detection - * (need for weather radar whose value depends of pri) - */ -struct pri_sequence { - struct list_head head; - u32 pri; - u32 dur; - u32 count; - u32 count_falses; - u64 first_ts; - u64 last_ts; - u64 deadline_ts; - u8 ppb_thresh; -}; - - /** * struct pulse_elem - elements in pulse queue * @ts: time stamp in usecs @@ -804,9 +776,9 @@ struct pri_sequence *pde_long_add_pulse(struct rwnx_radar *radar, struct pri_det struct pri_sequence *ps; const struct radar_detector_specs *rs = pde->rs; - if(radar->status != RWNX_RADAR_CAC_BUSY) { - return NULL; - } + //if(radar->status != RWNX_RADAR_CAC_BUSY) { + // return NULL; + //} if (list_empty(&pde->sequences)) { /* First pulse, create a new sequence */ @@ -1407,6 +1379,29 @@ static void rwnx_radar_process_pulse(struct work_struct *ws) rm->ts[rm->idx] = dpd->last_pulse_ts + pri; } rm->idx = (rm->idx + 1) % RWNX_RADARR_DUMP_NB; + + if(rm->cnt == 1) + { + struct radar_detector_specs *spc; + int k; + AICWFDBG(LOGINFO, "dpd: en = %d, region = %d, ntype = %d", dpd->enabled, dpd->region, dpd->num_radar_types); + AICWFDBG(LOGINFO, "id wid.{min, max} pri.{min, max, num}, ppb, thd, tlrn, type"); + for (k = 0; k < dpd->num_radar_types; k++) + { + spc =(struct radar_detector_specs *)&dpd->radar_spec[k]; + AICWFDBG(LOGINFO, "%d %3d, %3d %4d %4d %d %2d %2d %d %d", + spc->type_id, + spc->width_min, + spc->width_max, + spc->pri_min, + spc->pri_max, + spc->num_pri, + spc->ppb, + spc->ppb_thresh, + spc->max_pri_tolerance, + spc->type); + } + } } #endif if((radar->status != RWNX_RADAR_CAC_BUSY) && (radar->status != RWNX_RADAR_INSERVICE_BUSY)) { @@ -1602,6 +1597,7 @@ void rwnx_radar_start_cac(struct rwnx_radar *radar, u32 cac_time_ms, { WARN(radar->cac_vif != NULL, "CAC already in progress"); radar->cac_vif = vif; + AICWFDBG(LOGINFO, "%s DFS: cac time = %u ms", __func__, cac_time_ms); schedule_delayed_work(&radar->cac_work, msecs_to_jiffies(cac_time_ms)); } @@ -1714,8 +1710,8 @@ int rwnx_radar_dump_pattern_detector(char *buf, size_t len, } size_needed += sizeof(info); - return size_needed; } + return size_needed; } /* */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_radar.h b/drivers/aic8800/aic8800_fdrv/rwnx_radar.h index 5e2b8e4..5e430e9 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_radar.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_radar.h @@ -32,6 +32,34 @@ enum rwnx_radar_detector { radar to upper layer. */ }; + +/** + * struct pri_sequence - sequence of pulses matching one PRI + * @head: list_head + * @pri: pulse repetition interval (PRI) in usecs + * @dur: duration of sequence in usecs + * @count: number of pulses in this sequence + * @count_falses: number of not matching pulses in this sequence + * @first_ts: time stamp of first pulse in usecs + * @last_ts: time stamp of last pulse in usecs + * @deadline_ts: deadline when this sequence becomes invalid (first_ts + dur) + * @ppb_thresh: Number of pulses to validate detection + * (need for weather radar whose value depends of pri) + */ +struct pri_sequence { + struct list_head head; + u32 pri; + u32 dur; + u32 count; + u32 count_falses; + u64 first_ts; + u64 last_ts; + u64 deadline_ts; + u8 ppb_thresh; +}; + + + #ifdef CONFIG_RWNX_RADAR #include #include @@ -137,6 +165,9 @@ int rwnx_radar_dump_pattern_detector(char *buf, size_t len, struct rwnx_radar *radar, u8 chain); int rwnx_radar_dump_radar_detected(char *buf, size_t len, struct rwnx_radar *radar, u8 chain); +struct pri_detector *pri_detector_init(struct dfs_pattern_detector *dpd, + u16 radar_type, u16 freq); +void print_radar_detect_info(struct pri_detector *pde, struct pri_sequence *ps); #else diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_rx.c b/drivers/aic8800/aic8800_fdrv/rwnx_rx.c index 2823d82..b584485 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_rx.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_rx.c @@ -812,6 +812,7 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, aicwf_nl_send_frame_rpt_msg(rwnx_vif, WIFI_AUTH, mgmt->sa, rxvect->rssi1); } +#if 0 if (ieee80211_is_probe_req(mgmt->frame_control)) { if (!rwnx_vif->ap.start) return; @@ -830,6 +831,7 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, AICWFDBG(LOGERROR, "usb probe_rsp pool full, drop %pM\n", mgmt->sa); return; } +#endif } #endif @@ -1364,8 +1366,10 @@ static void rwnx_rx_add_rtap_hdr(struct rwnx_hw* rwnx_hw, while ((pos - (u8 *)rtap) & 1) pos++; rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_HE); - memcpy(pos, &he, sizeof(he)); - pos += sizeof(he); + //memcpy(pos, &he, sizeof(he)); + //pos += sizeof(he); + *(struct ieee80211_radiotap_he *)pos = he; + pos += sizeof(struct ieee80211_radiotap_he); } // Rx Chains @@ -1833,8 +1837,7 @@ bool reord_rxframes_process(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *pr return bPktInBuf; } -void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv, - struct reord_ctrl *preorder_ctrl) +void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *preorder_ctrl) { struct list_head *phead, *plist; struct recv_msdu *prframe; @@ -1927,8 +1930,6 @@ int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv, struct reord_ctrl_info *reord_info; struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif; struct ethhdr *eh = (struct ethhdr *)(skb->data); - u8 *da = eh->h_dest; - u8 is_mcast = ((*da) & 0x01)? 1 : 0; #if 0 struct recv_msdu *pframe; @@ -1949,7 +1950,7 @@ int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv, preorder_ctrl = pframe->preorder_ctrl; pframe->is_amsdu = is_amsdu; - if ((ntohs(eh->h_proto) == ETH_P_PAE) || is_mcast) + if (ntohs(eh->h_proto) == ETH_P_PAE) return reord_single_frame_ind(rx_priv, pframe); if((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) @@ -2039,9 +2040,9 @@ 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); + ret = timer_delete(&preorder_ctrl->reord_timer); #else - ret = del_timer(&preorder_ctrl->reord_timer); + ret = del_timer(&preorder_ctrl->reord_timer); #endif } } @@ -2127,7 +2128,10 @@ void remove_sec_hdr_mgmt_frame(struct hw_rxhdr *hw_rxhdr,struct sk_buff *skb) if(!hw_rxhdr->hwvect.ga_frame){ if(((skb->data[0] & 0x0C) == 0) && (skb->data[1] & 0x40) == 0x40){ //protect management frame printk("frame type %x\n",skb->data[0]); - if(hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_CCMP128){ + if((hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_CCMP128) || + (hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_CCMP256) || + (hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_GCMP128) || + (hw_rxhdr->hwvect.decr_status == RWNX_RX_HD_DECR_GCMP256)) { memcpy(mgmt_header,skb->data,hdr_len); skb_pull(skb,8); memcpy(skb->data,mgmt_header,hdr_len); @@ -2250,7 +2254,14 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv) u8 is_amsdu = 0; bool resend = false, forward = true; const struct ethhdr *eth; - +#ifdef CONFIG_SUPPORT_4ADDR + u8_l b_4addr = 0; +#endif +#ifdef CONFIG_BR_SUPPORT + int vif_idx; + struct rwnx_vif *vif_itr = NULL; + struct rwnx_sta *cur_sta; +#endif REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_RWNXDATAIND); hw_rxhdr = (struct hw_rxhdr *)skb->data; @@ -2333,8 +2344,8 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv) #endif } - skb_reset_tail_pointer(skb); - skb->len = 0; + //skb_reset_tail_pointer(skb); + //skb->len = 0; skb_reset_tail_pointer(skb_monitor); skb_monitor->len = 0; skb_put(skb_monitor, frm_len); @@ -2389,8 +2400,26 @@ check_len_update: rwnx_rx_vector_convert(rwnx_hw, &hw_rxhdr->hwvect.rx_vect1, &hw_rxhdr->hwvect.rx_vect2); + +#ifndef CONFIG_SUPPORT_4ADDR + if (hw_rxhdr->flags_is_4addr) { + dev_err(rwnx_hw->dev, "4addr Frame received (%d), skb->len:%u\n", hw_rxhdr->flags_vif_idx, skb->len); + print_hex_dump(KERN_ERR,"4addr ",DUMP_PREFIX_NONE, 16, 1, skb->data, skb->len, false); + dev_kfree_skb(skb); + goto end; + } +#endif + skb_pull(skb, msdu_offset + 2); //+2 since sdio allign 58->60 #define MAC_FCTRL_MOREFRAG 0x0400 + +#ifdef CONFIG_SUPPORT_4ADDR + if (hw_rxhdr->flags_is_4addr) { + hdr_len += 6; + b_4addr = 1; + } +#endif + frame_ctrl = (skb->data[1] << 8) | skb->data[0]; seq_num = ((skb->data[22] & 0xf0) >> 4) | (skb->data[23] << 4); frag_num = (skb->data[22] & 0x0f); @@ -2398,28 +2427,86 @@ check_len_update: if ((skb->data[0] & 0x0f) == 0x08) { if ((skb->data[0] & 0x80) == 0x80) {//qos data - hdr_len = 26; + hdr_len += 2; +#ifdef CONFIG_SUPPORT_4ADDR + tid = b_4addr ? (skb->data[30] & 0x0F) : (skb->data[24] & 0x0F); +#else tid = skb->data[24] & 0x0F; +#endif is_qos = 1; +#ifdef CONFIG_SUPPORT_4ADDR + if (b_4addr) { + if (skb->data[30] & 0x80) + is_amsdu = 1; + } else { + if (skb->data[24] & 0x80) + is_amsdu = 1; + } +#else if (skb->data[24] & 0x80) is_amsdu = 1; +#endif } if(skb->data[1] & 0x80)// htc hdr_len += 4; - if((skb->data[1] & 0x3) == 0x1) {// to ds - memcpy(ra, &skb->data[16], MAC_ADDR_LEN);//destination addr - memcpy(ta, &skb->data[10], MAC_ADDR_LEN);//source addr - } else if((skb->data[1] & 0x3) == 0x2) { //from ds - memcpy(ta, &skb->data[16], MAC_ADDR_LEN);//destination addr - memcpy(ra, &skb->data[4], MAC_ADDR_LEN);//BSSID - } +#ifdef CONFIG_SUPPORT_4ADDR + if (b_4addr) { + if ((skb->data[1] & 0x3) != 0x3) { + printk("aicwf: 4addr DS error, to_from ds:%d\n", skb->data[1] & 0x3); + print_hex_dump(KERN_ERR,"rx_4addr ",DUMP_PREFIX_NONE, 16, 1, skb->data, skb->len, false); + } + memcpy(ra, &skb->data[16], MAC_ADDR_LEN); + memcpy(ta, &skb->data[24], MAC_ADDR_LEN); + printk("aicwf 4addr: da: %pM, sa: %pM\n", ra, ta); + } else { + //printk("aicwf: to_from ds:%d\n", skb->data[1] & 0x3); + if((skb->data[1] & 0x3) == 0x1) {// to ds + memcpy(ra, &skb->data[16], MAC_ADDR_LEN); + memcpy(ta, &skb->data[10], MAC_ADDR_LEN); + } else if((skb->data[1] & 0x3) == 0x2) { //from ds + memcpy(ta, &skb->data[16], MAC_ADDR_LEN); + memcpy(ra, &skb->data[4], MAC_ADDR_LEN); + } + } +#else + if((skb->data[1] & 0x3) == 0x1) {// to ds + memcpy(ra, &skb->data[16], MAC_ADDR_LEN); + memcpy(ta, &skb->data[10], MAC_ADDR_LEN); + } else if((skb->data[1] & 0x3) == 0x2) { //from ds + memcpy(ta, &skb->data[16], MAC_ADDR_LEN); + memcpy(ra, &skb->data[4], MAC_ADDR_LEN); + } +#endif + +#ifdef CONFIG_BR_SUPPORT + if((skb->data[1] & 0x3) == 0x2) { + for (vif_idx = 0; vif_idx < NX_VIRT_DEV_MAX; vif_idx++) { + vif_itr = rwnx_hw->vif_table[vif_idx]; + if (vif_itr && vif_itr->up && RWNX_VIF_TYPE(vif_itr) == NL80211_IFTYPE_AP) { + spin_lock_bh(&vif_itr->rwnx_hw->cb_lock); + list_for_each_entry(cur_sta, &vif_itr->ap.sta_list, list) { + if (!memcmp(cur_sta->mac_addr, ta, MAC_ADDR_LEN)) { + //printk("aicwf filter out, %pM\n", ta); + dev_kfree_skb(skb); + spin_unlock_bh(&vif_itr->rwnx_hw->cb_lock); + goto end; + } + } + spin_unlock_bh(&vif_itr->rwnx_hw->cb_lock); + } + } + } +#endif pull_len += (hdr_len + 8); switch (hw_rxhdr->hwvect.decr_status) { case RWNX_RX_HD_DECR_CCMP128: + case RWNX_RX_HD_DECR_CCMP256: + case RWNX_RX_HD_DECR_GCMP128: + case RWNX_RX_HD_DECR_GCMP256: pull_len += 8;//ccmp_header //skb_pull(&skb->data[skb->len-8], 8); //ccmp_mic_len memcpy(ether_type, &skb->data[hdr_len + 6 + 8], 2); @@ -2441,17 +2528,33 @@ check_len_update: memcpy(ether_type, &skb->data[hdr_len + 6], 2); break; } + + + if((ether_type[0] == 0x8e && ether_type[1] == 0x88) || (ether_type[0] == 0x88 && ether_type[1] == 0x8e)) + printk("rx eapol\n"); + + if (is_amsdu) { +//Check NETGEAR R7000 router's AMSDU packet format for compliance. start + AICWFDBG(LOGDEBUG, "%s is amsdu pkt pull_len:%d %x %x %x\r\n", __func__, + pull_len, skb->data[pull_len - 8], + skb->data[pull_len - 7], + skb->data[pull_len - 2]); + if (skb->data[pull_len - 8] == 0xAA && + skb->data[pull_len - 7] == 0xAA && + skb->data[pull_len - 2] > 0x06){ + AICWFDBG(LOGERROR, "%s amsdu pkt not regular \r\n", __func__); + is_amsdu = 0; + }else{ + skb_pull(skb, pull_len-8); + } +//Check NETGEAR R7000 router's AMSDU packet format for compliance. end + } + if(is_amsdu) hw_rxhdr->flags_is_amsdu = 1; else hw_rxhdr->flags_is_amsdu = 0; - - if((ether_type[0] == 0x8e && ether_type[1] == 0x88) || (ether_type[0] == 0x88 && ether_type[1] == 0x8e)) - printk("rx eapol\n"); - if (is_amsdu) { - skb_pull(skb, pull_len-8); - } - + if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA) sta_idx = hw_rxhdr->flags_dst_idx; @@ -2629,6 +2732,7 @@ check_len_update: } if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) { + printk("aicwf: 4addr flag error\n"); #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev, sta->mac_addr, -1, GFP_ATOMIC); @@ -2675,7 +2779,7 @@ check_len_update: #ifdef CONFIG_DYNAMIC_PERPWR sta = &rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx]; - rssi_update_txpwrloss(sta, hw_rxhdr->hwvect.rx_vect1.rssi1); + rssi_update_txpwrloss(sta, hw_rxhdr->hwvect.rx_vect1.rssi1, rwnx_vif); #endif #ifdef CONFIG_BAND_STEERING (&rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx])->rssi = hw_rxhdr->hwvect.rx_vect1.rssi1; diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_rx.h b/drivers/aic8800/aic8800_fdrv/rwnx_rx.h index e7e71f6..e8595a1 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_rx.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_rx.h @@ -353,10 +353,15 @@ struct DHCPInfo { u8 options[308]; /* 312 - cookie */ }; +int reord_flush_tid(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u8 tid); +bool reord_rxframes_process(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *preorder_ctrl, int bforced); + u8 rwnx_unsup_rx_vec_ind(void *pthis, void *hostid); u8 rwnx_rxdataind(void *pthis, void *hostid); u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv); int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv); +void rwnx_rx_data_skb_resend(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, struct sk_buff *skb); + #ifdef CONFIG_USB_MSG_IN_EP int aicwf_process_msg_rxframes(struct aicwf_rx_priv *rx_priv); #endif @@ -373,11 +378,20 @@ int reord_need_check(struct reord_ctrl *preorder_ctrl, u16 seq_num); int reord_rxframe_enqueue(struct reord_ctrl *preorder_ctrl, struct recv_msdu *prframe); void reord_timeout_worker(struct work_struct *work); int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prframe); +void reord_rxframes_ind(struct aicwf_rx_priv *rx_priv, struct reord_ctrl *preorder_ctrl); +void remove_sec_hdr_mgmt_frame(struct hw_rxhdr *hw_rxhdr,struct sk_buff *skb); +int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 seq_num, u8 tid, u8 forward, u8 is_amsdu); + #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) void reord_timeout_handler (ulong data); #else void reord_timeout_handler (struct timer_list *t); #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) +void defrag_timeout_cb(ulong data); +#else +void defrag_timeout_cb(struct timer_list *t); +#endif #endif void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx, diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_tx.c b/drivers/aic8800/aic8800_fdrv/rwnx_tx.c index ae44319..8d2ab4a 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_tx.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_tx.c @@ -1833,7 +1833,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta, return 0; } -#ifdef CONFIG_BAND_STEERING +#if 0//def CONFIG_BAND_STEERING void rwnx_probersp_work(struct work_struct *work) { struct ap_probe_rsp *rsp = container_of(work, struct ap_probe_rsp, rsp_work); @@ -1841,7 +1841,6 @@ void rwnx_probersp_work(struct work_struct *work) struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; struct sk_buff *skb = NULL; struct rwnx_bcn *bcn = &rwnx_vif->ap.bcn; - unsigned int len = bcn->len; u8_l *buf; struct ieee80211_mgmt *mgmt; bool robust; @@ -1852,13 +1851,13 @@ void rwnx_probersp_work(struct work_struct *work) struct rwnx_sw_txhdr *sw_txhdr; struct txdesc_api *desc; headroom = sizeof(struct rwnx_txhdr); - frame_len = len; + frame_len = bcn->len; if (aicwf_band_steering_block_chk(rwnx_vif, rsp->da)) { AICWFDBG(LOGSTEER, "usb %s, %d, probe_rsp refuse temp %pM\n", __func__, rwnx_vif->ap.freq, rsp->da); goto free_use; } - if (!bcn->head || bcn->head_len == 0 || bcn->head_len > frame_len) { + if (frame_len == 0 || !bcn->head || bcn->head_len == 0 || bcn->head_len > frame_len) { AICWFDBG(LOGSTEER, "%s bcn head NULL\n", __func__); goto free_use; } @@ -2347,7 +2346,8 @@ int rwnx_txdatacfm(void *pthis, void *host_id) /* Check status in the header. If status is null, it means that the buffer * was not transmitted and we have to return immediately */ if (rwnx_txst.value == 0) { - return -1; + //return -1; + rwnx_txst.tx_done = 1; } #ifdef AICWF_USB_SUPPORT diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_tx.h b/drivers/aic8800/aic8800_fdrv/rwnx_tx.h index eb64c77..772e2d1 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_tx.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_tx.h @@ -17,6 +17,7 @@ #include "ipc_shared.h" #include "rwnx_txq.h" #include "hal_desc.h" +#include "aicwf_tcp_ack.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) #define IEEE80211_NUM_TIDS 16 @@ -197,6 +198,8 @@ void rwnx_tx_push(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr, int flags); #ifdef CONFIG_BAND_STEERING void rwnx_probersp_work(struct work_struct *work); #endif - +#ifdef CONFIG_FILTER_TCP_ACK +int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg); +#endif #endif /* _RWNX_TX_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_txq.h b/drivers/aic8800/aic8800_fdrv/rwnx_txq.h index c019c6a..a41fc2c 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_txq.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_txq.h @@ -393,5 +393,6 @@ void rwnx_txq_confirm_any(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq, void rwnx_hwq_init(struct rwnx_hw *rwnx_hw); void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq); void rwnx_hwq_process_all(struct rwnx_hw *rwnx_hw); +void rwnx_txq_flush(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq); #endif /* _RWNX_TXQ_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_utils.h b/drivers/aic8800/aic8800_fdrv/rwnx_utils.h index 402fb39..5db221c 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_utils.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_utils.h @@ -131,6 +131,7 @@ struct rwnx_ipc_rxbuf_elems { struct sk_buff *skb[RWNX_RXBUFF_MAX]; int idx; }; +int rwnx_init_aic(struct rwnx_hw *rwnx_hw); #endif /* CONFIG_RWNX_FULLMAC */ #endif /* _RWNX_IPC_UTILS_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_version_gen.h b/drivers/aic8800/aic8800_fdrv/rwnx_version_gen.h index b58a50b..561759d 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_1018_71b66e7b" +#define RELEASE_DATE "2026_0123_5f7be68d" diff --git a/drivers/aic8800/aic8800_fdrv/usb_host.h b/drivers/aic8800/aic8800_fdrv/usb_host.h index 70b7eb2..4e7b279 100644 --- a/drivers/aic8800/aic8800_fdrv/usb_host.h +++ b/drivers/aic8800/aic8800_fdrv/usb_host.h @@ -39,5 +39,6 @@ extern void aicwf_usb_host_txdesc_push(struct usb_host_env_tag *env, const int q extern void aicwf_usb_host_tx_cfm_handler(struct usb_host_env_tag *env, u32 *data); extern int aicwf_rwnx_usb_platform_init(struct aic_usb_dev *usbdev); +volatile struct txdesc_host *aicwf_usb_host_txdesc_get(struct usb_host_env_tag *env, const int queue_idx); #endif diff --git a/drivers/aic8800/aic_btusb/Makefile b/drivers/aic8800/aic_btusb/Makefile index 5cc9e57..61ec3d0 100644 --- a/drivers/aic8800/aic_btusb/Makefile +++ b/drivers/aic8800/aic_btusb/Makefile @@ -1,9 +1,9 @@ MODULE_NAME = aic_btusb -CONFIG_AIC8800_BTUSB_SUPPORT ?= m -CONFIG_SUPPORT_VENDOR_APCF ?= n +CONFIG_AIC8800_BTUSB_SUPPORT = m +CONFIG_SUPPORT_VENDOR_APCF = n # Need to set fw path in BOARD_KERNEL_CMDLINE -CONFIG_USE_FW_REQUEST ?= n +CONFIG_USE_FW_REQUEST = n ifeq ($(CONFIG_SUPPORT_VENDOR_APCF), y) obj-$(CONFIG_AIC8800_BTUSB_SUPPORT) := $(MODULE_NAME).o aic_btusb_external_featrue.o @@ -53,17 +53,13 @@ endif ifeq ($(CONFIG_PLATFORM_UBUNTU), y) ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU -ifndef KDIR KDIR := /lib/modules/$(shell uname -r)/build -endif PWD := $(shell pwd) -ifndef KVER KVER := $(shell uname -r) -endif 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 ?= +CROSS_COMPILE := endif ifeq ($(CONFIG_PLATFORM_MTK_LINUX), y) diff --git a/drivers/aic8800/aic_btusb/aic_btusb.c b/drivers/aic8800/aic_btusb/aic_btusb.c index 5eb0d80..185fcc6 100644 --- a/drivers/aic8800/aic_btusb/aic_btusb.c +++ b/drivers/aic8800/aic_btusb/aic_btusb.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "aic_btusb.h" @@ -48,7 +49,6 @@ #define AICBT_RELEASE_NAME "202012_ANDROID" #define VERSION "2.1.0" -#define SUSPNED_DW_FW 0 static spinlock_t queue_lock; @@ -62,14 +62,22 @@ static volatile uint16_t dlfw_dis_state = 0; #define USB_PRODUCT_ID_AIC8800DC 0x88dc #define USB_PRODUCT_ID_AIC8800D80 0x8d81 #define USB_PRODUCT_ID_AIC8800D80X2 0x8d91 -#define USB_PRODUCT_ID_AIC8800M80 0x8d83 +#define USB_PRODUCT_ID_AIC8800D80X2P 0x8da1 +#define USB_PRODUCT_ID_AIC8800D80N 0x8d45 +#define USB_PRODUCT_ID_AIC8800D80LN 0x8d46 +#define USB_PRODUCT_ID_AIC8800D40N 0x8d48 +#define USB_PRODUCT_ID_AIC8800D40LN 0x8d49 +#define USB_PRODUCT_ID_AIC8800DLN 0x8871 enum AICWF_IC{ PRODUCT_ID_AIC8801 = 0, PRODUCT_ID_AIC8800DC, PRODUCT_ID_AIC8800DW, + PRODUCT_ID_AIC8800DLN, + PRODUCT_ID_AIC8800D80N, PRODUCT_ID_AIC8800D80, - PRODUCT_ID_AIC8800D80X2 + PRODUCT_ID_AIC8800D80X2, + PRODUCT_ID_MAX, }; u16 g_chipid = PRODUCT_ID_AIC8801; @@ -78,7 +86,9 @@ u8 sub_chip_id = 0; int btdual = 0; int bt_support = 0; +int testmode = 0; +module_param(testmode, int, 0660); module_param(btdual, int, 0660); module_param(bt_support, int, 0660); @@ -139,24 +149,11 @@ struct btusb_data { struct notifier_block reboot_notifier; #endif firmware_info *fw_info; - -#ifdef CONFIG_SCO_OVER_HCI - AIC_sco_card_t *pSCOSnd; -#endif }; #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 1) static bool reset_on_close = 0; #endif -#ifdef CONFIG_SCO_OVER_HCI -struct snd_sco_cap_timer { - struct timer_list cap_timer; - struct timer_list play_timer; - struct btusb_data snd_usb_data; - int snd_sco_length; -}; -static struct snd_sco_cap_timer snd_cap_timer; -#endif #ifdef CONFIG_SUPPORT_VENDOR_APCF int vendor_apcf_sent_done = 0; @@ -164,6 +161,12 @@ int vendor_apcf_sent_done = 0; const struct aicbt_firmware *aicbt_fw; +static int aic_load_firmware(u8 ** fw_buf, const char *name, struct device *device); +static int aicbt_patch_table_free(struct aicbt_patch_table **head); +static int download_patch(firmware_info *fw_info, int cached); +static int rwnx_send_dbg_mem_write_req(firmware_info *fw_info, u32 mem_addr, u32 mem_data); + + static inline int check_set_dlfw_state_value(uint16_t change_value) { spin_lock(&dlfw_lock); @@ -411,6 +414,7 @@ enum CODEC_TYPE{ static enum CODEC_TYPE codec_type = CODEC_CVSD; static void set_select_msbc(enum CODEC_TYPE type); static enum CODEC_TYPE check_select_msbc(void); +int send_hci_cmd(firmware_info *fw_info); #if CONFIG_BLUEDROID @@ -427,11 +431,25 @@ static struct cdev bt_char_dev; /* bt character device structure */ static struct class *bt_char_class; /* device class for usb char driver */ static int bt_reset = 0; static int aic_queue_cnt(void); +static void aic_enqueue(struct sk_buff *skb); /* HCI device & lock */ DEFINE_RWLOCK(hci_dev_lock); struct hci_dev *ghdev = NULL; +#ifdef CONFIG_BT_WAKEUP_IN_PM +static bool aic_store_acl_handle(uint16_t handle); +static bool aic_check_store_handle(uint16_t handle); +static void aic_clean_store_acl_handle(uint16_t handle); +static void aic_clean_all_store_acl_handle(void); +static int aic_handle_cmd(struct sk_buff *skb); +static uint8_t ble_scan_en[10]={0x00,0x42,0x20,0x06,0x01,0x00,0x00,0x00,0x00,0x00}; +static uint8_t bt_scan_en[5]={0x00,0x1a,0x0c,0x01,0x03}; +static uint8_t ble_create_con[62]={0x00,0x43,0x20,0x3a,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,\ + 0x60,0x00,0x30,0x00,0x09,0x00,0x09,0x00,0x00,0x00,0xf4,0x01,0x00,0x00,0x00,0x00,\ + 0x60,0x00,0x30,0x00,0x09,0x00,0x09,0x00,0x00,0x00,0xf4,0x01,0x00,0x00,0x00,0x00,\ + 0x60,0x00,0x30,0x00,0x09,0x00,0x09,0x00,0x00,0x00,0xf4,0x01,0x00,0x00,0x00,0x00}; +#endif static int bypass_event(struct sk_buff *skb) { int ret = 0; @@ -481,9 +499,65 @@ static int bypass_event(struct sk_buff *skb) } } break; +#ifdef CONFIG_BT_WAKEUP_IN_PM + case HCI_BLE_CONN_COMPLETE_EVT: + { + uint8_t status = opcode[3]; + uint16_t handle; + uint8_t *ptr = &opcode[4]; + printk("%s: HCI_BLE_CONN_COMPLETE_EVT(0x%02x)", __func__, *opcode); + handle = ((uint16_t)(*(ptr)) | (((uint16_t)(*((ptr) + 1))) << 8)); + if(status == 0){ + aic_store_acl_handle(handle); + } + ble_create_con[0]=0; + } + break; + case HCI_BLE_ENHANCED_CONN_COMPLETE_EVT: + { + uint8_t status = opcode[3]; + uint16_t handle; + uint8_t *ptr = &opcode[4]; + printk("%s: HCI_BLE_ENHANCED_CONN_COMPLETE_EVT(0x%02x)", __func__, *opcode); + handle = ((uint16_t)(*(ptr)) | (((uint16_t)(*((ptr) + 1))) << 8)); + if(status == 0){ + aic_store_acl_handle(handle); + } + ble_create_con[0]=0; + } + break; +#endif//CONFIG_BT_WAKEUP_IN_PM + default: + break; } } break; +#ifdef CONFIG_BT_WAKEUP_IN_PM + case HCI_EV_CONN_COMPLETE: + { + uint8_t status; + uint16_t handle; + printk("%s: HCI_EV_SYNC_CONN_COMPLETE(0x%02x)", __func__, *opcode); + status = *(opcode + 2); + handle = *(opcode + 3) | *(opcode + 4) << 8; + if(status == 0){ + aic_store_acl_handle(handle); + } + } + break; + case HCI_EV_DISCONN_COMPLETE: + { + uint8_t status; + uint16_t handle; + printk("%s: HCI_EV_DISCONN_COMPLETE(0x%02x)", __func__, *opcode); + status = *(opcode + 2); + handle = *(opcode + 3) | *(opcode + 4) << 8; + if(aic_check_store_handle(handle)){ + aic_clean_store_acl_handle(handle); + } + } + break; +#endif//CONFIG_BT_WAKEUP_IN_PM default: break; } @@ -688,9 +762,9 @@ static inline int is_queue_empty(void) static void aic_clear_queue(void) { struct sk_buff *skb; - unsigned long flags = 0; - - spin_lock_irqsave(&queue_lock, flags); + unsigned long flags = 0; + AICBT_INFO("aic_clear_queue: %s\n", __func__); + spin_lock_irqsave(&queue_lock, flags); while(!is_queue_empty()) { skb = aic_skb_queue[aic_skb_queue_front]; aic_skb_queue[aic_skb_queue_front] = NULL; @@ -790,71 +864,6 @@ static int hci_dev_close(__u16 dev) return err; } -#ifdef CONFIG_SCO_OVER_HCI -/* copy data from the URB buffer into the ALSA ring buffer */ -static bool aic_copy_capture_data_to_alsa(struct btusb_data *data, uint8_t* p_data, unsigned int frames) -{ - struct snd_pcm_runtime *runtime; - unsigned int frame_bytes, frames1; - u8 *dest; - AIC_sco_card_t *pSCOSnd = data->pSCOSnd; - - runtime = pSCOSnd->capture.substream->runtime; - frame_bytes = 2; - - dest = runtime->dma_area + pSCOSnd->capture.buffer_pos * frame_bytes; - if (pSCOSnd->capture.buffer_pos + frames <= runtime->buffer_size) { - memcpy(dest, p_data, frames * frame_bytes); - } else { - /* wrap around at end of ring buffer */ - frames1 = runtime->buffer_size - pSCOSnd->capture.buffer_pos; - memcpy(dest, p_data, frames1 * frame_bytes); - memcpy(runtime->dma_area, - p_data + frames1 * frame_bytes, - (frames - frames1) * frame_bytes); - } - - pSCOSnd->capture.buffer_pos += frames; - if (pSCOSnd->capture.buffer_pos >= runtime->buffer_size) { - pSCOSnd->capture.buffer_pos -= runtime->buffer_size; - } - - if((pSCOSnd->capture.buffer_pos%runtime->period_size) == 0) { - snd_pcm_period_elapsed(pSCOSnd->capture.substream); - } - - return false; -} - - -static void hci_send_to_alsa_ringbuffer(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct btusb_data *data = GET_DRV_DATA(hdev); - AIC_sco_card_t *pSCOSnd = data->pSCOSnd; - uint8_t* p_data; - int sco_length = skb->len - HCI_SCO_HDR_SIZE; - u16 *handle = (u16 *) (skb->data); - //u8 errflg = (u8)((*handle & 0x3000) >> 12); - - pSCOSnd->usb_data->sco_handle = (*handle & 0x0fff); - - AICBT_DBG("%s, %x, %x %x\n", __func__,pSCOSnd->usb_data->sco_handle, *handle, errflg); - - if (!hdev) { - AICBT_INFO("%s: Frame for unknown HCI device", __func__); - return; - } - - if (!test_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states)) { - AICBT_INFO("%s: ALSA is not running", __func__); - return; - } - snd_cap_timer.snd_sco_length = sco_length; - p_data = (uint8_t *)skb->data + HCI_SCO_HDR_SIZE; - aic_copy_capture_data_to_alsa(data, p_data, sco_length/2); -} - -#endif #if CONFIG_BLUEDROID static struct hci_dev *hci_alloc_dev(void) @@ -986,19 +995,6 @@ static int hci_recv_frame(struct sk_buff *skb) __net_timestamp(skb); if (atomic_read(&hdev->promisc)) { -#ifdef CONFIG_SCO_OVER_HCI - if(bt_cb(skb)->pkt_type == HCI_SCODATA_PKT){ - hci_send_to_alsa_ringbuffer(hdev, skb); - }else{ - if(bt_cb(skb)->pkt_type == HCI_EVENT_PKT){ - if(bypass_event(skb)){ - kfree_skb(skb); - return 0; - } - } - hci_send_to_stack(hdev, skb); - } -#else if(bt_cb(skb)->pkt_type == HCI_EVENT_PKT){ if(bypass_event(skb)){ kfree_skb(skb); @@ -1007,8 +1003,6 @@ static int hci_recv_frame(struct sk_buff *skb) } /* Send copy to the sockets */ hci_send_to_stack(hdev, skb); -#endif - } kfree_skb(skb); @@ -1154,7 +1148,7 @@ static int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int cou } #endif //CONFIG_BLUEDROID -void hci_hardware_error(void) +static void hci_hardware_error(void) { struct sk_buff *aic_skb_copy = NULL; int len = 4; @@ -1172,7 +1166,8 @@ void hci_hardware_error(void) wake_up_interruptible(&btchr_read_wait); } -void hci_resume_hardware_error(void) +#if 0 +static void hci_resume_hardware_error(void) { struct sk_buff *aic_skb_copy = NULL; int len = 4; @@ -1189,6 +1184,7 @@ void hci_resume_hardware_error(void) wake_up_interruptible(&btchr_read_wait); } +#endif static int btchr_open(struct inode *inode_p, struct file *file_p) { struct btusb_data *data; @@ -1216,7 +1212,9 @@ static int btchr_open(struct inode *inode_p, struct file *file_p) mutex_lock(&btchr_mutex); hci_dev_open(0); mutex_unlock(&btchr_mutex); - +#ifdef CONFIG_BT_WAKEUP_IN_PM + aic_clean_all_store_acl_handle(); +#endif//CONFIG_BT_WAKEUP_IN_PM aic_clear_queue(); return nonseekable_open(inode_p, file_p); } @@ -1381,6 +1379,9 @@ static ssize_t btchr_write(struct file *file_p, skb->dev = (void *)hdev; bt_cb(skb)->pkt_type = *((__u8 *)skb->data); skb_pull(skb, 1); +#ifdef CONFIG_BT_WAKEUP_IN_PM + aic_handle_cmd(skb); +#endif//CONFIG_BT_WAKEUP_IN_PM data->hdev->send(skb); return count; @@ -1477,16 +1478,16 @@ static long btchr_ioctl(struct file *file_p,unsigned int cmd, unsigned long arg) return 1; case DWFW_CMPLT: AICBT_INFO(" btchr_ioctl DWFW_CMPLT"); -#if 1 - case SET_ISO_CFG: + break; + case SET_ISO_CFG: AICBT_INFO("btchr_ioctl SET_ISO_CFG"); - if(copy_from_user(&(hdev->voice_setting), (__u16*)arg, sizeof(__u16))){ - AICBT_INFO(" voice settings err"); - } - //hdev->voice_setting = *(uint16_t*)arg; - AICBT_INFO(" voice settings = %d", hdev->voice_setting); - //return 1; -#endif + if(copy_from_user(&(hdev->voice_setting), (__u16*)arg, sizeof(__u16))){ + AICBT_INFO(" voice settings err"); + } + //hdev->voice_setting = *(uint16_t*)arg; + AICBT_INFO(" voice settings = %d", hdev->voice_setting); + //return 1; + break; case GET_USB_INFO: //ret = download_patch(fw_info,1); AICBT_INFO(" btchr_ioctl GET_USB_INFO"); @@ -1515,12 +1516,14 @@ static long btchr_ioctl(struct file *file_p,unsigned int cmd, unsigned long arg) } #ifdef CONFIG_PLATFORM_UBUNTU//AIDEN +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) typedef u32 compat_uptr_t; static inline void __user *compat_ptr(compat_uptr_t uptr) { return (void __user *)(unsigned long)uptr; } #endif +#endif #ifdef CONFIG_COMPAT static long compat_btchr_ioctl (struct file *filp, unsigned int cmd, unsigned long arg) @@ -1641,7 +1644,7 @@ int send_hci_cmd(firmware_info *fw_info) } -int rcv_hci_evt(firmware_info *fw_info) +static int rcv_hci_evt(firmware_info *fw_info) { int ret_len = 0, ret_val = 0; int i; @@ -1667,17 +1670,17 @@ int rcv_hci_evt(firmware_info *fw_info) } #ifdef CONFIG_BT_WAKEUP_IN_PM -int rcv_hci_evt_in_pm(firmware_info *fw_info) +static int rcv_hci_evt_in_pm(firmware_info *fw_info, bool is_cmp) { int ret_len = 0, ret_val = 0; int i; while (1) { - for(i = 0; i < 5; i++) { + for(i = 0; i < 2; i++) { ret_val = usb_interrupt_msg( fw_info->udev, fw_info->pipe_in, (void *)(fw_info->rcv_pkt), RCV_PKT_LEN, - &ret_len, 200); + &ret_len, 10); if (ret_val >= 0) break; } @@ -1685,19 +1688,67 @@ int rcv_hci_evt_in_pm(firmware_info *fw_info) if (ret_val < 0) return ret_val; - if (CMD_CMP_EVT == fw_info->evt_hdr->evt) { - if (fw_info->cmd_hdr->opcode == fw_info->cmd_cmp->opcode) - return ret_len; + if (is_cmp){ + if (CMD_CMP_EVT == fw_info->evt_hdr->evt) { + if (fw_info->cmd_hdr->opcode == fw_info->cmd_cmp->opcode) + return ret_len; + } + }else{ + return ret_len; } } } -int set_bt_wakeup_param(firmware_info *fw_info) +static void rcv_ble_wakeup_event(firmware_info *fw_info) +{ + int ret_val = 0; + u8 reportdata[128]; + int i; + + ret_val = rcv_hci_evt_in_pm(fw_info,0); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to receive ble wakeup event, errno %d", + __func__, ret_val); + return; + }else{ + for(i = 0;ircv_pkt[i]; + printk("%x ",fw_info->rcv_pkt[i]); + } + } +} +static int set_bt_ad_filetr_en_param(firmware_info *fw_info) { int ret_val; AICBT_INFO("%s", __func__); + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_SET_ADFILTER_EN_CMD); + fw_info->cmd_hdr->plen = 0; + fw_info->pkt_len = CMD_HDR_LEN ; + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to send bt wakeup param, errno %d", + __func__, ret_val); + return ret_val; + } + + ret_val = rcv_hci_evt_in_pm(fw_info,0); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to receive bt event, errno %d", + __func__, ret_val); + return ret_val; + } + + return ret_val; +} + +static int set_bt_wakeup_param(firmware_info *fw_info) +{ + int ret_val; + struct ble_wakeup_param_t* wakeup_param = NULL; + AICBT_INFO("%s", __func__); + /* data and ad_data_filter_mask instructions for use ex. @@ -1710,14 +1761,14 @@ int set_bt_wakeup_param(firmware_info *fw_info) data & mask = "0x46 0x00" 0x00 0x00 0x00 0x00 0x00 0x00 0x00 "0x30 0xff 0xff 0x43 0x52 0x45 0x4c 0x42" using data & mask value condition to wakeup host_wake_bt gpio */ - struct ble_wakeup_param_t* wakeup_param = (struct ble_wakeup_param_t*)kmalloc(sizeof(struct ble_wakeup_param_t), GFP_KERNEL); + wakeup_param = (struct ble_wakeup_param_t*)kmalloc(sizeof(struct ble_wakeup_param_t), GFP_KERNEL); printk("%s ble scan wakeup \r\n", __func__); memset(wakeup_param, 0, sizeof(struct ble_wakeup_param_t)); wakeup_param->magic_num = 0x53454C42;//magic_num wakeup_param->delay_scan_to = 1000;//delay start scan time(ms) - wakeup_param->reboot_to = 1000;//reboot time(ms): bit31: 1, ic will reboot when timer is handle; 0 , do not reboot + wakeup_param->reboot_to = 0x800003e8;//reboot time(ms): bit31: 1, ic will reboot when timer is handle; 0 , do not reboot // bit0~30 : time(ms) /******************************************************************/ ///gpio_trigger_idx : 0 if wakeup_param->gpio_dft_lvl[0]=0xfe,this idx will be invalid. @@ -1845,7 +1896,7 @@ int set_bt_wakeup_param(firmware_info *fw_info) return ret_val; } - ret_val = rcv_hci_evt_in_pm(fw_info); + ret_val = rcv_hci_evt_in_pm(fw_info,0); if (ret_val < 0) { AICBT_ERR("%s: Failed to receive bt event, errno %d", __func__, ret_val); @@ -1855,11 +1906,12 @@ int set_bt_wakeup_param(firmware_info *fw_info) return ret_val; } -int reset_bt_from_wakeup_process(firmware_info *fw_info) +static int reset_bt_from_wakeup_process(firmware_info *fw_info) { int ret_val; AICBT_INFO("%s", __func__); + rcv_ble_wakeup_event(fw_info); fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_RESET_ADFILTER_PROCESS_PT_CMD); fw_info->cmd_hdr->plen = 0; @@ -1871,8 +1923,9 @@ int reset_bt_from_wakeup_process(firmware_info *fw_info) __func__, ret_val); return ret_val; } + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_OP_RESET); - ret_val = rcv_hci_evt_in_pm(fw_info); + ret_val = rcv_hci_evt_in_pm(fw_info,1); if (ret_val < 0) { AICBT_ERR("%s: Failed to receive bt event, errno %d", __func__, ret_val); @@ -1881,6 +1934,369 @@ int reset_bt_from_wakeup_process(firmware_info *fw_info) return ret_val; } + +uint16_t aic_acl_handle_list[10]; +static void hci_disconnect_complete_event(uint16_t handle,uint8_t reason) +{ + struct sk_buff *aic_skb_copy = NULL; + + int len = 7; + unsigned char p_buf[7] = {HCI_EVENT_PKT, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00}; + p_buf[4] = (unsigned char)(handle & 0x00ff); + p_buf[5] = (unsigned char)((handle & 0xff00)>>8); + p_buf[6] = reason; + printk("%s\n",__func__); + + aic_skb_copy = alloc_skb(len, GFP_ATOMIC); + if (!aic_skb_copy) { + AICBT_ERR("%s: Failed to allocate mem", __func__); + return; + } + + memcpy(skb_put(aic_skb_copy, len), p_buf, len); + aic_enqueue(aic_skb_copy); + + wake_up_interruptible(&btchr_read_wait); +} + +static int hci_disconnect_complete_cmd(firmware_info *fw_info,uint16_t handle,uint8_t reason) +{ + int ret_val = 0; + int len = 3; + unsigned char p_buf[3] = {0x00, 0x00, 0x00}; + + + p_buf[0] = (unsigned char)(handle & 0x00ff); + p_buf[1] = (unsigned char)((handle & 0xff00)>>8); + p_buf[2] = reason; + printk("%s\n",__func__); + + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_OP_DISCONNECT); + fw_info->cmd_hdr->plen = len; + fw_info->pkt_len = CMD_HDR_LEN + len; + memcpy(fw_info->req_para,p_buf,len); + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to send , errno %d", + __func__, ret_val); + return ret_val; + } + + ret_val = rcv_hci_evt_in_pm(fw_info,1); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to receive bt event, errno %d", + __func__, ret_val); + return ret_val; + } + return ret_val; +} + +static bool aic_check_store_handle(uint16_t handle) +{ + bool ret = false; + int i = 0; + for(i = 0 ;i < 10; i++){ + if(aic_acl_handle_list[i] == handle && aic_acl_handle_list[i] != 0){ + ret = true; + break; + } + } + printk("%s,handle = 0x%x,ret = %d\n", __func__,handle,ret); + return ret; +} + +static bool aic_store_acl_handle(uint16_t handle) +{ + bool ret = false; + int i = 0; + for(i = 0 ;i < 10; i++){ + if(aic_acl_handle_list[i] != handle && aic_acl_handle_list[i] == 0){ + aic_acl_handle_list[i] = handle; + ret = true; + break; + } + } + printk("%s,handle = 0x%x,ret = %d\n", __func__,handle,ret); + return ret; +} + +static void aic_clean_store_acl_handle(uint16_t handle) +{ + int i = 0; + printk("%s,handle = 0x%x\n", __func__,handle); + for(i = 0 ;i < 10; i++){ + if(aic_acl_handle_list[i] == handle && aic_acl_handle_list[i] != 0){ + aic_acl_handle_list[i] = 0; + break; + } + } +} + +static void aic_clean_all_store_acl_handle(void) +{ + int i = 0; + for(i = 0 ;i < 10; i++){ + aic_acl_handle_list[i] = 0; + } + printk("%s\n", __func__); +} + +static int aic_event_disconnect_all_store_acl_handle(void) +{ + int i = 0; + int ret = 0; + printk("%s\n", __func__); + for(i = 0 ;i < 10; i++){ + if(aic_acl_handle_list[i] != 0){ + printk("%s,handle = 0x%x\n", __func__,aic_acl_handle_list[i]); + if(aic_acl_handle_list[i]>=0x10){ + hci_disconnect_complete_event(aic_acl_handle_list[i],0x13); + } + aic_clean_store_acl_handle(aic_acl_handle_list[i]); + ret = 1; + } + } + printk("%s ret = %d\n", __func__,ret); + return ret; +} + +static int aic_cmd_disconnect_all_store_acl_handle(firmware_info *fw_info) +{ + int i = 0; + int ret = 0; + printk("%s\n", __func__); + for(i = 0 ;i < 10; i++){ + if(aic_acl_handle_list[i] != 0){ + printk("%s,handle = 0x%x\n", __func__,aic_acl_handle_list[i]); + if(aic_acl_handle_list[i]>=0x10){ + hci_disconnect_complete_cmd(fw_info,aic_acl_handle_list[i],0x13); + } + ret = 1; + } + } + printk("%s ret = %d\n", __func__,ret); + return ret; +} + + +static int aic_cmd_cancel_le_conn(firmware_info *fw_info) +{ + int ret_val = 0; + int len = 0; + printk("%s,ble_create_con %d\n",__func__,ble_create_con[0]); + + if(ble_create_con[0] == 1 ){ + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_OP_LE_Create_Connection_Cancel); + fw_info->cmd_hdr->plen = len; + fw_info->pkt_len = CMD_HDR_LEN + len; + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to send , errno %d", + __func__, ret_val); + } + + ret_val = rcv_hci_evt_in_pm(fw_info,0); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to receive bt event, errno %d", + __func__, ret_val); + } + } + + return ret_val; +} + +static int aic_cmd_reconn_le_conn(firmware_info *fw_info) +{ + int ret_val = 0; + int len = 0; + u16 opcode = 0; + printk("%s,ble_create_con %d\n",__func__,ble_create_con[0]); + + if(ble_create_con[0] == 1 ){ + opcode = (u16)ble_create_con[1]|((u16)ble_create_con[2]<<8); + len = ble_create_con[3]; + AICBT_INFO("%s: opcode 0x%x,len %d",__func__, opcode,len); + fw_info->cmd_hdr->opcode = cpu_to_le16(opcode); + fw_info->cmd_hdr->plen = len; + fw_info->pkt_len = CMD_HDR_LEN + len; + memcpy(fw_info->req_para,&ble_create_con[4],len); + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to send , errno %d", + __func__, ret_val); + } + + ret_val = rcv_hci_evt_in_pm(fw_info,0); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to receive bt event, errno %d", + __func__, ret_val); + } + } + + return ret_val; +} + +static int aic_cmd_disable_scan(firmware_info *fw_info) +{ + int ret_val = 0; + int len = 6; + unsigned char p_buf[6] = {0x01,0x00,0x00,0x00,0x00,0x00}; + + printk("%s,ble_scan_en %d,%d\n",__func__,ble_scan_en[0],ble_scan_en[4]); + + if(ble_scan_en[0] == 1 && ble_scan_en[4] == 1){ + p_buf[0] = 0; + memcpy(&p_buf[1],&ble_scan_en[5],5); + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_OP_LE_Set_Extended_Scan_Enable); + fw_info->cmd_hdr->plen = len; + fw_info->pkt_len = CMD_HDR_LEN + len; + memcpy(fw_info->req_para,p_buf,len); + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to send , errno %d", + __func__, ret_val); + } + + ret_val = rcv_hci_evt_in_pm(fw_info,0); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to receive bt event, errno %d", + __func__, ret_val); + } + } + + + printk("%s,bt_scan_en %d ,%d\n",__func__,bt_scan_en[0],bt_scan_en[4]); + + if(bt_scan_en[0] == 1 && bt_scan_en[4] > 0){ + p_buf[0] = 0; + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_OP_Write_Scan_Enable); + fw_info->cmd_hdr->plen = 1; + fw_info->pkt_len = CMD_HDR_LEN + 1; + memcpy(fw_info->req_para,p_buf,len); + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to send , errno %d", + __func__, ret_val); + } + + ret_val = rcv_hci_evt_in_pm(fw_info,0); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to receive bt event, errno %d", + __func__, ret_val); + } + } + ret_val = aic_cmd_cancel_le_conn(fw_info); + + return ret_val; +} + +static int aic_cmd_enable_scan(firmware_info *fw_info) +{ + int ret_val = 0; + int len = 6; + unsigned char p_buf[6] = {0x01,0x00,0x00,0x00,0x00,0x00}; + + printk("%s,ble_scan_en %d,%d\n",__func__,ble_scan_en[0],ble_scan_en[4]); + + if(ble_scan_en[0] == 1 && ble_scan_en[4] == 1){ + p_buf[0] = 1; + memcpy(&p_buf[1],&ble_scan_en[5],5); + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_OP_LE_Set_Extended_Scan_Enable); + fw_info->cmd_hdr->plen = len; + fw_info->pkt_len = CMD_HDR_LEN + len; + memcpy(fw_info->req_para,p_buf,len); + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to send , errno %d", + __func__, ret_val); + } + + ret_val = rcv_hci_evt_in_pm(fw_info,0); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to receive bt event, errno %d", + __func__, ret_val); + } + } + + printk("%s,bt_scan_en %d,%d\n",__func__,bt_scan_en[0],bt_scan_en[4]); + + if(bt_scan_en[0] == 1 && bt_scan_en[4] > 0){ + p_buf[0] = bt_scan_en[4]; + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_OP_Write_Scan_Enable); + fw_info->cmd_hdr->plen = 1; + fw_info->pkt_len = CMD_HDR_LEN + 1; + memcpy(fw_info->req_para,p_buf,len); + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to send , errno %d", + __func__, ret_val); + } + + ret_val = rcv_hci_evt_in_pm(fw_info,0); + if (ret_val < 0) { + AICBT_ERR("%s: Failed to receive bt event, errno %d", + __func__, ret_val); + } + } + ret_val = aic_cmd_reconn_le_conn(fw_info); + + return ret_val; +} + + +static int aic_handle_cmd(struct sk_buff *skb) +{ + int ret = 0; + u8 *opcode = (u8*)(skb->data); + u16 command; + command = ((u16)opcode[0]|(u16)(opcode[1])<<8); + switch(command){ + case HCI_OP_LE_Set_Extended_Scan_Enable: + { + u8 scan_en = opcode[3]; + if(scan_en){ + ble_scan_en[0]=1; + memcpy(&ble_scan_en[1],opcode,9); + }else{ + ble_scan_en[0]=0; + } + } + break; + case HCI_OP_LE_Set_Extended_Adv_Enable: + break; + case HCI_OP_Write_Scan_Enable: + { + u8 scan_en = opcode[3]; + if(scan_en){ + bt_scan_en[0]=1; + bt_scan_en[4] = scan_en; + }else{ + bt_scan_en[0]=0; + } + } + break; + case HCI_OP_LE_Extended_Create_Connection: + case HCI_OP_LE_Create_Connection: + { + u8 len = opcode[2]; + printk("%s,0x%x,len %d\n",__func__,command,len); + ble_create_con[0]=1; + memcpy(&ble_create_con[1],opcode,len+2); + } + break; + case HCI_OP_LE_Create_Connection_Cancel: + { + printk("%s,0x%x\n",__func__,command); + ble_create_con[0]=0; + } + break; + default: + break; + } + return ret; +} + + #endif //for 8800DC start u32 fwcfg_tbl[][2] = { @@ -1889,7 +2305,7 @@ u32 fwcfg_tbl[][2] = { }; //Crystal provided by CPU (start) -int hci_send_dbg_rd_mem_cmd(firmware_info* fw_info, u32 addr){ +static int hci_send_dbg_rd_mem_cmd(firmware_info* fw_info, u32 addr){ struct hci_dbg_rd_mem_cmd *rd_cmd; struct hci_dbg_rd_mem_cmd_evt *evt_para; @@ -1932,7 +2348,7 @@ int hci_send_dbg_rd_mem_cmd(firmware_info* fw_info, u32 addr){ return 0; } -int set_bbpll_config(firmware_info* fw_info){ +static int set_bbpll_config(firmware_info* fw_info){ int ret_val = -1; struct fw_status *evt_status; struct hci_dbg_rd_mem_cmd_evt *evt_para; @@ -1980,6 +2396,9 @@ int set_bbpll_config(firmware_info* fw_info){ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_UPDATE_PT_CMD); fw_info->cmd_hdr->plen = HCI_VSC_UPDATE_PT_SIZE; + if (g_chipid == PRODUCT_ID_AIC8800D80N) { + fw_info->cmd_hdr->plen = HCI_VSC_UPDATE_PT_V2_SIZE; + } fw_info->pkt_len = fw_info->cmd_hdr->plen + 3; ret_val = send_hci_cmd(fw_info); if (ret_val < 0) { @@ -2006,7 +2425,7 @@ int set_bbpll_config(firmware_info* fw_info){ //Crystal provided by CPU (end) -int fw_config(firmware_info* fw_info) +static int fw_config(firmware_info* fw_info) { int ret_val = -1; struct hci_dbg_rd_mem_cmd *rd_cmd; @@ -2093,7 +2512,7 @@ int fw_config(firmware_info* fw_info) return ret_val; } -int system_config(firmware_info *fw_info) +static int system_config(firmware_info *fw_info) { int ret_val = -1; struct hci_dbg_rd_mem_cmd *rd_cmd; @@ -2190,7 +2609,7 @@ int system_config(firmware_info *fw_info) return ret_val; } -int check_fw_status(firmware_info* fw_info) +static int check_fw_status(firmware_info* fw_info) { struct fw_status *read_ver_rsp; int ret_val = -1; @@ -2221,7 +2640,7 @@ int check_fw_status(firmware_info* fw_info) } -int download_data(firmware_info *fw_info, u32 fw_addr, const char *filename) +static int download_data(firmware_info *fw_info, u32 fw_addr, const char *filename) { unsigned int i=0; int size; @@ -2230,11 +2649,15 @@ int download_data(firmware_info *fw_info, u32 fw_addr, const char *filename) struct hci_dbg_wr_mem_cmd *dl_cmd; int hdr_len = sizeof(__le32) + sizeof(__u8) + sizeof(__u8); int data_len = HCI_VSC_MEM_WR_SIZE; + int mem_wr_size = HCI_VSC_MEM_WR_SIZE; int frag_len = data_len + hdr_len; int ret_val; int ncmd = 1; struct fw_status *evt_para; + if (g_chipid == PRODUCT_ID_AIC8800D80N) { + mem_wr_size = HCI_VSC_MEM_WR_V2_SIZE; + } /* load aic firmware */ size = aic_load_firmware(&dst, filename, NULL); if(size <= 0){ @@ -2252,9 +2675,9 @@ int download_data(firmware_info *fw_info, u32 fw_addr, const char *filename) /* Copy the file on the Embedded side */ printk("### Upload %s firmware, @ = %x size=%d\n", filename, fw_addr, size); - if (size > HCI_VSC_MEM_WR_SIZE) {// > 1KB data - for (i = 0; i < (size - HCI_VSC_MEM_WR_SIZE); i += HCI_VSC_MEM_WR_SIZE) {//each time write 240 bytes - data_len = HCI_VSC_MEM_WR_SIZE; + if (size > mem_wr_size) {// > 1KB data + for (i = 0; i < (size - mem_wr_size); i += mem_wr_size) {//each time write 240 bytes + data_len = mem_wr_size; frag_len = data_len + hdr_len; memcpy(dl_cmd->data, dst + i, data_len); dl_cmd->length = data_len; @@ -2375,6 +2798,7 @@ enum aicbt_btmode_type { AICBT_BTMODE_BT_ONLY, // bt only mode without switch AICBT_BTMODE_BT_ONLY_TEST, // bt only test mode AICBT_BTMODE_BT_WIFI_COMBO_TEST, // wifi/bt combo test mode + AICBT_BTMODE_BT_ONLY_COANT, AICBT_MODE_NULL = 0xFF, // invalid value }; @@ -2399,9 +2823,11 @@ enum aicbt_uart_flowctrl_type { #define AICBSP_HWINFO_DEFAULT (-1) #define AICBSP_CPMODE_DEFAULT AICBSP_CPMODE_WORK #define AICBT_TXPWR_DFT 0x6F2F +#define AICBT_TXPWR_RF_DFT 0x7F0F #define AICBT_BTMODE_DEFAULT AICBT_BTMODE_BT_WIFI_COMBO +#define AICBT_BTMODE_DEFAULT_D80N AICBT_BTMODE_BT_ONLY #define AICBT_BTPORT_DEFAULT AICBT_BTPORT_MB #define AICBT_UART_BAUD_DEFAULT AICBT_UART_BAUD_1_5M #define AICBT_UART_FC_DEFAULT AICBT_UART_FLOWCTRL_ENABLE @@ -2417,13 +2843,14 @@ struct aicbsp_info_t aicbsp_info = { #define FW_PATH_MAX 200 char aic_fw_path[FW_PATH_MAX]; -#if (CONFIG_BLUEDROID == 0) -static const char* aic_default_fw_path = "/lib/firmware/aic8800DC"; +#if (CONFIG_BLUEDROID == 0) || defined (CONFIG_PLATFORM_UBUNTU) +static const char* aic_default_fw_path = "/lib/firmware"; #else static const char* aic_default_fw_path = "/vendor/etc/firmware"; #endif #endif //CONFIG_USE_FW_REQUEST +#if 0 static struct aicbt_info_t aicbt_info = { .btmode = AICBT_BTMODE_DEFAULT, .btport = AICBT_BTPORT_DEFAULT, @@ -2432,11 +2859,42 @@ static struct aicbt_info_t aicbt_info = { .lpm_enable = AICBT_LPM_ENABLE_DEFAULT, .txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT, }; +#endif +static struct aicbt_info_t aicbt_info[] = { + { + },//PRODUCT_ID_AIC8801 + { + .btmode = AICBT_BTMODE_DEFAULT, + .btport = AICBT_BTPORT_DEFAULT, + .uart_baud = AICBT_UART_BAUD_DEFAULT, + .uart_flowctrl = AICBT_UART_FC_DEFAULT, + .lpm_enable = AICBT_LPM_ENABLE_DEFAULT, + .txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT, + },//PRODUCT_ID_AIC8800DC + { + },//PRODUCT_ID_AIC8800DW + { + },//PRODUCT_ID_AIC8800DLN + { + .btmode = AICBT_BTMODE_DEFAULT_D80N, + .btport = AICBT_BTPORT_DEFAULT, + .uart_baud = AICBT_UART_BAUD_DEFAULT, + .uart_flowctrl = AICBT_UART_FC_DEFAULT, + .lpm_enable = AICBT_LPM_ENABLE_DEFAULT, + .txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT, + },//PRODUCT_ID_AIC8800D80N + { + },//PRODUCT_ID_AIC8800D80 + { + },//PRODUCT_ID_AIC8800D80X2 +}; -int patch_table_load(firmware_info *fw_info, struct aicbt_patch_table *_head) + +static int patch_table_load(firmware_info *fw_info, struct aicbt_patch_table *_head) { struct aicbt_patch_table *head, *p; int i; + int ret = 0; uint32_t *data = NULL; struct aicbt_patch_table_cmd *patch_table_cmd = (struct aicbt_patch_table_cmd *)(fw_info->req_para); struct fw_status *evt_para; @@ -2451,20 +2909,23 @@ int patch_table_load(firmware_info *fw_info, struct aicbt_patch_table *_head) *(data + 1) = aicbsp_info.hwinfo < 0; *(data + 3) = aicbsp_info.hwinfo; *(data + 5) = aicbsp_info.cpmode; + if (g_chipid < PRODUCT_ID_MAX) { + if(testmode == 1) { + aicbt_info[g_chipid].txpwr_lvl = AICBT_TXPWR_RF_DFT; + } + *(data + 7) = aicbt_info[g_chipid].btmode; + *(data + 9) = aicbt_info[g_chipid].btport; + *(data + 11) = aicbt_info[g_chipid].uart_baud; + *(data + 13) = aicbt_info[g_chipid].uart_flowctrl; + *(data + 15) = aicbt_info[g_chipid].lpm_enable; + *(data + 17) = aicbt_info[g_chipid].txpwr_lvl; - *(data + 7) = aicbt_info.btmode; - *(data + 9) = aicbt_info.btport; - *(data + 11) = aicbt_info.uart_baud; - *(data + 13) = aicbt_info.uart_flowctrl; - *(data + 15) = aicbt_info.lpm_enable; - *(data + 17) = aicbt_info.txpwr_lvl; - - printk("%s bt btmode:%d \r\n", __func__, aicbt_info.btmode); - printk("%s bt uart_baud:%d \r\n", __func__, aicbt_info.uart_baud); - printk("%s bt uart_flowctrl:%d \r\n", __func__, aicbt_info.uart_flowctrl); - printk("%s bt lpm_enable:%d \r\n", __func__, aicbt_info.lpm_enable); - printk("%s bt tx_pwr:%d \r\n", __func__, aicbt_info.txpwr_lvl); - + printk("%s bt btmode:%d \r\n", __func__, aicbt_info[g_chipid].btmode); + printk("%s bt uart_baud:%d \r\n", __func__, aicbt_info[g_chipid].uart_baud); + printk("%s bt uart_flowctrl:%d \r\n", __func__, aicbt_info[g_chipid].uart_flowctrl); + printk("%s bt lpm_enable:%d \r\n", __func__, aicbt_info[g_chipid].lpm_enable); + printk("%s bt tx_pwr:%d \r\n", __func__, aicbt_info[g_chipid].txpwr_lvl); + } } if (p->type == AICBT_PT_INF || p->type == AICBT_PT_PWRON) { @@ -2491,36 +2952,46 @@ int patch_table_load(firmware_info *fw_info, struct aicbt_patch_table *_head) memcpy(&patch_table_cmd->patch_table_addr[i], data, sizeof(uint32_t)); memcpy(&patch_table_cmd->patch_table_data[i], data + 1, sizeof(uint32_t)); //printk("[%d] data: %08x %08x\n", i, patch_table_cmd->patch_table_addr[i],patch_table_cmd->patch_table_data[i]); + if (g_chipid == PRODUCT_ID_AIC8800D80N) { + ret = rwnx_send_dbg_mem_write_req(fw_info, patch_table_cmd->patch_table_addr[i],patch_table_cmd->patch_table_data[i]); + if (ret) { + printk("%s err %d\n", __func__, ret); + break; + } + } data += 2; } tot_len -= len; - evt_para = (struct fw_status *)fw_info->rsp_para; - //print_hex_dump(KERN_ERR,"data0:",DUMP_PREFIX_NONE,16,1,patch_table_cmd,sizeof(struct aicbt_patch_table_cmd),false); + if (g_chipid == PRODUCT_ID_AIC8800DC) + { + evt_para = (struct fw_status *)fw_info->rsp_para; + //print_hex_dump(KERN_ERR,"data0:",DUMP_PREFIX_NONE,16,1,patch_table_cmd,sizeof(struct aicbt_patch_table_cmd),false); - //printk("patch num %x %d\n", patch_table_cmd->patch_num, (int)sizeof(struct aicbt_patch_table_cmd)); - fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_UPDATE_PT_CMD); - fw_info->cmd_hdr->plen = HCI_VSC_UPDATE_PT_SIZE; - fw_info->pkt_len = fw_info->cmd_hdr->plen + 3; - AICBT_DBG("patch num 0x%x, plen 0x%x\n", patch_table_cmd->patch_num, fw_info->cmd_hdr->plen ); - //print_hex_dump(KERN_ERR,"patch table:",DUMP_PREFIX_NONE,16,1,fw_info->send_pkt,32,false); - ret_val = send_hci_cmd(fw_info); - while (ncmd > 0) { - ret_val = rcv_hci_evt(fw_info); - //printk("%s ret_val:%d \r\n", __func__, ret_val); - if (ret_val < 0) { - AICBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val); - goto out; - } else { - AICBT_DBG("%s: Receive acked frag num %d", __func__, evt_para->status); - ncmd--; - } - if (0 != evt_para->status) { - AICBT_ERR("%s: Receive acked frag num %d, err status %d", - __func__, ret_val, evt_para->status); - ret_val = -1; - goto out; - }else{ - ret_val = 0; + //printk("patch num %x %d\n", patch_table_cmd->patch_num, (int)sizeof(struct aicbt_patch_table_cmd)); + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_UPDATE_PT_CMD); + fw_info->cmd_hdr->plen = HCI_VSC_UPDATE_PT_SIZE; + fw_info->pkt_len = fw_info->cmd_hdr->plen + 3; + AICBT_DBG("patch num 0x%x, plen 0x%x\n", patch_table_cmd->patch_num, fw_info->cmd_hdr->plen ); + //print_hex_dump(KERN_ERR,"patch table:",DUMP_PREFIX_NONE,16,1,fw_info->send_pkt,32,false); + ret_val = send_hci_cmd(fw_info); + while (ncmd > 0) { + ret_val = rcv_hci_evt(fw_info); + //printk("%s ret_val:%d \r\n", __func__, ret_val); + if (ret_val < 0) { + AICBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val); + goto out; + } else { + AICBT_DBG("%s: Receive acked frag num %d", __func__, evt_para->status); + ncmd--; + } + if (0 != evt_para->status) { + AICBT_ERR("%s: Receive acked frag num %d, err status %d", + __func__, ret_val, evt_para->status); + ret_val = -1; + goto out; + }else{ + ret_val = 0; + } } } ncmd = 1; @@ -2533,7 +3004,7 @@ out: } -int aic_load_firmware(u8 ** fw_buf, const char *name, struct device *device) +static int aic_load_firmware(u8 ** fw_buf, const char *name, struct device *device) { #ifdef CONFIG_USE_FW_REQUEST @@ -2592,7 +3063,17 @@ int aic_load_firmware(u8 ** fw_buf, const char *name, struct device *device) printk("%s: use customer define fw_path\n", __func__); len = snprintf(path, FW_PATH_MAX, "%s/%s", aic_fw_path, name); } else { +#if (CONFIG_BLUEDROID == 0) || defined (CONFIG_PLATFORM_UBUNTU) + if (g_chipid == PRODUCT_ID_AIC8800DC) { + len = snprintf(path, FW_PATH_MAX, "%s/%s/%s",aic_default_fw_path, "aic8800DC", name); + } else if (g_chipid == PRODUCT_ID_AIC8800D80N) { + len = snprintf(path, FW_PATH_MAX, "%s/%s/%s",aic_default_fw_path, "aic8800D80N", name); + } else { + printk("%s unknown chipid %d\n", __func__, g_chipid); + } +#else len = snprintf(path, FW_PATH_MAX, "%s/%s",aic_default_fw_path, name); +#endif } if (len >= FW_PATH_MAX) { @@ -2675,7 +3156,7 @@ int aic_load_firmware(u8 ** fw_buf, const char *name, struct device *device) #endif } -int aicbt_patch_table_free(struct aicbt_patch_table **head) +static int aicbt_patch_table_free(struct aicbt_patch_table **head) { struct aicbt_patch_table *p = *head, *n = NULL; while (p) { @@ -2689,7 +3170,7 @@ int aicbt_patch_table_free(struct aicbt_patch_table **head) return 0; } -struct aicbt_patch_table *aicbt_patch_table_alloc(const char *filename) +static struct aicbt_patch_table *aicbt_patch_table_alloc(const char *filename) { uint8_t *rawdata = NULL, *p; int size; @@ -2759,7 +3240,7 @@ err: } -int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t) +static int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t) { uint8_t *patch_info_array = (uint8_t*)patch_info; int base_len = 0; @@ -2803,7 +3284,7 @@ int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_ return 0; } -int rwnx_send_dbg_mem_write_req(firmware_info *fw_info, u32 mem_addr, u32 mem_data){ +static int rwnx_send_dbg_mem_write_req(firmware_info *fw_info, u32 mem_addr, u32 mem_data){ int ret_val = -1; struct hci_dbg_wr_mem_cmd *dl_cmd; int data_len = 4; @@ -2846,7 +3327,7 @@ int rwnx_send_dbg_mem_write_req(firmware_info *fw_info, u32 mem_addr, u32 mem_da return ret_val; } -int aicbt_ext_patch_data_load(firmware_info *fw_info, struct aicbt_patch_info_t *patch_info) +static int aicbt_ext_patch_data_load(firmware_info *fw_info, struct aicbt_patch_info_t *patch_info) { int ret = 0; uint32_t ext_patch_nb = patch_info->ext_patch_nb; @@ -2855,19 +3336,7 @@ int aicbt_ext_patch_data_load(firmware_info *fw_info, struct aicbt_patch_info_t uint32_t id = 0; uint32_t addr = 0; - if (ext_patch_nb > 0){ - - printk("%s [0x40506004]: 0x04318000\r\n", __func__); - ret = rwnx_send_dbg_mem_write_req(fw_info, 0x40506004, 0x04318000); - printk("%s [0x40506004]: 0x04338000\r\n", __func__); - ret = rwnx_send_dbg_mem_write_req(fw_info, 0x40506004, 0x04338000); - - if(ret < 0){ - printk("%s set dc enable fail\r\n", __func__); - return ret; - } - for (index = 0; index < patch_info->ext_patch_nb; index++){ id = *(patch_info->ext_patch_param + (index * 2)); addr = *(patch_info->ext_patch_param + (index * 2) + 1); @@ -2890,7 +3359,7 @@ int aicbt_ext_patch_data_load(firmware_info *fw_info, struct aicbt_patch_info_t } -int aicbt_patch_trap_data_load(firmware_info *fw_info, struct aicbt_patch_table *head) +static int aicbt_patch_trap_data_load(firmware_info *fw_info, struct aicbt_patch_table *head) { int ret_val; @@ -2927,10 +3396,117 @@ int aicbt_patch_trap_data_load(firmware_info *fw_info, struct aicbt_patch_table return 0; } -int download_patch(firmware_info *fw_info, int cached) +#define ROM_FMAC_BTUSB_ADDR_8800D80N_U02 0x00132c00 +#define ROM_FMAC_CINIT_ADDR_8800D80N_U02 0x00133000 + +#define CHIP_INFO_FLAG_CINIT_BEGIN (0x01U << 12) +#define CHIP_INFO_FLAG_CINIT_DONE (0x01U << 13) + +enum { + HOST_START_APP_AUTO = 1, + HOST_START_APP_CUSTOM, + HOST_START_APP_REBOOT, + HOST_START_APP_FNCALL = 4, + HOST_START_APP_DUMMY = 5, +}; + +static int hci_send_wf_cinit_exec_cmd(firmware_info* fw_info) +{ + int ret = 0; + struct wf_start_app_param start_app_param; + start_app_param.bootaddr = ROM_FMAC_CINIT_ADDR_8800D80N_U02 + 0x0009; + start_app_param.boottype = HOST_START_APP_FNCALL; + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_WF_START_APP_CMD); + fw_info->cmd_hdr->plen = sizeof(struct wf_start_app_param); + fw_info->pkt_len = CMD_HDR_LEN + sizeof(struct wf_start_app_param); + memcpy(fw_info->req_para, &start_app_param,sizeof(struct wf_start_app_param)); + printk("%s wf start_app exec cinit\r\n", __func__); + ret = send_hci_cmd(fw_info); + if (ret < 0) { + AICBT_ERR("%s: Failed to send wf start_app_param, errno %d\r\n", __func__, ret); + return ret; + } + return ret; +} + +static int aicbt_wf_cinit_data_load(firmware_info *fw_info) +{ + int ret = 0; + uint32_t addr = 0; + addr = ROM_FMAC_CINIT_ADDR_8800D80N_U02; + printk("%s wf cinit:%s addr:%x\r\n", __func__, aicbt_fw->wf_cinit, addr); + ret = download_data(fw_info, addr, aicbt_fw->wf_cinit); + if (ret < 0) { + printk("%s download wf cinit error, ret:%d\r\n", __func__, ret); + return ret; + } + addr = ROM_FMAC_BTUSB_ADDR_8800D80N_U02; + printk("%s wf btusb:%s addr:%x\r\n", __func__, aicbt_fw->wf_btusb, addr); + ret = download_data(fw_info, addr, aicbt_fw->wf_btusb); + if (ret < 0) { + printk("%s download wf btusb error, ret:%d\r\n", __func__, ret); + return ret; + } + printk("%s patch btusb\r\n", __func__); + ret = rwnx_send_dbg_mem_write_req(fw_info, 0x00113564, ROM_FMAC_BTUSB_ADDR_8800D80N_U02 + 0x0009); + if (ret) { + printk("%s patch btusb error, ret:%d\r\n", __func__, ret); + return ret; + } + return ret; +} + +static int aicbt_wf_cinit_exec(firmware_info *fw_info) +{ + int ret_val = 0; + struct hci_dbg_rd_mem_cmd_evt *evt_para; + uint32_t chipinfo_val; + //Read chipinfo + ret_val = hci_send_dbg_rd_mem_cmd(fw_info, 0x40500184); + if(ret_val < 0){ + printk("%s error ret_val:%d\r\n", __func__, ret_val); + return ret_val; + } + evt_para = (struct hci_dbg_rd_mem_cmd_evt *)(fw_info->rsp_para); + chipinfo_val = ( (uint32_t)evt_para->data[0] | + ((uint32_t)evt_para->data[1] << 8) | + ((uint32_t)evt_para->data[2] << 16) | + ((uint32_t)evt_para->data[3] << 24)); + if (chipinfo_val & CHIP_INFO_FLAG_CINIT_BEGIN) { + while (!(chipinfo_val & CHIP_INFO_FLAG_CINIT_DONE)) { + printk("%s chipinfo_val=%d\r\n", __func__, chipinfo_val); + ret_val = hci_send_dbg_rd_mem_cmd(fw_info, 0x40500184); + if(ret_val < 0){ + printk("%s error ret_val:%d\r\n", __func__, ret_val); + return ret_val; + } + evt_para = (struct hci_dbg_rd_mem_cmd_evt *)(fw_info->rsp_para); + chipinfo_val = ( (uint32_t)evt_para->data[0] | + ((uint32_t)evt_para->data[1] << 8) | + ((uint32_t)evt_para->data[2] << 16) | + ((uint32_t)evt_para->data[3] << 24)); + } + printk("cinit executed, chipinfo=%x\r\n", chipinfo_val); + return 0; + } + ret_val = aicbt_wf_cinit_data_load(fw_info); + if (ret_val < 0){ + printk("%s wf cinit load fail, ret_val:%d\r\n", __func__, ret_val); + return ret_val; + } + ret_val = hci_send_wf_cinit_exec_cmd(fw_info); + if (ret_val < 0){ + printk("%s wf cinit exec fail, ret_val:%d\r\n", __func__, ret_val); + return ret_val; + } + return ret_val; +} + +static int download_patch(firmware_info *fw_info, int cached) { int ret_val = 0; struct aicbt_patch_table *head; + int ret = 0; printk("%s: Download fw patch start, cached %d", __func__, cached); @@ -2967,7 +3543,17 @@ int download_patch(firmware_info *fw_info, int cached) case DC_U01: case DC_U02: case DC_U02H: - aicbt_fw = &fw_8800dc[sub_chip_id]; + if (g_chipid == PRODUCT_ID_AIC8800DC) { + aicbt_fw = &fw_8800dc[sub_chip_id]; + } else if (g_chipid == PRODUCT_ID_AIC8800D80N) { + if (testmode) { + aicbt_fw = &fw_8800d80n_rf[sub_chip_id]; + } else { + aicbt_fw = &fw_8800d80n[sub_chip_id]; + } + } else { + goto free; + } printk("%s aicbt_fw desc:%s \r\n", __func__, aicbt_fw->desc); break; default: @@ -2976,6 +3562,30 @@ int download_patch(firmware_info *fw_info, int cached) break; } + if (g_chipid == PRODUCT_ID_AIC8800DC) { + printk("%s [0x40506004]: 0x04318000\r\n", __func__); + ret = rwnx_send_dbg_mem_write_req(fw_info, 0x40506004, 0x04318000); + printk("%s [0x40506004]: 0x04338000\r\n", __func__); + ret = rwnx_send_dbg_mem_write_req(fw_info, 0x40506004, 0x04338000); + if(ret < 0){ + printk("%s set dc enable fail\r\n", __func__); + return ret; + } + } + + if (g_chipid == PRODUCT_ID_AIC8800D80N) { + printk("%s try to exec wf cinit\r\n", __func__); + ret_val = aicbt_wf_cinit_exec(fw_info); + if (ret_val < 0){ + printk("%s wf cinit exec fail, ret_val:%d\r\n", __func__, ret_val); + goto free; + } + printk("%s [0x40506004]: 0x04338000\r\n", __func__); + ret = rwnx_send_dbg_mem_write_req(fw_info, 0x40506004, 0x04338000); + printk("%s [0x40509000] : 0x00040000 \r\n",__func__); + ret = rwnx_send_dbg_mem_write_req(fw_info, 0x40509000, 0x00040000); + } + //step 1 get patch table data head = aicbt_patch_table_alloc(aicbt_fw->bt_table); if (head == NULL){ @@ -3010,7 +3620,7 @@ end: //for 8800dc end -firmware_info *firmware_info_init(struct usb_interface *intf) +static firmware_info *firmware_info_init(struct usb_interface *intf) { struct usb_device *udev = interface_to_usbdev(intf); firmware_info *fw_info; @@ -3061,7 +3671,7 @@ firmware_info *firmware_info_init(struct usb_interface *intf) } -void firmware_info_destroy(struct usb_interface *intf) +static void firmware_info_destroy(struct usb_interface *intf) { firmware_info *fw_info; struct usb_device *udev; @@ -3104,8 +3714,12 @@ static struct usb_device_id btusb_table[] = { {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D80, 0xe0, 0x01,0x01)}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DC, 0xe0, 0x01,0x01)}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80X2, 0xe0, 0x01,0x01)}, - {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800M80, 0xe0, 0x01,0x01)}, /* a69c:8d83 */ - {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80, 0xe0, 0x01,0x01)}, /* 368b:8d81 */ + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80X2P, 0xe0, 0x01,0x01)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80N, 0xe0, 0x01,0x01)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D80LN, 0xe0, 0x01,0x01)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D40N, 0xe0, 0x01,0x01)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D40LN, 0xe0, 0x01,0x01)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800DLN, 0xe0, 0x01,0x01)}, {} }; @@ -3125,7 +3739,7 @@ static int inc_tx(struct btusb_data *data) return rv; } -void check_sco_event(struct urb *urb) +static void check_sco_event(struct urb *urb) { u8* opcode = (u8*)(urb->transfer_buffer); u8 status; @@ -3133,10 +3747,6 @@ void check_sco_event(struct urb *urb) uint16_t handle; u8 air_mode = 0; struct hci_dev *hdev = urb->context; -#ifdef CONFIG_SCO_OVER_HCI - struct btusb_data *data = GET_DRV_DATA(hdev); - AIC_sco_card_t *pSCOSnd = data->pSCOSnd; -#endif switch (*opcode) { case HCI_EV_SYNC_CONN_COMPLETE: @@ -3147,11 +3757,14 @@ void check_sco_event(struct urb *urb) printk("%s status:%d,air_mode:%d \r\n", __func__, status,air_mode); if (status == 0) { SCO_NUM++; - hdev->notify(hdev, 0); - //schedule_work(&data->work); if (air_mode == 0x03) { set_select_msbc(CODEC_MSBC); + hdev->voice_setting = 0x43; + }else{ + hdev->voice_setting = 0x60; } + hdev->notify(hdev, 0); + //schedule_work(&data->work); } break; case HCI_EV_DISCONN_COMPLETE: @@ -3163,11 +3776,6 @@ void check_sco_event(struct urb *urb) hdev->notify(hdev, 0); set_select_msbc(CODEC_CVSD); //schedule_work(&data->work); -#ifdef CONFIG_SCO_OVER_HCI - if (test_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states)) { - mod_timer(&snd_cap_timer.cap_timer,jiffies + msecs_to_jiffies(3)); - } -#endif } break; default: @@ -3399,14 +4007,7 @@ static void btusb_intr_complete(struct urb *urb) hdev->stat.err_rx++; } #endif - -#ifdef CONFIG_SCO_OVER_HCI check_sco_event(urb); -#endif -#ifdef CONFIG_USB_AIC_UART_SCO_DRIVER - check_sco_event(urb); -#endif - } /* Avoid suspend failed when usb_kill_urb */ else if(urb->status == -ENOENT) { @@ -3885,7 +4486,10 @@ static int btusb_close(struct hci_dev *hdev) int i; #endif int err; - +#ifdef CONFIG_BT_WAKEUP_IN_PM + firmware_info *fw_info; + fw_info = data->fw_info; +#endif AICBT_INFO("%s: hci running %lu", __func__, hdev->flags & HCI_RUNNING); if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)){ @@ -3924,6 +4528,11 @@ static int btusb_close(struct hci_dev *hdev) failed: mdelay(URB_CANCELING_DELAY_MS); usb_scuttle_anchored_urbs(&data->deferred); + #ifdef CONFIG_BT_WAKEUP_IN_PM + { + set_bt_ad_filetr_en_param(fw_info); + } + #endif return 0; } @@ -3939,164 +4548,13 @@ static int btusb_flush(struct hci_dev *hdev) return 0; } -#ifdef CONFIG_SCO_OVER_HCI -static void btusb_isoc_snd_tx_complete(struct urb *urb); - -static int snd_send_sco_frame(struct sk_buff *skb) -{ - struct hci_dev *hdev = (struct hci_dev *) skb->dev; - - struct btusb_data *data = GET_DRV_DATA(hdev); - //struct usb_ctrlrequest *dr; - struct urb *urb; - unsigned int pipe; - int err; - - AICBT_DBG("%s:pkt type %d, packet_len : %d", - __func__,bt_cb(skb)->pkt_type, skb->len); - - if (!hdev && !test_bit(HCI_RUNNING, &hdev->flags)) - return -EBUSY; - - if (!data->isoc_tx_ep || !SCO_NUM) { - kfree(skb); - return -ENODEV; - } - - urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); - if (!urb) { - AICBT_ERR("%s: Failed to allocate mem for sco pkts", __func__); - kfree(skb); - return -ENOMEM; - } - - pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); - - usb_fill_int_urb(urb, data->udev, pipe, - skb->data, skb->len, btusb_isoc_snd_tx_complete, - skb, data->isoc_tx_ep->bInterval); - - urb->transfer_flags = URB_ISO_ASAP; - - fill_isoc_descriptor(urb, skb->len, - le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); - - hdev->stat.sco_tx++; - - usb_anchor_urb(urb, &data->tx_anchor); - - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - AICBT_ERR("%s: Failed to submit urb %p, pkt type %d, err %d", - __func__, urb, bt_cb(skb)->pkt_type, err); - kfree(urb->setup_packet); - usb_unanchor_urb(urb); - } else - usb_mark_last_busy(data->udev); - usb_free_urb(urb); - - return err; - -} - -static bool snd_copy_send_sco_data( AIC_sco_card_t *pSCOSnd) -{ - struct snd_pcm_runtime *runtime = pSCOSnd->playback.substream->runtime; - unsigned int frame_bytes = 2, frames1; - const u8 *source; - - snd_pcm_uframes_t period_size = runtime->period_size; - int i, count; - u8 buffer[period_size * 3]; - int sco_packet_bytes = pSCOSnd->playback.sco_packet_bytes; - struct sk_buff *skb; - - count = frames_to_bytes(runtime, period_size)/sco_packet_bytes; - skb = bt_skb_alloc(((sco_packet_bytes + HCI_SCO_HDR_SIZE) * count), GFP_ATOMIC); - skb->dev = (void *)hci_dev_get(0); - bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; - skb_put(skb, ((sco_packet_bytes + HCI_SCO_HDR_SIZE) * count)); - if(!skb) - return false; - - AICBT_DBG("%s, buffer_pos:%d sco_handle:%d sco_packet_bytes:%d count:%d", __FUNCTION__, pSCOSnd->playback.buffer_pos, pSCOSnd->usb_data->sco_handle, - sco_packet_bytes, count); - - source = runtime->dma_area + pSCOSnd->playback.buffer_pos * frame_bytes; - - if (pSCOSnd->playback.buffer_pos + period_size <= runtime->buffer_size) { - memcpy(buffer, source, period_size * frame_bytes); - } else { - /* wrap around at end of ring buffer */ - frames1 = runtime->buffer_size - pSCOSnd->playback.buffer_pos; - memcpy(buffer, source, frames1 * frame_bytes); - memcpy(&buffer[frames1 * frame_bytes], - runtime->dma_area, (period_size - frames1) * frame_bytes); - } - - pSCOSnd->playback.buffer_pos += period_size; - if ( pSCOSnd->playback.buffer_pos >= runtime->buffer_size) - pSCOSnd->playback.buffer_pos -= runtime->buffer_size; - - for(i = 0; i < count; i++) { - *((__u16 *)(skb->data + i * (sco_packet_bytes + HCI_SCO_HDR_SIZE))) = pSCOSnd->usb_data->sco_handle; - *((__u8 *)(skb->data + i*(sco_packet_bytes + HCI_SCO_HDR_SIZE) + 2)) = sco_packet_bytes; - memcpy((skb->data + i * (sco_packet_bytes + HCI_SCO_HDR_SIZE) + HCI_SCO_HDR_SIZE), - &buffer[sco_packet_bytes * i], sco_packet_bytes); - } - - if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) { - snd_pcm_period_elapsed(pSCOSnd->playback.substream); - } - snd_send_sco_frame(skb); - return true; -} - -static void btusb_isoc_snd_tx_complete(struct urb *urb) -{ - struct sk_buff *skb = urb->context; - struct hci_dev *hdev = (struct hci_dev *) skb->dev; - struct btusb_data *data = GET_DRV_DATA(hdev); - AIC_sco_card_t *pSCOSnd = data->pSCOSnd; - - AICBT_DBG("%s: status %d count %d", - __func__,urb->status, urb->actual_length); - - if (skb && hdev) { - if (!test_bit(HCI_RUNNING, &hdev->flags)) - goto done; - - if (!urb->status) - hdev->stat.byte_tx += urb->transfer_buffer_length; - else - hdev->stat.err_tx++; - } else - AICBT_ERR("%s: skb 0x%p hdev 0x%p", __func__, skb, hdev); - -done: - kfree(urb->setup_packet); - kfree_skb(skb); - if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)){ - snd_copy_send_sco_data(pSCOSnd); - //schedule_work(&pSCOSnd->send_sco_work); - } -} - -static void playback_work(struct work_struct *work) -{ - AIC_sco_card_t *pSCOSnd = container_of(work, AIC_sco_card_t, send_sco_work); - - snd_copy_send_sco_data(pSCOSnd); -} - -#endif #if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) -int btusb_send_frame(struct sk_buff *skb) +static int btusb_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *) skb->dev; #else -int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) +static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { #endif //struct hci_dev *hdev = (struct hci_dev *) skb->dev; @@ -4328,28 +4786,12 @@ static enum CODEC_TYPE check_select_msbc(void) return codec_type; } -#ifdef CONFIG_SCO_OVER_HCI -static int check_controller_support_msbc( struct usb_device *udev) -{ - //fix this in the future,when new card support msbc decode and encode - AICBT_INFO("%s:pid = 0x%02x, vid = 0x%02x",__func__,udev->descriptor.idProduct, udev->descriptor.idVendor); - switch (udev->descriptor.idProduct) { - - default: - return 0; - } - return 0; -} -#endif static void btusb_work(struct work_struct *work) { struct btusb_data *data = container_of(work, struct btusb_data, work); struct hci_dev *hdev = data->hdev; int err; int new_alts; -#ifdef CONFIG_SCO_OVER_HCI - AIC_sco_card_t *pSCOSnd = data->pSCOSnd; -#endif printk("%s data->sco_num:%d \r\n", __func__, data->sco_num); if (data->sco_num > 0) { @@ -4411,28 +4853,9 @@ static void btusb_work(struct work_struct *work) else btusb_submit_isoc_urb(hdev, GFP_KERNEL); } -#ifdef CONFIG_SCO_OVER_HCI - if(test_bit(BTUSB_ISOC_RUNNING, &data->flags)) { - set_bit(USB_CAPTURE_RUNNING, &data->pSCOSnd->states); - set_bit(USB_PLAYBACK_RUNNING, &data->pSCOSnd->states); - } - if (test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) { - schedule_work(&pSCOSnd->send_sco_work); - AICBT_INFO("%s: play_timer restart", __func__); - } -#endif } else { AICBT_INFO("%s: data->sco_num :%d", __func__, data->sco_num); clear_bit(BTUSB_ISOC_RUNNING, &data->flags); -#ifdef CONFIG_SCO_OVER_HCI - clear_bit(USB_CAPTURE_RUNNING, &data->pSCOSnd->states); - clear_bit(USB_PLAYBACK_RUNNING, &data->pSCOSnd->states); - //AIC_sco_card_t *pSCOSnd = data->pSCOSnd; - if (test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) { - mod_timer(&snd_cap_timer.play_timer,jiffies + msecs_to_jiffies(30)); - AICBT_INFO("%s: play_timer start", __func__); - } -#endif mdelay(URB_CANCELING_DELAY_MS); usb_kill_anchored_urbs(&data->isoc_anchor); @@ -4456,7 +4879,7 @@ static void btusb_waker(struct work_struct *work) usb_autopm_put_interface(data->intf); } -int bt_pm_notify(struct notifier_block *notifier, ulong pm_event, void *unused) +static int bt_pm_notify(struct notifier_block *notifier, ulong pm_event, void *unused) { struct btusb_data *data; firmware_info *fw_info; @@ -4480,6 +4903,9 @@ int bt_pm_notify(struct notifier_block *notifier, ulong pm_event, void *unused) #endif if (!device_may_wakeup(&udev->dev)) { #if (CONFIG_RESET_RESUME || CONFIG_BLUEDROID) +#ifdef CONFIG_BT_WAKEUP_IN_PM + set_bt_ad_filetr_en_param(fw_info); +#endif//CONFIG_BT_WAKEUP_IN_PM AICBT_INFO("%s:remote wakeup not supported, reset resume supported", __func__); #else fw_info->intf->needs_binding = 1; @@ -4514,18 +4940,19 @@ int bt_pm_notify(struct notifier_block *notifier, ulong pm_event, void *unused) return NOTIFY_DONE; } -int bt_reboot_notify(struct notifier_block *notifier, ulong pm_event, void *unused) +static int bt_reboot_notify(struct notifier_block *notifier, ulong pm_event, void *unused) { struct btusb_data *data; firmware_info *fw_info; struct usb_device *udev; - + int ret = 0; AICBT_INFO("%s: pm event %ld", __func__, pm_event); data = container_of(notifier, struct btusb_data, reboot_notifier); fw_info = data->fw_info; udev = fw_info->udev; + switch (pm_event) { case SYS_DOWN: AICBT_DBG("%s:system down or restart", __func__); @@ -4533,25 +4960,23 @@ int bt_reboot_notify(struct notifier_block *notifier, ulong pm_event, void *unus case SYS_HALT: case SYS_POWER_OFF: -#if SUSPNED_DW_FW + { +#ifdef CONFIG_BT_WAKEUP_IN_PM cancel_work_sync(&data->work); btusb_stop_traffic(data); mdelay(URB_CANCELING_DELAY_MS); usb_kill_anchored_urbs(&data->tx_anchor); - - if(fw_info_4_suspend) { - download_suspend_patch(fw_info_4_suspend,1); - } - else - AICBT_ERR("%s: Failed to download suspend fw", __func__); -#endif - -#ifdef SET_WAKEUP_DEVICE - set_wakeup_device_from_conf(fw_info_4_suspend); + set_bt_ad_filetr_en_param(fw_info); + ret = aic_cmd_disable_scan(fw_info); + AICBT_ERR("%s disable scan err %x\n", __func__, ret); + aic_cmd_disconnect_all_store_acl_handle(fw_info); + set_bt_wakeup_param(fw_info); + aic_clear_queue(); #endif AICBT_DBG("%s:system halt or power off", __func__); + } break; default: @@ -4562,430 +4987,6 @@ int bt_reboot_notify(struct notifier_block *notifier, ulong pm_event, void *unus } -#ifdef CONFIG_SCO_OVER_HCI -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) -void aic_snd_capture_timeout(ulong data) -#else -void aic_snd_capture_timeout(struct timer_list *t) -#endif -{ - uint8_t null_data[255]; - struct btusb_data *usb_data; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) - usb_data = (struct btusb_data *)data; -#else - usb_data = &snd_cap_timer.snd_usb_data; -#endif - aic_copy_capture_data_to_alsa(usb_data, null_data, snd_cap_timer.snd_sco_length/2); - //printk("%s enter\r\n", __func__); - mod_timer(&snd_cap_timer.cap_timer,jiffies + msecs_to_jiffies(3)); -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) -void aic_snd_play_timeout(ulong data) -#else -void aic_snd_play_timeout(struct timer_list *t) -#endif -{ - AIC_sco_card_t *pSCOSnd; - struct snd_pcm_runtime *runtime; - snd_pcm_uframes_t period_size; - int count; - struct btusb_data *usb_data; - int sco_packet_bytes; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) - usb_data = (struct btusb_data *)data; -#else - usb_data = &snd_cap_timer.snd_usb_data; -#endif - pSCOSnd = usb_data->pSCOSnd; - - if(test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) { - return; - } - - if(!test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) { - return; - } - - runtime = pSCOSnd->playback.substream->runtime; - period_size = runtime->period_size; - sco_packet_bytes = pSCOSnd->playback.sco_packet_bytes; - count = frames_to_bytes(runtime, period_size)/sco_packet_bytes; - - pSCOSnd->playback.buffer_pos += period_size; - if ( pSCOSnd->playback.buffer_pos >= runtime->buffer_size) - pSCOSnd->playback.buffer_pos -= runtime->buffer_size; - - if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) { - snd_pcm_period_elapsed(pSCOSnd->playback.substream); - } - //AICBT_DBG("%s,play_timer restart buffer_pos:%d sco_handle:%d sco_packet_bytes:%d count:%d", __FUNCTION__, pSCOSnd->playback.buffer_pos, pSCOSnd->usb_data->sco_handle, - //sco_packet_bytes, count); - mod_timer(&snd_cap_timer.play_timer,jiffies + msecs_to_jiffies(3*count)); -} - -static const struct snd_pcm_hardware snd_card_sco_capture_default = -{ - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED | - SNDRV_PCM_ACCESS_RW_INTERLEAVED | SNDRV_PCM_INFO_FIFO_IN_FRAMES), - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8, - .rates = (SNDRV_PCM_RATE_8000), - .rate_min = 8000, - .rate_max = 8000, - .channels_min = 1, - .channels_max = 1, - .buffer_bytes_max = 8 * 768, - .period_bytes_min = 48, - .period_bytes_max = 768, - .periods_min = 1, - .periods_max = 8, - .fifo_size = 8, - -}; - -static int snd_sco_capture_pcm_open(struct snd_pcm_substream * substream) -{ - AIC_sco_card_t *pSCOSnd = substream->private_data; - - AICBT_INFO("%s", __FUNCTION__); - pSCOSnd->capture.substream = substream; - - memcpy(&substream->runtime->hw, &snd_card_sco_capture_default, sizeof(struct snd_pcm_hardware)); - pSCOSnd->capture.buffer_pos = 0; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) - init_timer(&snd_cap_timer.cap_timer); - snd_cap_timer.cap_timer.data = (unsigned long)pSCOSnd->usb_data; - snd_cap_timer.cap_timer.function = aic_snd_capture_timeout; -#else - timer_setup(&snd_cap_timer.cap_timer, aic_snd_capture_timeout, 0); - snd_cap_timer.snd_usb_data = *(pSCOSnd->usb_data); -#endif - - if(check_controller_support_msbc(pSCOSnd->dev)) { - substream->runtime->hw.rates |= SNDRV_PCM_RATE_16000; - substream->runtime->hw.rate_max = 16000; - substream->runtime->hw.period_bytes_min = 96; - substream->runtime->hw.period_bytes_max = 16 * 96; - substream->runtime->hw.buffer_bytes_max = 8 * 16 * 96; - } - set_bit(ALSA_CAPTURE_OPEN, &pSCOSnd->states); - return 0; -} - -static int snd_sco_capture_pcm_close(struct snd_pcm_substream *substream) -{ - AIC_sco_card_t *pSCOSnd = substream->private_data; - - del_timer(&snd_cap_timer.cap_timer); - clear_bit(ALSA_CAPTURE_OPEN, &pSCOSnd->states); - return 0; -} - -static int snd_sco_capture_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) -{ - AICBT_DBG("%s, cmd = %d", __FUNCTION__, cmd); - switch (cmd) - { - default: - return snd_pcm_lib_ioctl(substream, cmd, arg); - } - return 0; -} - -static int snd_sco_capture_pcm_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params * hw_params) -{ - - int err; - struct snd_pcm_runtime *runtime = substream->runtime; - err = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); - AICBT_INFO("%s,err : %d, runtime state : %d", __FUNCTION__, err, runtime->status->state); - return err; -} - -static int snd_sco_capture_pcm_hw_free(struct snd_pcm_substream * substream) -{ - AICBT_DBG("%s", __FUNCTION__); - return snd_pcm_lib_free_vmalloc_buffer(substream);; -} - -static int snd_sco_capture_pcm_prepare(struct snd_pcm_substream *substream) -{ - AIC_sco_card_t *pSCOSnd = substream->private_data; - struct snd_pcm_runtime *runtime = substream->runtime; - - AICBT_INFO("%s %d\n", __FUNCTION__, (int)runtime->period_size); - if (test_bit(DISCONNECTED, &pSCOSnd->states)) - return -ENODEV; - if (!test_bit(USB_CAPTURE_RUNNING, &pSCOSnd->states)) - return -EIO; - - if(runtime->rate == 8000) { - if(pSCOSnd->usb_data->isoc_altsetting != 2) - return -ENOEXEC; - pSCOSnd->capture.sco_packet_bytes = 48; - } - else if(runtime->rate == 16000 && check_controller_support_msbc(pSCOSnd->dev)) { - if(pSCOSnd->usb_data->isoc_altsetting != 4) - return -ENOEXEC; - pSCOSnd->capture.sco_packet_bytes = 96; - } - else if(pSCOSnd->usb_data->isoc_altsetting == 2) { - pSCOSnd->capture.sco_packet_bytes = 48; - } - else if(pSCOSnd->usb_data->isoc_altsetting == 1) { - pSCOSnd->capture.sco_packet_bytes = 24; - } - return 0; -} - -static int snd_sco_capture_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - AIC_sco_card_t *pSCOSnd = substream->private_data; - AICBT_INFO("%s, cmd : %d", __FUNCTION__, cmd); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (!test_bit(USB_CAPTURE_RUNNING, &pSCOSnd->states)) - return -EIO; - set_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states); - return 0; - case SNDRV_PCM_TRIGGER_STOP: - clear_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states); - return 0; - default: - return -EINVAL; - } -} - -static snd_pcm_uframes_t snd_sco_capture_pcm_pointer(struct snd_pcm_substream *substream) -{ - AIC_sco_card_t *pSCOSnd = substream->private_data; - - return pSCOSnd->capture.buffer_pos; -} - - -static struct snd_pcm_ops snd_sco_capture_pcm_ops = { - .open = snd_sco_capture_pcm_open, - .close = snd_sco_capture_pcm_close, - .ioctl = snd_sco_capture_ioctl, - .hw_params = snd_sco_capture_pcm_hw_params, - .hw_free = snd_sco_capture_pcm_hw_free, - .prepare = snd_sco_capture_pcm_prepare, - .trigger = snd_sco_capture_pcm_trigger, - .pointer = snd_sco_capture_pcm_pointer, -}; - - -static const struct snd_pcm_hardware snd_card_sco_playback_default = -{ - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED | - SNDRV_PCM_ACCESS_RW_INTERLEAVED | SNDRV_PCM_INFO_FIFO_IN_FRAMES), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rates = (SNDRV_PCM_RATE_8000), - .rate_min = 8000, - .rate_max = 8000, - .channels_min = 1, - .channels_max = 1, - .buffer_bytes_max = 8 * 768, - .period_bytes_min = 48, - .period_bytes_max = 768, - .periods_min = 1, - .periods_max = 8, - .fifo_size = 8, -}; - -static int snd_sco_playback_pcm_open(struct snd_pcm_substream * substream) -{ - AIC_sco_card_t *pSCOSnd = substream->private_data; - int err = 0; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) - init_timer(&snd_cap_timer.play_timer); - snd_cap_timer.play_timer.data = (unsigned long)pSCOSnd->usb_data; - snd_cap_timer.play_timer.function = aic_snd_play_timeout; -#else - timer_setup(&snd_cap_timer.play_timer, aic_snd_play_timeout, 0); - snd_cap_timer.snd_usb_data = *(pSCOSnd->usb_data); -#endif - pSCOSnd->playback.buffer_pos = 0; - - AICBT_INFO("%s, rate : %d", __FUNCTION__, substream->runtime->rate); - memcpy(&substream->runtime->hw, &snd_card_sco_playback_default, sizeof(struct snd_pcm_hardware)); - if(check_controller_support_msbc(pSCOSnd->dev)) { - substream->runtime->hw.rates |= SNDRV_PCM_RATE_16000; - substream->runtime->hw.rate_max = 16000; - substream->runtime->hw.period_bytes_min = 96; - substream->runtime->hw.period_bytes_max = 16 * 96; - substream->runtime->hw.buffer_bytes_max = 8 * 16 * 96; - } - pSCOSnd->playback.substream = substream; - set_bit(ALSA_PLAYBACK_OPEN, &pSCOSnd->states); - - return err; -} - -static int snd_sco_playback_pcm_close(struct snd_pcm_substream *substream) -{ - AIC_sco_card_t *pSCOSnd = substream->private_data; - - del_timer(&snd_cap_timer.play_timer); - AICBT_INFO("%s: play_timer delete", __func__); - clear_bit(ALSA_PLAYBACK_OPEN, &pSCOSnd->states); - cancel_work_sync(&pSCOSnd->send_sco_work); - return 0; -} - -static int snd_sco_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) -{ - AICBT_DBG("%s, cmd : %d", __FUNCTION__, cmd); - switch (cmd) - { - default: - return snd_pcm_lib_ioctl(substream, cmd, arg); - break; - } - return 0; -} - -static int snd_sco_playback_pcm_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params * hw_params) -{ - int err; - err = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); - return err; -} - -static int snd_sco_palyback_pcm_hw_free(struct snd_pcm_substream * substream) -{ - AICBT_DBG("%s", __FUNCTION__); - return snd_pcm_lib_free_vmalloc_buffer(substream); -} - -static int snd_sco_playback_pcm_prepare(struct snd_pcm_substream *substream) -{ - AIC_sco_card_t *pSCOSnd = substream->private_data; - struct snd_pcm_runtime *runtime = substream->runtime; - - AICBT_INFO("%s, bound_rate = %d", __FUNCTION__, runtime->rate); - - if (test_bit(DISCONNECTED, &pSCOSnd->states)) - return -ENODEV; - if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) - return -EIO; - - if(runtime->rate == 8000) { - if(pSCOSnd->usb_data->isoc_altsetting != 2) - return -ENOEXEC; - pSCOSnd->playback.sco_packet_bytes = 48; - } - else if(runtime->rate == 16000) { - if(pSCOSnd->usb_data->isoc_altsetting != 4) - return -ENOEXEC; - pSCOSnd->playback.sco_packet_bytes = 96; - } - - return 0; -} - -static int snd_sco_playback_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - AIC_sco_card_t *pSCOSnd = substream->private_data; - - AICBT_INFO("%s, cmd = %d", __FUNCTION__, cmd); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) - return -EIO; - set_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states); - schedule_work(&pSCOSnd->send_sco_work); -#ifdef CONFIG_SCO_OVER_HCI - if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) { - AICBT_INFO("%s: play_timer cmd 1 start ", __func__); - mod_timer(&snd_cap_timer.play_timer,jiffies + msecs_to_jiffies(3)); - } -#endif - return 0; - case SNDRV_PCM_TRIGGER_STOP: - clear_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states); - return 0; - default: - return -EINVAL; - } -} - -static snd_pcm_uframes_t snd_sco_playback_pcm_pointer(struct snd_pcm_substream *substream) -{ - AIC_sco_card_t *pSCOSnd = substream->private_data; - - return pSCOSnd->playback.buffer_pos; -} - - -static struct snd_pcm_ops snd_sco_playback_pcm_ops = { - .open = snd_sco_playback_pcm_open, - .close = snd_sco_playback_pcm_close, - .ioctl = snd_sco_playback_ioctl, - .hw_params = snd_sco_playback_pcm_hw_params, - .hw_free = snd_sco_palyback_pcm_hw_free, - .prepare = snd_sco_playback_pcm_prepare, - .trigger = snd_sco_playback_pcm_trigger, - .pointer = snd_sco_playback_pcm_pointer, -}; - - -static AIC_sco_card_t* btusb_snd_init(struct usb_interface *intf, const struct usb_device_id *id, struct btusb_data *data) -{ - struct snd_card *card; - AIC_sco_card_t *pSCOSnd; - int err=0; - AICBT_INFO("%s", __func__); - err = snd_card_new(&intf->dev, - -1, AIC_SCO_ID, THIS_MODULE, - sizeof(AIC_sco_card_t), &card); - if (err < 0) { - AICBT_ERR("%s: sco snd card create fail", __func__); - return NULL; - } - // private data - pSCOSnd = (AIC_sco_card_t *)card->private_data; - pSCOSnd->card = card; - pSCOSnd->dev = interface_to_usbdev(intf); - pSCOSnd->usb_data = data; - - strcpy(card->driver, AIC_SCO_ID); - strcpy(card->shortname, "Aicsemi sco snd"); - sprintf(card->longname, "Aicsemi sco over hci: VID:0x%04x, PID:0x%04x", - id->idVendor, pSCOSnd->dev->descriptor.idProduct); - - err = snd_pcm_new(card, AIC_SCO_ID, 0, 1, 1, &pSCOSnd->pcm); - if (err < 0) { - AICBT_ERR("%s: sco snd card new pcm fail", __func__); - return NULL; - } - pSCOSnd->pcm->private_data = pSCOSnd; - sprintf(pSCOSnd->pcm->name, "sco_pcm:VID:0x%04x, PID:0x%04x", - id->idVendor, pSCOSnd->dev->descriptor.idProduct); - - snd_pcm_set_ops(pSCOSnd->pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sco_playback_pcm_ops); - snd_pcm_set_ops(pSCOSnd->pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sco_capture_pcm_ops); - - err = snd_card_register(card); - if (err < 0) { - AICBT_ERR("%s: sco snd card register card fail", __func__); - return NULL; - } - - spin_lock_init(&pSCOSnd->capture_lock); - spin_lock_init(&pSCOSnd->playback_lock); - INIT_WORK(&pSCOSnd->send_sco_work, playback_work); - return pSCOSnd; -} -#endif - static int aicwf_usb_chipmatch(u16 vid, u16 pid){ if(pid == USB_PRODUCT_ID_AIC8801){ @@ -5000,10 +5001,21 @@ static int aicwf_usb_chipmatch(u16 vid, u16 pid){ g_chipid = PRODUCT_ID_AIC8800D80; printk("%s USE AIC8800D80\r\n", __func__); return 0; - }else if(pid == USB_PRODUCT_ID_AIC8800D80X2){ + }else if((pid == USB_PRODUCT_ID_AIC8800D80X2) || (pid == USB_PRODUCT_ID_AIC8800D80X2P)){ g_chipid = PRODUCT_ID_AIC8800D80X2; printk("%s USE AIC8800D80X2\r\n", __func__); return 0; + }else if((pid == USB_PRODUCT_ID_AIC8800D80N) || + (pid == USB_PRODUCT_ID_AIC8800D80LN) || + (pid == USB_PRODUCT_ID_AIC8800D40N) || + (pid == USB_PRODUCT_ID_AIC8800D40LN)){ + g_chipid = PRODUCT_ID_AIC8800D80N; + printk("%s USE AIC8800D80N\r\n", __func__); + return 0; + }else if(pid == USB_PRODUCT_ID_AIC8800DLN){ + g_chipid = PRODUCT_ID_AIC8800DLN; + printk("%s USE AIC8800DLN\r\n", __func__); + return 0; }else{ return -1; } @@ -5109,7 +5121,7 @@ static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *i #if CONFIG_BLUEDROID mutex_lock(&btchr_mutex); #endif - if(g_chipid == PRODUCT_ID_AIC8800DC){ + if(g_chipid == PRODUCT_ID_AIC8800DC || g_chipid == PRODUCT_ID_AIC8800D80N){ err = download_patch(data->fw_info,1); } @@ -5174,9 +5186,6 @@ static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *i data = NULL; return err; } -#ifdef CONFIG_SCO_OVER_HCI - data->pSCOSnd = btusb_snd_init(intf, id, data); -#endif } err = hci_register_dev(hdev); @@ -5245,19 +5254,6 @@ static void btusb_disconnect(struct usb_interface *intf) return; } -#ifdef CONFIG_SCO_OVER_HCI - if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { - AIC_sco_card_t *pSCOSnd = data->pSCOSnd; - if(!pSCOSnd) { - AICBT_ERR("%s: sco private data is null", __func__); - return; - } - set_bit(DISCONNECTED, &pSCOSnd->states); - snd_card_disconnect(pSCOSnd->card); - snd_card_free_when_closed(pSCOSnd->card); - } -#endif - //#ifdef CONFIG_HAS_EARLYSUSPEND #if 0 unregister_early_suspend(&data->early_suspend); @@ -5303,18 +5299,16 @@ static void btusb_disconnect(struct usb_interface *intf) static int btusb_suspend(struct usb_interface *intf, pm_message_t message) { struct btusb_data *data = usb_get_intfdata(intf); - //firmware_info *fw_info = data->fw_info; - +#ifdef CONFIG_BT_WAKEUP_IN_PM + firmware_info *fw_info = data->fw_info; + int ret = 0; +#endif AICBT_INFO("%s: event 0x%x, suspend count %d", __func__, message.event, data->suspend_count); if (intf->cur_altsetting->desc.bInterfaceNumber != 0) return 0; - #ifdef CONFIG_BT_WAKEUP_IN_PM - set_bt_wakeup_param(fw_info); - #endif - if (data->suspend_count++) return 0; @@ -5334,6 +5328,14 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) btusb_stop_traffic(data); mdelay(URB_CANCELING_DELAY_MS); usb_kill_anchored_urbs(&data->tx_anchor); + +#ifdef CONFIG_BT_WAKEUP_IN_PM + ret = aic_cmd_disable_scan(fw_info); + AICBT_ERR("%s disable scan err %x\n", __func__, ret); + aic_cmd_disconnect_all_store_acl_handle(fw_info); + set_bt_wakeup_param(fw_info); + aic_clear_queue(); +#endif return 0; } @@ -5396,7 +5398,10 @@ static int btusb_resume(struct usb_interface *intf) } #ifdef CONFIG_BT_WAKEUP_IN_PM reset_bt_from_wakeup_process(data->fw_info); - hci_resume_hardware_error(); + //hci_resume_hardware_error(); + err = aic_cmd_enable_scan(data->fw_info); + AICBT_ERR("%s en scan err %x\n", __func__, err); + aic_event_disconnect_all_store_acl_handle(); #endif #if 1 @@ -5504,13 +5509,11 @@ module_exit(btusb_exit); module_param(mp_drv_mode, int, 0644); MODULE_PARM_DESC(mp_drv_mode, "0: NORMAL; 1: MP MODE"); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) MODULE_IMPORT_NS("VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver"); -#else +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); #endif -#endif MODULE_AUTHOR("AicSemi Corporation"); MODULE_DESCRIPTION("AicSemi Bluetooth USB driver version"); diff --git a/drivers/aic8800/aic_btusb/aic_btusb.h b/drivers/aic8800/aic_btusb/aic_btusb.h index 2a3cf22..5171a65 100644 --- a/drivers/aic8800/aic_btusb/aic_btusb.h +++ b/drivers/aic8800/aic_btusb/aic_btusb.h @@ -37,52 +37,17 @@ #ifdef CONFIG_PLATFORM_UBUNTU -#define CONFIG_BLUEDROID 0 /* bleuz 0, bluedroid 1 */ +#define CONFIG_BLUEDROID 1 /* bleuz 0, bluedroid 1, lbh 2 */ #else -#define CONFIG_BLUEDROID 0 /* bleuz 0, bluedroid 1 */ +#define CONFIG_BLUEDROID 1 /* bleuz 0, bluedroid 1, lbh 2 */ #endif +#if CONFIG_BLUEDROID == 1 +/* +If you need to use the feature of waking up with BLE during STR Suspend sleep, please enable this macro. +*/ -//#define CONFIG_SCO_OVER_HCI -#define CONFIG_USB_AIC_UART_SCO_DRIVER //#define CONFIG_BT_WAKEUP_IN_PM - -#ifdef CONFIG_SCO_OVER_HCI -#include -#include -#include -#include -#include - -#define AIC_SCO_ID "snd_sco_aic" -enum { - USB_CAPTURE_RUNNING, - USB_PLAYBACK_RUNNING, - ALSA_CAPTURE_OPEN, - ALSA_PLAYBACK_OPEN, - ALSA_CAPTURE_RUNNING, - ALSA_PLAYBACK_RUNNING, - CAPTURE_URB_COMPLETED, - PLAYBACK_URB_COMPLETED, - DISCONNECTED, -}; - -// AIC sound card -typedef struct AIC_sco_card { - struct snd_card *card; - struct snd_pcm *pcm; - struct usb_device *dev; - struct btusb_data *usb_data; - unsigned long states; - struct aic_sco_stream { - struct snd_pcm_substream *substream; - unsigned int sco_packet_bytes; - snd_pcm_uframes_t buffer_pos; - } capture, playback; - spinlock_t capture_lock; - spinlock_t playback_lock; - struct work_struct send_sco_work; -} AIC_sco_card_t; #endif /* Some Android system may use standard Linux kernel, while * standard Linux may also implement early suspend feature. @@ -221,6 +186,7 @@ int mp_drv_mode = 0; /* 1 Mptool Fw; 0 Normal Fw */ #define HCI_OP_Write_Class_of_Device 0x0c24 #define HCI_OP_LE_Rand 0x2018 #define HCI_OP_LE_Set_Random_Address 0x2005 +#define HCI_OP_LE_Set_Extended_Adv_Enable 0x2039 #define HCI_OP_LE_Set_Extended_Scan_Enable 0x2042 #define HCI_OP_LE_Set_Extended_Scan_Parameters 0x2041 #define HCI_OP_Set_Event_Filter 0x0c05 @@ -249,7 +215,7 @@ int mp_drv_mode = 0; /* 1 Mptool Fw; 0 Normal Fw */ #define HCI_OP_LE_Get_Vendor_Capabilities_Command 0xfd53 #define HCI_OP_LE_Set_Le_Scan_Enable 0x200C #define HCI_OP_LE_Create_Connection 0x200d - +#define HCI_OP_LE_Create_Connection_Cancel 0x200e #if CONFIG_BLUEDROID /* ----- HCI events---- */ @@ -329,10 +295,10 @@ int mp_drv_mode = 0; /* 1 Mptool Fw; 0 Normal Fw */ /* Reserv for core and drivers use */ #define BT_SKB_RESERVE 8 -/* BD Address */ + typedef struct { - __u8 b[6]; -} __packed bdaddr_t; + uint8_t addr[6]; +}bdaddr_t; /* Skb helpers */ struct bt_skb_cb { @@ -608,11 +574,7 @@ typedef struct { //Define ioctl cmd the same as HCIDEVUP in the kernel #define DOWN_FW_CFG _IOW('E', 176, int) -//#ifdef CONFIG_SCO_OVER_HCI -//#define SET_ISO_CFG _IOW('H', 202, int) -//#else #define SET_ISO_CFG _IOW('E', 177, int) -//#endif #define RESET_CONTROLLER _IOW('E', 178, int) #define DWFW_CMPLT _IOW('E', 179, int) @@ -689,8 +651,10 @@ typedef struct { #define DATA_END 0x80 #define DOWNLOAD_OPCODE 0xfc02 #define HCI_VSC_UPDATE_PT_CMD 0xFC75 +#define HCI_VSC_SET_ADFILTER_EN_CMD 0xFDAA #define HCI_VSC_SET_ADFILTER_PT_CMD 0xFDAB #define HCI_VSC_RESET_ADFILTER_PROCESS_PT_CMD 0xFDAC +#define HCI_VSC_WF_START_APP_CMD 0xFDAD #define TRUE 1 #define FALSE 0 #define CMD_HDR_LEN sizeof(struct hci_command_hdr) @@ -721,12 +685,19 @@ enum AIC_DC_SUBID{ DC_U02H, }; +enum AIC_D80N_SUBID{ + D80N_U01 = 0, + D80N_U02, +}; + struct aicbt_firmware { const char *desc; const char *bt_adid; const char *bt_patch; const char *bt_table; const char *bt_ext_patch; + const char *wf_cinit; + const char *wf_btusb; }; const struct aicbt_firmware fw_8800dc[] = { @@ -753,6 +724,44 @@ const struct aicbt_firmware fw_8800dc[] = { }, }; +const struct aicbt_firmware fw_8800d80n[] = { + [D80N_U01] = { + .desc = "aic8800d80n u01 bt patch", + .bt_adid = "fw_adid_8800d80n.bin", + .bt_patch = "fw_patch_8800d80n.bin", + .bt_table = "fw_patch_table_8800d80n.bin", + .bt_ext_patch = "fw_patch_8800d80n_ext" + }, + [D80N_U02] = { + .desc = "aic8800d80n u02 bt patch", + .bt_adid = "fw_adid_8800d80n_u02.bin", + .bt_patch = "fw_patch_8800d80n_u02.bin", + .bt_table = "fw_patch_table_8800d80n_u02.bin", + .bt_ext_patch = "fw_patch_8800d80n_u02_ext", + .wf_cinit = "fmacfw_cinit_8800d80n_u02.bin", + .wf_btusb = "fmacfw_btusb_8800d80n_u02.bin", + }, +}; + +const struct aicbt_firmware fw_8800d80n_rf[] = { + [D80N_U01] = { + .desc = "aic8800d80n u01 bt test patch", + .bt_adid = "fw_adid_8800d80n.bin", + .bt_patch = "fw_patch_8800d80n.bin", + .bt_table = "fw_patch_table_8800d80n.bin", + .bt_ext_patch = "fw_patch_8800d80n_ext" + }, + [D80N_U02] = { + .desc = "aic8800d80n u02 bt patch", + .bt_adid = "fw_adid_8800d80n_rf_u02.bin", + .bt_patch = "fw_patch_8800d80n_rf_u02.bin", + .bt_table = "fw_patch_table_8800d80n_rf_u02.bin", + .bt_ext_patch = "fw_patch_8800d80n_rf_u02_ext", + .wf_cinit = "fmacfw_cinit_8800d80n_u02.bin", + .wf_btusb = "fmacfw_btusb_8800d80n_u02.bin", + }, +}; + #define HCI_VSC_FW_STATUS_GET_CMD 0xFC78 @@ -766,6 +775,9 @@ struct fw_status { #define HCI_VSC_UPDATE_PT_SIZE 249 #define HCI_PT_MAX_LEN 31 +#define HCI_VSC_MEM_WR_V2_SIZE 128 +#define HCI_VSC_UPDATE_PT_V2_SIZE 128 + #define HCI_VSC_DBG_RD_MEM_CMD 0xFC01 #define MAX_AD_FILTER_NUM 4// Max AD Filter num @@ -809,6 +821,13 @@ struct ble_wakeup_param_t { struct wakeup_ad_data_filter ad_filter[MAX_AD_FILTER_NUM]; }; +/// Structure containing the parameters of the @ref DBG_START_APP_REQ message. +struct wf_start_app_param +{ + uint32_t bootaddr; + uint32_t boottype; +}; + struct hci_dbg_rd_mem_cmd { __le32 start_addr; __u8 type; @@ -877,9 +896,6 @@ enum aic_endpoit { /* #define HCI_VERSION_CODE KERNEL_VERSION(3, 14, 41) */ #define HCI_VERSION_CODE LINUX_VERSION_CODE -int aic_load_firmware(u8 ** fw_buf, const char *name, struct device *device); -int aicbt_patch_table_free(struct aicbt_patch_table **head); -int download_patch(firmware_info *fw_info, int cached); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38) #define NUM_REASSEMBLY 3 diff --git a/drivers/aic8800/aic_btusb/aic_btusb_external_featrue.c b/drivers/aic8800/aic_btusb/aic_btusb_external_featrue.c new file mode 100644 index 0000000..368997e --- /dev/null +++ b/drivers/aic8800/aic_btusb/aic_btusb_external_featrue.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define IOCTL_CHAR_DEVICE_NAME "aic_btusb_ex_dev" + +#define SET_APCF_PARAMETER _IOR('E', 181, int) + +static dev_t ioctl_devid; /* bt char device number */ +static struct cdev ioctl_char_dev; /* bt character device structure */ +static struct class *ioctl_char_class; /* device class for usb char driver */ + +extern struct file_operations ioctl_chrdev_ops; + +extern void btchr_external_write(char* data, int len); + +static long ioctl_ioctl(struct file *file_p,unsigned int cmd, unsigned long arg) +{ + char data[1024]; + int ret = 0; + + printk("%s enter\r\n", __func__); + memset(data, 0, 1024); + switch(cmd) + { + case SET_APCF_PARAMETER: + printk("set apcf parameter\r\n"); + ret = copy_from_user(data, (int __user *)arg, 1024); + btchr_external_write(&data[1], (int)data[0]); + break; + + default: + printk("unknow cmdr\r\n"); + break; + } + return 0; +} + + +#ifdef CONFIG_COMPAT +static long compat_ioctlchr_ioctl (struct file *filp, unsigned int cmd, unsigned long arg) +{ + return ioctl_ioctl(filp, cmd, (unsigned long) compat_ptr(arg)); +} +#endif + + +struct file_operations ioctl_chrdev_ops = { + unlocked_ioctl : ioctl_ioctl, +#ifdef CONFIG_COMPAT + compat_ioctl : compat_ioctlchr_ioctl, +#endif + +}; + +static int __init init_extenal_ioctl(void){ + int res = 0; + struct device *dev; + + printk("%s enter\r\n", __func__); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) + ioctl_char_class = class_create(IOCTL_CHAR_DEVICE_NAME); +#else + ioctl_char_class = class_create(THIS_MODULE, IOCTL_CHAR_DEVICE_NAME); +#endif + if (IS_ERR(ioctl_char_class)) { + printk("Failed to create ioctl char class"); + } + + res = alloc_chrdev_region(&ioctl_devid, 0, 1, IOCTL_CHAR_DEVICE_NAME); + if (res < 0) { + printk("Failed to allocate ioctl char device"); + goto err_alloc; + } + + dev = device_create(ioctl_char_class, NULL, ioctl_devid, NULL, IOCTL_CHAR_DEVICE_NAME); + if (IS_ERR(dev)) { + printk("Failed to create ioctl char device"); + res = PTR_ERR(dev); + goto err_create; + } + + cdev_init(&ioctl_char_dev, &ioctl_chrdev_ops); + res = cdev_add(&ioctl_char_dev, ioctl_devid, 1); + if (res < 0) { + printk("Failed to add ioctl char device"); + goto err_add; + } + + return res; + +err_add: + device_destroy(ioctl_char_class, ioctl_devid); +err_create: + unregister_chrdev_region(ioctl_devid, 1); +err_alloc: + class_destroy(ioctl_char_class); + + return res; + +} +static void __exit deinit_extenal_ioctl(void){ + printk("%s enter\r\n", __func__); + device_destroy(ioctl_char_class, ioctl_devid); + cdev_del(&ioctl_char_dev); + unregister_chrdev_region(ioctl_devid, 1); + class_destroy(ioctl_char_class); + +} + +module_init(init_extenal_ioctl); +module_exit(deinit_extenal_ioctl); + + +MODULE_AUTHOR("AicSemi Corporation"); +MODULE_DESCRIPTION("AicSemi Bluetooth USB driver version"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/aic8800/aic_btusb/aic_btusb_external_featrue.h b/drivers/aic8800/aic_btusb/aic_btusb_external_featrue.h new file mode 100644 index 0000000..3b7b81c --- /dev/null +++ b/drivers/aic8800/aic_btusb/aic_btusb_external_featrue.h @@ -0,0 +1,3 @@ + +void btchr_external_write(char* data, int len); + diff --git a/drivers/aic8800/aic_load_fw/Makefile b/drivers/aic8800/aic_load_fw/Makefile index 3cdb65b..0c0e373 100644 --- a/drivers/aic8800/aic_load_fw/Makefile +++ b/drivers/aic8800/aic_load_fw/Makefile @@ -7,14 +7,16 @@ CONFIG_M2D_OTA_AUTO_SUPPORT = n CONFIG_LINK_DET_5G = y CONFIG_FOR_IPCAM = n CONFIG_USB_SUSPEND_REBOOT_TIME = n -CONFIG_SUPPORT_USB_SUSP = n CONFIG_RADAR_OR_IR_DETECT =n - +CONFIG_LOAD_BT_CONF = n +CONFIG_FLASH_CALRES = n +CONFIG_WOWLAN ?= n # Need to set fw path in BOARD_KERNEL_CMDLINE CONFIG_USE_FW_REQUEST ?= n CONFIG_PREALLOC_RX_SKB ?= n CONFIG_PREALLOC_TXQ ?= y CONFIG_BAND_STEERING = n +CONFIG_PRBREQ_REPORT = n # Platform support list CONFIG_PLATFORM_ROCKCHIP ?= n @@ -44,7 +46,11 @@ ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ ccflags-$(CONFIG_USB_SUSPEND_REBOOT_TIME) += -DCONFIG_USB_SUSPEND_REBOOT_TIME ccflags-$(CONFIG_SUPPORT_USB_SUSP) += -DCONFIG_SUPPORT_USB_SUSP ccflags-$(CONFIG_RADAR_OR_IR_DETECT) += -DCONFIG_RADAR_OR_IR_DETECT +ccflags-$(CONFIG_LOAD_BT_CONF) += -DCONFIG_LOAD_BT_CONF +ccflags-$(CONFIG_FLASH_CALRES) += -DCONFIG_FLASH_CALRES ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING +ccflags-$(CONFIG_PRBREQ_REPORT) += -DCONFIG_PRBREQ_REPORT +ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN obj-$(CONFIG_AIC_LOADFW_SUPPORT) := $(MODULE_NAME).o $(MODULE_NAME)-y := aic_bluetooth_main.o \ @@ -67,7 +73,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 ?=$(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/) +ARCH ?= arm 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,12 +97,13 @@ endif ifeq ($(CONFIG_PLATFORM_UBUNTU), y) ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU -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 ?= +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 := endif diff --git a/drivers/aic8800/aic_load_fw/aic_compat_8800d80.c b/drivers/aic8800/aic_load_fw/aic_compat_8800d80.c index 2c80c93..e322d01 100644 --- a/drivers/aic8800/aic_load_fw/aic_compat_8800d80.c +++ b/drivers/aic8800/aic_load_fw/aic_compat_8800d80.c @@ -44,21 +44,30 @@ typedef struct { #define USER_TX_USE_ANA_F_FLAG (0x01U << 2) #define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3) #define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4) +#define USER_LOFT_CALIB_DISABLE_FLAG (0x01U << 6) +#define USER_CAPA_CALIB_DISABLE_FLAG (0x01U << 7) +#define USER_PWR_CALIB_DISABLE_FLAG (0x01U << 8) +#define USER_IPA_CALIB_DISABLE_FLAG (0x01U << 13) -#define CFG_PWROFST_COVER_CALIB 1 -#ifdef CONFIG_POWER_LIMIT -#define CFG_USER_CHAN_MAX_TXPWR_EN 1 -#else -#define CFG_USER_CHAN_MAX_TXPWR_EN 0 -#endif -#define CFG_USER_TX_USE_ANA_F 0 -#ifdef CONFIG_BAND_STEERING -#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 1 -#else -#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 0 -#endif +#define USER_EXT_FLAGS_DEFAULT_D80 (USER_PWROFST_COVER_CALIB_FLAG) -#define CFG_USER_EXT_FLAGS_EN (CFG_PWROFST_COVER_CALIB || CFG_USER_CHAN_MAX_TXPWR_EN || CFG_USER_TX_USE_ANA_F|| CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE) +#define CFG_USER_PWROFST_COVER_CALIB_EN (1) +#if (defined(CONFIG_POWER_LIMIT)) +#define CFG_USER_CHAN_MAX_TXPWR_EN (1) +#else +#define CFG_USER_CHAN_MAX_TXPWR_EN (0) +#endif +#define CFG_USER_TX_USE_ANA_F_EN (0) +#if (defined(CONFIG_PRBREQ_REPORT)) +#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (1) +#else +#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (0) +#endif +#define CFG_USER_HE_MU_EDCA_UPDATE_DISABLE (0) +#define CFG_USER_LOFT_CALIB_DISABLE_DISABLE (0) +#define CFG_USER_CAPA_CALIB_DISABLE_DISABLE (0) +#define CFG_USER_PWR_CALIB_DISABLE_DISABLE (0) +#define CFG_USER_IPA_CALIB_DISABLE_DISABLE (0) u32 patch_tbl_d80[][2] = { @@ -73,25 +82,47 @@ u32 patch_tbl_d80[][2] = {0x0170, 0x0001000A},//rx aggr counter #endif -#if CFG_USER_EXT_FLAGS_EN - {0x0188, 0x00000000 -#if CFG_PWROFST_COVER_CALIB - | USER_PWROFST_COVER_CALIB_FLAG -#endif -#if CFG_USER_CHAN_MAX_TXPWR_EN - | USER_CHAN_MAX_TXPWR_EN_FLAG -#endif -#if CFG_USER_TX_USE_ANA_F - | USER_TX_USE_ANA_F_FLAG -#endif -#if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE - | USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG -#endif - }, // user_ext_flags -#endif + {0x0188, + (USER_EXT_FLAGS_DEFAULT_D80 | + #if CFG_USER_CHAN_MAX_TXPWR_EN + USER_CHAN_MAX_TXPWR_EN_FLAG | + #endif + #if CFG_USER_TX_USE_ANA_F_EN + USER_TX_USE_ANA_F_FLAG | + #endif + #if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE + USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG | + #endif + #if CFG_USER_HE_MU_EDCA_UPDATE_DISABLE + USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG | + #endif + #if CFG_USER_LOFT_CALIB_DISABLE_DISABLE + USER_LOFT_CALIB_DISABLE_FLAG | + #endif + #if CFG_USER_CAPA_CALIB_DISABLE_DISABLE + USER_CAPA_CALIB_DISABLE_FLAG | + #endif + #if CFG_USER_PWR_CALIB_DISABLE_DISABLE + USER_PWR_CALIB_DISABLE_FLAG | + #endif + #if CFG_USER_IPA_CALIB_DISABLE_DISABLE + USER_IPA_CALIB_DISABLE_FLAG | + #endif + 0) & ~( + #if !CFG_USER_PWROFST_COVER_CALIB_EN + USER_PWROFST_COVER_CALIB_FLAG | + #endif + 0) + }, // user_ext_flags #ifdef CONFIG_RADAR_OR_IR_DETECT - {0x0019c,0x00000B00}, + {0x0019c,0x00000900}, +#endif +#ifdef CONFIG_WOWLAN + {0x019c,0x01000000}, +#ifdef ANDROID_PLATFORM + {0x01A0, 0x01000001}, +#endif #endif }; @@ -351,7 +382,7 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){ } -static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info) +static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info, const char *filename) { int ret = 0; uint32_t ext_patch_nb = patch_info->ext_patch_nb; @@ -368,7 +399,7 @@ static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_p addr = *(patch_info->ext_patch_param + (index * 2) + 1); memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name)); sprintf(ext_patch_file_name,"%s%d.bin", - FW_PATCH_BASE_NAME_8800D80_U02_EXT, + filename, id); AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n", __func__,ext_patch_file_name, id, addr); @@ -438,7 +469,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) return -1; } - if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { + if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80_U02_EXT)) { return -1; } @@ -500,7 +531,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) return -1; } - if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { + if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80_U02_EXT)) { return -1; } @@ -518,7 +549,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) } } - if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80_U02, FW_RF_BASE_NAME_8800D80_U02)) { + if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80_U02, FW_RF_BASE_NAME_8800D80_U02)) { AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__); return -1; } diff --git a/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.c b/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.c index 847f1bb..e74d608 100644 --- a/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.c +++ b/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.c @@ -41,21 +41,32 @@ typedef struct { #define USER_PWROFST_COVER_CALIB_FLAG (0x01U << 0) #define USER_CHAN_MAX_TXPWR_EN_FLAG (0x01U << 1) -#define USER_TX_USE_ANA_F_FLAG (0x01U << 2) #define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3) #define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4) +#define USER_RF_WITH_SAW_EN_FLAG (0x01U << 10) +#define USER_SETCH_LOFT_CALIB_EN_FLAG (0x01U << 11) +#define USER_SETCH_RXDC_CALIB_EN_FLAG (0x01U << 12) -#ifdef CONFIG_POWER_LIMIT -#define CFG_USER_CHAN_MAX_TXPWR_EN 1 +#define USER_EXT_FLAGS_DEFAULT_D80X2 \ + (USER_PWROFST_COVER_CALIB_FLAG | \ + USER_CHAN_MAX_TXPWR_EN_FLAG | \ + USER_SETCH_LOFT_CALIB_EN_FLAG) + +#define CFG_USER_PWROFST_COVER_CALIB_EN (1) +#if (defined(CONFIG_POWER_LIMIT)) +#define CFG_USER_CHAN_MAX_TXPWR_EN (1) #else -#define CFG_USER_CHAN_MAX_TXPWR_EN 0 +#define CFG_USER_CHAN_MAX_TXPWR_EN (0) #endif -#define CFG_USER_TX_USE_ANA_F 0 -#ifdef CONFIG_BAND_STEERING -#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 1 +#if (defined(CONFIG_PRBREQ_REPORT)) +#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (1) #else -#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 0 +#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE (0) #endif +#define CFG_USER_HE_MU_EDCA_UPDATE_DISABLE (0) +#define CFG_USER_RF_WITH_SAW_EN (0) +#define CFG_USER_SETCH_LOFT_CALIB_EN (1) +#define CFG_USER_SETCH_RXDC_CALIB_EN (0) u32 patch_tbl_d80x2[][2] = { @@ -71,29 +82,35 @@ u32 patch_tbl_d80x2[][2] = {0x0228, 0x50000a00},//ss aggr #endif -#if 0 - #ifdef USE_5G - {0x00b4, 0xf3010001}, - #else - {0x00b4, 0xf3010000}, - #endif -#ifdef CONFIG_PLATFORM_HI - {0x0170, 0x00000001},//rx aggr counter -#else - {0x0170, 0x0000000A},//rx aggr counter -#endif +#ifdef CONFIG_FLASH_CALRES + {0x0234, 0x0000004F}, // cal_res_stored_in_flash_flags #endif - {0x01f0, 0x00000001 - #if CFG_USER_CHAN_MAX_TXPWR_EN - | USER_CHAN_MAX_TXPWR_EN_FLAG - #endif - #if CFG_USER_TX_USE_ANA_F - | USER_TX_USE_ANA_F_FLAG - #endif - #if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE - | USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG - #endif + {0x01f0, + (USER_EXT_FLAGS_DEFAULT_D80X2 | + #if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE + USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG | + #endif + #if CFG_USER_HE_MU_EDCA_UPDATE_DISABLE + USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG | + #endif + #if CFG_USER_RF_WITH_SAW_EN + USER_RF_WITH_SAW_EN_FLAG | + #endif + #if CFG_USER_SETCH_RXDC_CALIB_EN + USER_SETCH_RXDC_CALIB_EN_FLAG | + #endif + 0) & ~( + #if !CFG_USER_PWROFST_COVER_CALIB_EN + USER_PWROFST_COVER_CALIB_FLAG | + #endif + #if !CFG_USER_CHAN_MAX_TXPWR_EN + USER_CHAN_MAX_TXPWR_EN_FLAG | + #endif + #if !CFG_USER_SETCH_LOFT_CALIB_EN + USER_SETCH_LOFT_CALIB_EN_FLAG | + #endif + 0) }, // user_ext_flags }; @@ -297,53 +314,84 @@ int rwnx_plat_userconfig_load_8800d80x2(struct aic_usb_dev *usb_dev){ } #endif int system_config_8800d80x2(struct aic_usb_dev *usb_dev){ - int syscfg_num; - int ret, cnt; - const u32 mem_addr = 0x40500000; - const u32 mem_addr2 = 0x40500004; - struct dbg_mem_read_cfm rd_mem_addr_cfm; - ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm); - if (ret) { - printk("%x rd fail: %d\n", mem_addr, ret); - return ret; - } - chip_id = rd_mem_addr_cfm.memdata >> 16; + int syscfg_num; + int ret, cnt; + const u32 mem_addr = 0x40500000; + const u32 mem_addr2 = 0x40500004; + const u32 mem_addr3 = 0x40800000; + const u32 mem_mask3 = (0x03UL << 24) | (0x01UL << 6) | (0x01UL << 1); + const u32 mem_data3 = (0x02UL << 24) | (0x01UL << 6); + const u32 mem_addr4 = 0x40800014; + const u32 mem_data4 = 0x00000820; + struct dbg_mem_read_cfm rd_mem_addr_cfm; - ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr2, &rd_mem_addr_cfm); - if (ret) { - printk("%x rd fail: %d\n", mem_addr2, ret); - return ret; - } - if (((rd_mem_addr_cfm.memdata >> 17) & 0x01UL) == 0x00UL) { - chip_mcu_id = 1; - } + /* fix usb2.0 rx_err */ + ret = rwnx_send_dbg_mem_mask_write_req(usb_dev, mem_addr3, mem_mask3, mem_data3); + if (ret) { + printk("%x mask write fail: %d\n", mem_addr3, ret); + return ret; + } + ret = rwnx_send_dbg_mem_write_req(usb_dev, mem_addr4, mem_data4); + if (ret) { + printk("%x write fail: %d\n", mem_addr4, ret); + return ret; + } + ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr3, &rd_mem_addr_cfm); + if (ret) { + printk("%x rd fail: %d\n", mem_addr3, ret); + return ret; + } else { + printk("[%08x]=%08x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata); + } + ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr4, &rd_mem_addr_cfm); + if (ret) { + printk("%x rd fail: %d\n", mem_addr4, ret); + return ret; + } else { + printk("[%08x]=%08x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata); + } - printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id); - #if 1 - syscfg_num = sizeof(syscfg_tbl_8800d80x2) / sizeof(u32) / 2; - for (cnt = 0; cnt < syscfg_num; cnt++) { - ret = rwnx_send_dbg_mem_write_req(usb_dev, syscfg_tbl_8800d80x2[cnt][0], syscfg_tbl_8800d80x2[cnt][1]); - if (ret) { - printk("%x write fail: %d\n", syscfg_tbl_8800d80x2[cnt][0], ret); - return ret; - } - } - syscfg_num = sizeof(syscfg_tbl_masked_8800d80x2) / sizeof(u32) / 3; - for (cnt = 0; cnt < syscfg_num; cnt++) { - ret = rwnx_send_dbg_mem_mask_write_req(usb_dev, - syscfg_tbl_masked_8800d80x2[cnt][0], syscfg_tbl_masked_8800d80x2[cnt][1], syscfg_tbl_masked_8800d80x2[cnt][2]); - if (ret) { - printk("%x mask write fail: %d\n", syscfg_tbl_masked_8800d80x2[cnt][0], ret); - return ret; - } - } - #endif + ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm); + if (ret) { + printk("%x rd fail: %d\n", mem_addr, ret); + return ret; + } + chip_id = rd_mem_addr_cfm.memdata >> 16; - return 0; + ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr2, &rd_mem_addr_cfm); + if (ret) { + printk("%x rd fail: %d\n", mem_addr2, ret); + return ret; + } + if (((rd_mem_addr_cfm.memdata >> 17) & 0x01UL) == 0x00UL) { + chip_mcu_id = 1; + } + + printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id); + + syscfg_num = sizeof(syscfg_tbl_8800d80x2) / sizeof(u32) / 2; + for (cnt = 0; cnt < syscfg_num; cnt++) { + ret = rwnx_send_dbg_mem_write_req(usb_dev, syscfg_tbl_8800d80x2[cnt][0], syscfg_tbl_8800d80x2[cnt][1]); + if (ret) { + printk("%x write fail: %d\n", syscfg_tbl_8800d80x2[cnt][0], ret); + return ret; + } + } + syscfg_num = sizeof(syscfg_tbl_masked_8800d80x2) / sizeof(u32) / 3; + for (cnt = 0; cnt < syscfg_num; cnt++) { + ret = rwnx_send_dbg_mem_mask_write_req(usb_dev, + syscfg_tbl_masked_8800d80x2[cnt][0], syscfg_tbl_masked_8800d80x2[cnt][1], syscfg_tbl_masked_8800d80x2[cnt][2]); + if (ret) { + printk("%x mask write fail: %d\n", syscfg_tbl_masked_8800d80x2[cnt][0], ret); + return ret; + } + } + + return 0; } -static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info) +static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info, const char *filename) { int ret = 0; uint32_t ext_patch_nb = patch_info->ext_patch_nb; @@ -351,16 +399,26 @@ static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_p int index = 0; uint32_t id = 0; uint32_t addr = 0; - + uint32_t mem_w_add = 0; + uint32_t mem_w_data = 0; if (ext_patch_nb > 0){ + AICWFDBG(LOGDEBUG, "[0x40480000]: 0x00040220\n"); + mem_w_add = 0x40580000; + mem_w_data = 0x00040220; + AICWFDBG(LOGDEBUG, "%s addr:0x%x data:0x%x \n", __func__, mem_w_add, mem_w_data); + ret = rwnx_send_dbg_mem_write_req(usb_dev, mem_w_add, mem_w_data); + if (ret) { + printk("%x wr fail: %d\n", mem_w_add, ret); + return ret; + } for (index = 0; index < patch_info->ext_patch_nb; index++){ id = *(patch_info->ext_patch_param + (index * 2)); addr = *(patch_info->ext_patch_param + (index * 2) + 1); memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name)); sprintf(ext_patch_file_name,"%s%d.bin", - FW_PATCH_BASE_NAME_8800D80X2_U03_EXT, + filename, id); AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n", __func__,ext_patch_file_name, id, addr); @@ -393,6 +451,10 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev) int i = 0; +#ifdef CONFIG_LOAD_BT_CONF + aicbt_parse_config(usb_dev, FW_BT_CONF_NAME_8800D80X2); +#endif + if (chip_id < CHIP_REV_U05) { head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80X2_U03); } else { @@ -480,7 +542,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev) return -1; } - if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { + if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U03_EXT)) { return -1; } @@ -515,7 +577,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev) if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80X2_U05)) { return -1; } - if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { + if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U05_EXT)) { return -1; } if (aicbt_patch_table_load(usb_dev, head)) { @@ -545,7 +607,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev) return -1; } - if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { + if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U03_EXT)) { return -1; } @@ -556,23 +618,14 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev) mdelay(100); #endif - if (chip_mcu_id) { - int ret = 0; - ret = rwnx_plat_flash_bin_upload_android(usb_dev, FLASH_BIN_ADDR_8800M80X2, FLASH_BIN_8800M80X2); - if (ret && ret!= ENOENT) { - AICWFDBG(LOGERROR,"%s flash bin download fail \r\n", __func__); - return -1; - } + if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, FW_RF_BASE_NAME_8800D80X2)) { + AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__); + return -1; } - - if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, FW_RF_BASE_NAME_8800D80X2)) { - AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__); - return -1; - } - if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, HOST_START_APP_AUTO)) { - return -1; - } - } else { + if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, HOST_START_APP_AUTO)) { + return -1; + } + } else { #ifdef CONFIG_USB_BT if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80X2_U05)) { return -1; @@ -582,7 +635,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev) return -1; } - if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { + if (aicbt_ext_patch_data_load(usb_dev, &patch_info, FW_PATCH_BASE_NAME_8800D80X2_U05_EXT)) { return -1; } @@ -613,12 +666,12 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev) data & mask = "0x46 0x00" 0x00 0x00 0x00 0x00 0x00 0x00 0x00 "0x30 0xff 0xff 0x43 0x52 0x45 0x4c 0x42" using data & mask value condition to wakeup host_wake_bt gpio */ - + int ret; struct ble_wakeup_param_t* wakeup_param = (struct ble_wakeup_param_t*)kmalloc(sizeof(struct ble_wakeup_param_t), GFP_KERNEL); uint32_t *write_blocks = (uint32_t *)wakeup_param; - + printk("%s ble scan wakeup \r\n", __func__); - + memset(wakeup_param, 0, sizeof(struct ble_wakeup_param_t)); rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80, FW_BLE_SCAN_AD_FILTER_NAME); wakeup_param->magic_num = 0x53454C42;//magic_num @@ -737,14 +790,13 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev) wakeup_param->ad_filter[4].wl_addr.addr[4] = 0; wakeup_param->ad_filter[4].wl_addr.addr[5] = 0; } - + for(i = 0; i < (sizeof(struct ble_wakeup_param_t)/4 +1); i++){ printk("write_blocks[%d]:0x%08X \r\n", i, write_blocks[i]); rwnx_send_dbg_mem_write_req(usb_dev, 0x15FE00 + (4 * i), write_blocks[i]); } //rwnx_send_dbg_start_app_req(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80, HOST_START_APP_AUTO); - - int ret; + ret = rwnx_send_dbg_mem_write_req(usb_dev, 0x40500048, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80); if (ret) { printk("%x write fail\n", ret); @@ -756,7 +808,7 @@ int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev) kfree(wakeup_param); - + return -1; } diff --git a/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.h b/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.h index 571bf8c..cb984bb 100644 --- a/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.h +++ b/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.h @@ -4,6 +4,7 @@ #define USB_DEVICE_ID_AIC_8800D80X2 0x8D90 #define USB_DEVICE_ID_AIC_8800D81X2 0x8D91 #define USB_DEVICE_ID_AIC_8800D89X2 0x8D99 +#define USB_DEVICE_ID_AIC_8800D40X2 0x8D92 #ifdef CONFIG_FOR_IPCAM #define FW_BASE_NAME_8800D80X2 "fmacfw_8800d80x2_ipc.bin" @@ -22,12 +23,14 @@ #define FW_ADID_BASE_NAME_8800D80X2_U05 "fw_adid_8800d80x2_u05.bin" #define FW_PATCH_TABLE_NAME_8800D80X2_U05 "fw_patch_table_8800d80x2_u05.bin" +#define FW_BT_CONF_NAME_8800D80X2 "aicbt.conf" + #define FLASH_BIN_8800M80X2 "host_wb_8800m80x2.bin" #define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt" -#define RAM_FMAC_FW_ADDR_8800D80X2 0x120000 -#define RAM_FMAC_RF_FW_ADDR_8800D80X2 0x120000 +#define RAM_FMAC_FW_ADDR_8800D80X2 0x128000 +#define RAM_FMAC_RF_FW_ADDR_8800D80X2 0x128000 #define FW_RAM_ADID_BASE_ADDR_8800D80X2_U03 0x003018f8 #define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U03 0x0030b494 @@ -35,7 +38,7 @@ #define FW_RAM_ADID_BASE_ADDR_8800D80X2_U05 0x003018f8 #define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U05 0x0030b48c -#define FLASH_BIN_ADDR_8800M80X2 0x8000000 +#define FLASH_BIN_ADDR_8800M80X2 0x4000000 int aicwf_patch_config_8800d80x2(struct aic_usb_dev *usb_dev); diff --git a/drivers/aic8800/aic_load_fw/aic_txrxif.h b/drivers/aic8800/aic_load_fw/aic_txrxif.h index 08df943..d566a11 100644 --- a/drivers/aic8800/aic_load_fw/aic_txrxif.h +++ b/drivers/aic8800/aic_load_fw/aic_txrxif.h @@ -18,7 +18,7 @@ #define DATA_BUF_MAX 2048 #define TXPKT_BLOCKSIZE 512 #define MAX_AGGR_TXPKT_LEN (1536*32) -#define CMD_TX_TIMEOUT 2000 +#define CMD_TX_TIMEOUT 5000 #define TX_ALIGNMENT 4 #define RX_HWHRD_LEN 60 //58->60 word allined diff --git a/drivers/aic8800/aic_load_fw/aicbluetooth.c b/drivers/aic8800/aic_load_fw/aicbluetooth.c index 9ae9254..79e0a99 100644 --- a/drivers/aic8800/aic_load_fw/aicbluetooth.c +++ b/drivers/aic8800/aic_load_fw/aicbluetooth.c @@ -20,20 +20,6 @@ extern int flash_erase_len; int flash_write_size = 0; u32 flash_write_bin_crc = 0; -typedef struct -{ - int8_t enable; - int8_t dsss; - int8_t ofdmlowrate_2g4; - int8_t ofdm64qam_2g4; - int8_t ofdm256qam_2g4; - int8_t ofdm1024qam_2g4; - int8_t ofdmlowrate_5g; - int8_t ofdm64qam_5g; - int8_t ofdm256qam_5g; - int8_t ofdm1024qam_5g; -} txpwr_idx_conf_t; - txpwr_idx_conf_t userconfig_txpwr_idx = { .enable = 1, @@ -49,17 +35,6 @@ txpwr_idx_conf_t userconfig_txpwr_idx = { }; -typedef struct -{ - int8_t enable; - int8_t chan_1_4; - int8_t chan_5_9; - int8_t chan_10_13; - int8_t chan_36_64; - int8_t chan_100_120; - int8_t chan_122_140; - int8_t chan_142_165; -} txpwr_ofst_conf_t; txpwr_ofst_conf_t userconfig_txpwr_ofst = { .enable = 1, @@ -72,13 +47,6 @@ txpwr_ofst_conf_t userconfig_txpwr_ofst = { .chan_142_165 = 0 }; -typedef struct -{ - int8_t enable; - int8_t xtal_cap; - int8_t xtal_cap_fine; -} xtal_cap_conf_t; - xtal_cap_conf_t userconfig_xtal_cap = { .enable = 0, @@ -757,7 +725,7 @@ int rwnx_plat_flash_bin_upload_android(struct aic_usb_dev *usbdev, u32 fw_addr, int err=0; const u32 mem_addr = fw_addr; struct dbg_mem_read_cfm rd_mem_addr_cfm; - u32 crc = ~0UL; + u32 crc = (u32)~0UL; /* load aic firmware */ size = aic_load_firmware(&dst, filename, dev); @@ -1285,6 +1253,149 @@ static struct aicbt_info_t aicbt_info[] = { },//PRODUCT_ID_AIC8800D80X2 }; +#ifdef CONFIG_LOAD_BT_CONF +static const char *aicbt_find_tag(const u8 *file_data, unsigned int file_size, + const char *tag_name, unsigned int tag_len) +{ + unsigned int line_start = 0, tag_name_len = strlen(tag_name); + const char *comment_symbols = "#;"; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + while (line_start < file_size) { + unsigned int line_end = line_start; + + while (line_end < file_size && file_data[line_end] != '\n' && file_data[line_end] != '\r') { + line_end++; + } + + if (line_end - line_start >= tag_name_len && + !strncmp((const char*)&file_data[line_start], tag_name, tag_name_len)) + { + const char *value_start = (const char*)&file_data[line_start + tag_name_len]; + const char *value_end = (const char*)&file_data[line_end]; + + while (value_start < value_end && (*value_start == ' ' || *value_start == '=')) { + value_start++; + } + const char *comment_pos = value_start; + while (comment_pos < value_end && !strchr(comment_symbols, *comment_pos)) { + comment_pos++; + } + while (comment_pos > value_start && (*(comment_pos-1) == ' ' || *(comment_pos-1) == '\t')) { + comment_pos--; + } + if (comment_pos > value_start) { + return value_start; + } + } + + line_start = line_end; + while (line_start < file_size && (file_data[line_start] == '\n' || file_data[line_start] == '\r')) { + line_start++; + } + } + return NULL; +} + +void aicbt_parse_config(struct aic_usb_dev *usbdev, const char *filename) +{ + struct device *dev = usbdev->dev; + u32 *dst = NULL; + int size; + const u8 *tag_ptr; + u32 tmp_val; + //char *filename = "aicbt.conf"; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + size = aic_load_firmware((u32 **)&dst, filename, dev); + if (size <= 0) { + AICWFDBG(LOGERROR, "%s: load %s fail (%d)\n", __func__, filename, size); + return; + } + + tag_ptr = aicbt_find_tag((char*)dst, size, "BTMODE=", strlen("0")); + if (tag_ptr) { + if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].btmode) != 1 || + aicbt_info[usbdev->chipid].btmode > AICBT_BTMODE_BT_ONLY_COANT) { + aicbt_info[usbdev->chipid].btmode = AICBT_BTMODE_DEFAULT; + AICWFDBG(LOGERROR, "BTMODE invalid, use default %02X\n", AICBT_BTMODE_DEFAULT); + } + } else { + aicbt_info[usbdev->chipid].btmode = AICBT_BTMODE_DEFAULT; + } + + tag_ptr = aicbt_find_tag((char*)dst, size, "BTPORT=", strlen("0")); + if (tag_ptr) { + if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].btport) != 1 || + aicbt_info[usbdev->chipid].btport > AICBT_BTPORT_UART) { + aicbt_info[usbdev->chipid].btport = AICBT_BTPORT_DEFAULT; + } + } else { + aicbt_info[usbdev->chipid].btport = AICBT_BTPORT_DEFAULT; + } + + tag_ptr = aicbt_find_tag((char*)dst, size, "UART_BAUD=", 0); + if (tag_ptr) { + if (sscanf(tag_ptr, "%u", &tmp_val) == 1) { + if(tmp_val >= AICBT_UART_BAUD_115200 && tmp_val <= AICBT_UART_BAUD_3_25M) { + aicbt_info[usbdev->chipid].uart_baud = tmp_val; + } else { + aicbt_info[usbdev->chipid].uart_baud = AICBT_UART_BAUD_DEFAULT; + AICWFDBG(LOGERROR, "UART_BAUD %u invalid, use default %d\n", tmp_val, AICBT_UART_BAUD_DEFAULT); + } + } else { + aicbt_info[usbdev->chipid].uart_baud = AICBT_UART_BAUD_DEFAULT; + } + } else { + aicbt_info[usbdev->chipid].uart_baud = AICBT_UART_BAUD_DEFAULT; + } + tag_ptr = aicbt_find_tag((char*)dst, size, "UART_FC=", strlen("0")); + if (tag_ptr) { + if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].uart_flowctrl) != 1 || + aicbt_info[usbdev->chipid].uart_flowctrl > AICBT_UART_FLOWCTRL_ENABLE) { + aicbt_info[usbdev->chipid].uart_flowctrl = AICBT_UART_FC_DEFAULT; + } + } else { + aicbt_info[usbdev->chipid].uart_flowctrl = AICBT_UART_FC_DEFAULT; + } + + tag_ptr = aicbt_find_tag((char*)dst, size, "LPM_ENABLE=", strlen("0")); + if (tag_ptr) { + if (sscanf(tag_ptr, "%x", &aicbt_info[usbdev->chipid].lpm_enable) != 1 || + aicbt_info[usbdev->chipid].lpm_enable > 1) { + aicbt_info[usbdev->chipid].lpm_enable = AICBT_LPM_ENABLE_DEFAULT; + } + } else { + aicbt_info[usbdev->chipid].lpm_enable = AICBT_LPM_ENABLE_DEFAULT; + } + tag_ptr = aicbt_find_tag((char*)dst, size, "TXPWR_LVL=", strlen("0x6F2F")); + if (tag_ptr) { + if (sscanf(tag_ptr, "%08x", &tmp_val) == 1) { + if (tmp_val >= 0 || tmp_val <= 0X7F7F) { + aicbt_info[usbdev->chipid].txpwr_lvl = tmp_val; + } else { + aicbt_info[usbdev->chipid].txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT; + } + } else { + aicbt_info[usbdev->chipid].txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT; + } + } else { + aicbt_info[usbdev->chipid].txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT; + } + vfree(dst); + AICWFDBG(LOGINFO, "%s: btmode %d btport %d uart baud %d uart fc %d lpm %d txpwrlvl %4X\n", + __func__, + aicbt_info[usbdev->chipid].btmode, + aicbt_info[usbdev->chipid].btport, + aicbt_info[usbdev->chipid].uart_baud, + aicbt_info[usbdev->chipid].uart_flowctrl, + aicbt_info[usbdev->chipid].lpm_enable, + aicbt_info[usbdev->chipid].txpwr_lvl); +} +#endif + int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *_head) { struct aicbt_patch_table *head, *p; @@ -1306,12 +1417,13 @@ int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *(data + 13) = aicbt_info[usbdev->chipid].uart_flowctrl; *(data + 15) = aicbt_info[usbdev->chipid].lpm_enable; *(data + 17) = aicbt_info[usbdev->chipid].txpwr_lvl; - - printk("%s bt btmode[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].btmode); - printk("%s bt uart_baud[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_baud); - printk("%s bt uart_flowctrl[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_flowctrl); - printk("%s bt lpm_enable[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].lpm_enable); - printk("%s bt tx_pwr[%d]:%d \r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].txpwr_lvl); + + printk("%s bt btmode[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].btmode); + printk("%s bt btport[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].btport); + printk("%s bt uart_baud[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_baud); + printk("%s bt uart_flowctrl[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].uart_flowctrl); + printk("%s bt lpm_enable[%d]:%d\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].lpm_enable); + printk("%s bt tx_pwr[%d]:%4X\r\n", __func__, usbdev->chipid, aicbt_info[usbdev->chipid].txpwr_lvl); } if (p->type == 0x06) { @@ -1326,7 +1438,8 @@ int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table data += 2; } if (p->type == AICBT_PT_PWRON) - udelay(500); + mdelay(100); + // udelay(500); } aicbt_patch_table_free(head); return 0; @@ -1349,6 +1462,7 @@ int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_ patch_info->info_len = head_t->len; memcpy_len = patch_info->info_len; } + head_t->len = patch_info->info_len; AICWFDBG(LOGDEBUG, "%s memcpy_len:%d \r\n", __func__, memcpy_len); if (patch_info->info_len == 0) diff --git a/drivers/aic8800/aic_load_fw/aicbluetooth.h b/drivers/aic8800/aic_load_fw/aicbluetooth.h index d4af0c7..a7330d5 100644 --- a/drivers/aic8800/aic_load_fw/aicbluetooth.h +++ b/drivers/aic8800/aic_load_fw/aicbluetooth.h @@ -9,6 +9,53 @@ struct aicbt_patch_table { struct aicbt_patch_table *next; }; +typedef struct +{ + int8_t enable; + int8_t dsss; + int8_t ofdmlowrate_2g4; + int8_t ofdm64qam_2g4; + int8_t ofdm256qam_2g4; + int8_t ofdm1024qam_2g4; + int8_t ofdmlowrate_5g; + int8_t ofdm64qam_5g; + int8_t ofdm256qam_5g; + int8_t ofdm1024qam_5g; +} txpwr_idx_conf_t; + + +typedef struct +{ + int8_t enable; + int8_t chan_1_4; + int8_t chan_5_9; + int8_t chan_10_13; + int8_t chan_36_64; + int8_t chan_100_120; + int8_t chan_122_140; + int8_t chan_142_165; +} txpwr_ofst_conf_t; + +typedef struct +{ + int8_t enable; + int8_t xtal_cap; + int8_t xtal_cap_fine; +} xtal_cap_conf_t; + +u32 aic_crc32(u8 *p, u32 len, u32 crc); +void get_fw_path(char* fw_path); +void set_testmode(int val); +int get_testmode(void); +int get_hardware_info(void); +int get_adap_test(void); +int get_flash_bin_size(void); +u32 get_flash_bin_crc(void); +void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap); +void get_userconfig_txpwr_idx(txpwr_idx_conf_t *txpwr_idx); +void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst); +void rwnx_plat_userconfig_set_value(char *command, char *value); +void rwnx_plat_userconfig_parsing(char *buffer, int size); int aic_bt_platform_init(struct aic_usb_dev *sdiodev); @@ -30,6 +77,9 @@ int8_t rwnx_atoi(char *value); uint32_t rwnx_atoli(char *value); int aicbt_patch_table_free(struct aicbt_patch_table *head); struct aicbt_patch_table *aicbt_patch_table_alloc(struct aic_usb_dev *usbdev, const char *filename); +#ifdef CONFIG_LOAD_BT_CONF +void aicbt_parse_config(struct aic_usb_dev *usbdev, const char *filename); +#endif int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t); int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *_head); diff --git a/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c b/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c index 4040e00..2a48e65 100644 --- a/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c +++ b/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c @@ -240,7 +240,6 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len) struct aicwf_bus *bus = usbdev->bus_if; u8 *buffer = bus->cmd_buf; u16 index = 0; - int ret = 0; memset(buffer, 0, CMD_BUF_MAX); buffer[0] = (len+4) & 0x00ff; @@ -262,10 +261,7 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len) index += 2; memcpy(&buffer[index], (u8 *)msg->param, msg->param_len); - ret = aicwf_bus_txmsg(bus, buffer, len + 8); - if (ret == -EIO) { - ret = aicwf_bus_txmsg(bus, buffer, len + 8); - } + aicwf_bus_txmsg(bus, buffer, len + 8); } static inline void *rwnx_msg_zalloc(lmac_msg_id_t const id, @@ -336,7 +332,10 @@ static int rwnx_send_msg(struct aic_usb_dev *usbdev, const void *msg_params, } if(!reqcfm) + { kfree(cmd); + rwnx_msg_free(msg, msg_params); + } return ret; } @@ -408,7 +407,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/drivers/aic8800/aic_load_fw/aicwf_txq_prealloc.c b/drivers/aic8800/aic_load_fw/aicwf_txq_prealloc.c index cca0659..309b079 100644 --- a/drivers/aic8800/aic_load_fw/aicwf_txq_prealloc.c +++ b/drivers/aic8800/aic_load_fw/aicwf_txq_prealloc.c @@ -1,5 +1,6 @@ #include #include "aicwf_debug.h" +#include "aicwf_txq_prealloc.h" struct prealloc_txq{ int prealloced; diff --git a/drivers/aic8800/aic_load_fw/aicwf_txq_prealloc.h b/drivers/aic8800/aic_load_fw/aicwf_txq_prealloc.h index ce4ee07..f39b449 100644 --- a/drivers/aic8800/aic_load_fw/aicwf_txq_prealloc.h +++ b/drivers/aic8800/aic_load_fw/aicwf_txq_prealloc.h @@ -1,4 +1,7 @@ +#ifndef __AICWF_TXQ_PREALLOC_H +#define __AICWF_TXQ_PREALLOC_H - +void *aicwf_prealloc_txq_alloc(size_t size); void aicwf_prealloc_txq_free(void); +#endif diff --git a/drivers/aic8800/aic_load_fw/aicwf_usb.c b/drivers/aic8800/aic_load_fw/aicwf_usb.c index 8d4b010..3f550f6 100644 --- a/drivers/aic8800/aic_load_fw/aicwf_usb.c +++ b/drivers/aic8800/aic_load_fw/aicwf_usb.c @@ -985,7 +985,7 @@ u32 patch_tbl[][2] ={ #ifdef CONFIG_USB_SUSPEND_REBOOT_TIME {0x0110, 0x03e80001}//reboot time when usb suspend,0001 enables reboot on suspend, default 0x3e8 = 1000ms reboot #else -#ifdef CONFIG_SUPPORT_USB_SUSP +#ifdef CONFIG_WOWLAN //USB SUSP keep working 0x0100:enable 0x0000:disable {0x0110, 0x00000100} #endif @@ -1364,13 +1364,17 @@ static int aicloadfw_chipmatch(struct aic_usb_dev *usb_dev, u16 vid, u16 pid){ AICWFDBG(LOGINFO, "%s USE AIC8800D81X2\r\n", __func__); return 0; }else if(pid == USB_DEVICE_ID_AIC_8800D89X2 && vid == USB_VENDOR_ID_AIC_V2){ - usb_dev->chipid = PRODUCT_ID_AIC8800D89X2; - AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__); - return 0; + usb_dev->chipid = PRODUCT_ID_AIC8800D89X2; + AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__); + return 0; + }else if(pid == USB_DEVICE_ID_AIC_8800D40X2 && vid == USB_VENDOR_ID_AIC_V2){ + usb_dev->chipid = PRODUCT_ID_AIC8800D80X2; + AICWFDBG(LOGINFO, "%s USE AIC8800D40X2\r\n", __func__); + return 0; }else if(pid == USB_DEVICE_ID_AIC_8800D81 && vid == USB_VENDOR_ID_AIC_V2){ - usb_dev->chipid = PRODUCT_ID_AIC8800D81; - AICWFDBG(LOGINFO, "%s USE AIC8800D81 (368b:8d81)\r\n", __func__); - return 0; + usb_dev->chipid = PRODUCT_ID_AIC8800D81; + AICWFDBG(LOGINFO, "%s USE AIC8800D81 (368b:8d81)\r\n", __func__); + return 0; }else{ return -1; } @@ -1850,6 +1854,7 @@ static struct usb_device_id aicwf_usb_id_table[] = { {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D80X2)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D81X2)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D89X2)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D40X2)}, {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D81)}, /* 368b:8d81 */ {} }; diff --git a/drivers/aic8800/aic_load_fw/aicwf_usb.h b/drivers/aic8800/aic_load_fw/aicwf_usb.h index 759698d..736fdcf 100644 --- a/drivers/aic8800/aic_load_fw/aicwf_usb.h +++ b/drivers/aic8800/aic_load_fw/aicwf_usb.h @@ -42,11 +42,12 @@ enum AICWF_IC{ PRODUCT_ID_AIC8800D80X2, PRODUCT_ID_AIC8800D81X2, PRODUCT_ID_AIC8800D89X2, + PRODUCT_ID_AIC8800D40X2, }; #define AICWF_USB_RX_URBS (20) -#define AICWF_USB_TX_URBS (30) +#define AICWF_USB_TX_URBS (100) #define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4) #define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3) #define AICWF_USB_MAX_PKT_SIZE (2048) @@ -233,6 +234,8 @@ extern void aicwf_usb_tx_flowctrl(struct aic_usb_dev *usb_dev, bool state); int usb_bustx_thread(void *data); int usb_busrx_thread(void *data); int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv); +int aicfw_download_fw_8800(struct aic_usb_dev *usb_dev); +int aicfw_download_fw(struct aic_usb_dev *usb_dev); #endif /* AICWF_USB_SUPPORT */ #endif /* _AICWF_USB_H_ */ diff --git a/drivers/aic8800/aic_load_fw/rwnx_version_gen.h b/drivers/aic8800/aic_load_fw/rwnx_version_gen.h index f31bfce..3210d0c 100644 --- a/drivers/aic8800/aic_load_fw/rwnx_version_gen.h +++ b/drivers/aic8800/aic_load_fw/rwnx_version_gen.h @@ -1,4 +1,4 @@ #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 "2026_0123_5f7be68d" diff --git a/fw/aic8800/fmacfw.bin b/fw/aic8800/fmacfw.bin index 67ecd8c..908f425 100644 Binary files a/fw/aic8800/fmacfw.bin and b/fw/aic8800/fmacfw.bin differ diff --git a/fw/aic8800/fmacfw_rf.bin b/fw/aic8800/fmacfw_rf.bin index 6a68eaa..6b154a1 100644 Binary files a/fw/aic8800/fmacfw_rf.bin and b/fw/aic8800/fmacfw_rf.bin differ diff --git a/fw/aic8800/fw_patch_table_u03.bin b/fw/aic8800/fw_patch_table_u03.bin index c3a28b2..ac999f6 100644 Binary files a/fw/aic8800/fw_patch_table_u03.bin and b/fw/aic8800/fw_patch_table_u03.bin differ diff --git a/fw/aic8800/fw_patch_u03.bin b/fw/aic8800/fw_patch_u03.bin index 4a9c2e8..83efdba 100644 Binary files a/fw/aic8800/fw_patch_u03.bin and b/fw/aic8800/fw_patch_u03.bin differ diff --git a/fw/aic8800D80/aic_powerlimit_8800d80.txt b/fw/aic8800D80/aic_powerlimit_8800d80.txt index 9a16186..4fd2ee9 100644 --- a/fw/aic8800D80/aic_powerlimit_8800d80.txt +++ b/fw/aic8800D80/aic_powerlimit_8800d80.txt @@ -1,118 +1,117 @@ -# AIC POWERLIMIT 2024/1108/1900 +# AIC POWERLIMIT 2025/0623/1700 # Max tx power reference: Linux wireless regulatory database for CRDA # https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt -# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment +# If loss_value in aic_userconfig.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment # Table 1: -## 2.4G, 20M,#5# +## 2.4G, 20M,#6# ## START -## SRRC FCC ETSI JP UNSET -CH01 15 15 15 15 15 -CH02 16 16 16 16 16 -CH03 16 16 16 16 16 -CH04 16 16 16 16 16 -CH05 16 16 16 16 16 -CH06 16 16 16 16 16 -CH07 16 16 16 16 16 -CH08 16 16 16 16 16 -CH09 16 16 16 16 16 -CH10 16 16 16 16 16 -CH11 16 16 16 16 16 -CH12 12 12 12 12 12 -CH13 12 12 12 12 12 -CH14 NA NA NA 12 12 +## SRRC FCC ETSI JP KCC UNSET +CH01 16 14 14 16 16 15 +CH02 16 14 14 16 16 16 +CH03 16 14 14 16 16 16 +CH04 16 14 14 16 16 16 +CH05 16 14 14 16 16 16 +CH06 16 14 14 16 16 16 +CH07 16 14 14 16 16 16 +CH08 16 14 14 16 16 16 +CH09 16 14 14 16 16 16 +CH10 16 14 14 16 16 16 +CH11 16 14 14 16 16 16 +CH12 15 14 14 16 16 12 +CH13 13 14 14 16 16 12 +CH14 NA NA NA 16 NA 12 ## END # Table 2: -## 2.4G, 40M,#5# +## 2.4G, 40M,#6# ## START -## SRRC FCC ETSI JP UNSET -CH01 NA NA NA NA NA -CH02 NA NA NA NA NA -CH03 16 16 16 16 16 -CH04 16 16 16 16 16 -CH05 16 16 16 16 16 -CH06 16 16 16 16 16 -CH07 16 16 16 16 16 -CH08 16 16 16 16 16 -CH09 16 16 16 16 16 -CH10 16 16 16 16 16 -CH11 16 16 16 16 16 -CH12 NA NA NA NA NA -CH13 NA NA NA NA NA -CH14 NA NA NA NA NA +## SRRC FCC ETSI JP KCC UNSET +CH01 NA NA NA NA NA NA +CH02 NA NA NA NA NA NA +CH03 16 13 14 16 16 16 +CH04 16 13 14 16 16 16 +CH05 16 13 14 16 16 16 +CH06 16 13 14 16 16 16 +CH07 16 13 14 16 16 16 +CH08 16 13 14 16 16 16 +CH09 16 11 14 16 16 16 +CH10 16 11 14 16 16 16 +CH11 16 11 14 16 16 16 +CH12 NA NA NA NA NA NA +CH13 NA NA NA NA NA NA +CH14 NA NA NA NA NA NA ## END # Table 3: -## 5G, 20M,#5# +## 5G, 20M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH36 15 16 16 16 15 -CH40 15 16 16 16 15 -CH44 15 16 16 16 15 -CH48 15 16 16 16 15 +CH36 15 16 16 16 16 15 +CH40 15 16 16 16 16 15 +CH44 15 16 16 16 16 15 +CH48 15 16 16 16 16 15 # 5G Band 2 -CH52 15 16 16 16 15 -CH56 15 16 16 16 15 -CH60 15 16 16 16 15 -CH64 15 16 16 16 15 +CH52 15 16 16 16 16 15 +CH56 15 16 16 16 16 15 +CH60 15 16 16 16 16 15 +CH64 15 16 16 16 16 15 # 5G Band 3 -CH100 NA 16 16 16 15 -CH104 NA 16 16 16 15 -CH108 NA 16 16 16 15 -CH112 NA 16 16 16 15 -CH116 NA 16 16 16 15 -CH120 NA 16 16 16 15 -CH124 NA 16 16 16 15 -CH128 NA 16 16 16 15 -CH132 NA 16 16 16 15 -CH136 NA 16 16 16 15 -CH140 NA 16 16 16 15 -CH144 NA NA 16 16 15 +CH100 NA 16 16 16 16 15 +CH104 NA 16 16 16 16 15 +CH108 NA 16 16 16 16 15 +CH112 NA 16 16 16 16 15 +CH116 NA 16 16 16 16 15 +CH120 NA 16 16 16 16 15 +CH124 NA 16 16 16 16 15 +CH128 NA 16 16 16 16 15 +CH132 NA 16 16 16 16 15 +CH136 NA 16 16 16 16 15 +CH140 NA 16 16 16 16 15 +CH144 NA NA 16 16 16 15 # 5G Band 4 -CH149 16 16 11 NA 11 -CH153 16 16 11 NA 11 -CH157 16 16 11 NA 11 -CH161 16 16 11 NA 11 -CH165 16 16 11 NA 11 +CH149 20 16 8 NA 20 11 +CH153 20 16 8 NA 20 11 +CH157 20 16 8 NA 20 11 +CH161 20 16 8 NA 20 11 +CH165 20 16 8 NA 20 11 ## END # Table 4: -## 5G, 40M,#5# +## 5G, 40M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH38 15 16 16 16 15 -CH46 15 16 16 16 15 +CH38 15 16 16 16 20 15 +CH46 15 16 16 16 20 15 # 5G Band 2 -CH54 15 16 16 16 15 -CH62 15 16 16 16 15 +CH54 15 16 16 16 20 15 +CH62 15 16 16 16 20 15 # 5G Band 3 -CH102 NA 16 16 16 15 -CH110 NA 16 16 16 15 -CH118 NA 16 16 16 15 -CH126 NA 16 16 16 15 -CH134 NA 16 16 16 15 -CH142 NA 16 NA 16 15 +CH102 NA 16 16 16 20 15 +CH110 NA 16 16 16 20 15 +CH118 NA 16 16 16 20 15 +CH126 NA 16 16 16 20 15 +CH134 NA 16 16 16 20 15 +CH142 NA 16 NA 16 20 15 # 5G Band 4 -CH151 16 16 11 NA 11 -CH159 16 16 11 NA 11 +CH151 16 15 8 NA 18 11 +CH159 17 16 8 NA 17 11 ## END # Table 5: -## 5G, 80M,#5# +## 5G, 80M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH42 15 16 16 16 15 +CH42 15 16 16 16 20 15 # 5G Band 2 -CH58 15 16 16 16 15 +CH58 15 16 16 16 20 15 # 5G Band 3 -CH106 NA 16 16 16 15 -CH122 NA 16 16 16 15 -CH138 NA 16 NA NA 15 +CH106 NA 16 16 16 20 15 +CH122 NA 16 16 16 20 15 +CH138 NA 16 NA NA 20 15 # 5G Band 4 -CH155 16 16 11 NA 11 -## END - +CH155 15 14 8 NA 16 11 +## END \ No newline at end of file diff --git a/fw/aic8800D80/fmacfw_8800d80_h_u02.bin b/fw/aic8800D80/fmacfw_8800d80_h_u02.bin index e61bc31..868bd38 100644 Binary files a/fw/aic8800D80/fmacfw_8800d80_h_u02.bin and b/fw/aic8800D80/fmacfw_8800d80_h_u02.bin differ diff --git a/fw/aic8800D80/fmacfw_8800d80_h_u02_ipc.bin b/fw/aic8800D80/fmacfw_8800d80_h_u02_ipc.bin index b06528a..6138563 100644 Binary files a/fw/aic8800D80/fmacfw_8800d80_h_u02_ipc.bin and b/fw/aic8800D80/fmacfw_8800d80_h_u02_ipc.bin differ diff --git a/fw/aic8800D80/fmacfw_8800d80_u02.bin b/fw/aic8800D80/fmacfw_8800d80_u02.bin index 6e48b9d..5891122 100644 Binary files a/fw/aic8800D80/fmacfw_8800d80_u02.bin and b/fw/aic8800D80/fmacfw_8800d80_u02.bin differ diff --git a/fw/aic8800D80/fmacfw_8800d80_u02_ipc.bin b/fw/aic8800D80/fmacfw_8800d80_u02_ipc.bin index 08581c7..b8286d2 100644 Binary files a/fw/aic8800D80/fmacfw_8800d80_u02_ipc.bin and b/fw/aic8800D80/fmacfw_8800d80_u02_ipc.bin differ diff --git a/fw/aic8800D80/fw_patch_8800d80_u02.bin b/fw/aic8800D80/fw_patch_8800d80_u02.bin index 348afe6..be2bc89 100644 Binary files a/fw/aic8800D80/fw_patch_8800d80_u02.bin and b/fw/aic8800D80/fw_patch_8800d80_u02.bin differ diff --git a/fw/aic8800D80/fw_patch_8800d80_u02_ext0.bin b/fw/aic8800D80/fw_patch_8800d80_u02_ext0.bin index 04330d1..be2bacb 100644 Binary files a/fw/aic8800D80/fw_patch_8800d80_u02_ext0.bin and b/fw/aic8800D80/fw_patch_8800d80_u02_ext0.bin differ diff --git a/fw/aic8800D80/fw_patch_table_8800d80_u02.bin b/fw/aic8800D80/fw_patch_table_8800d80_u02.bin index 8b77dc4..2b95e93 100644 Binary files a/fw/aic8800D80/fw_patch_table_8800d80_u02.bin and b/fw/aic8800D80/fw_patch_table_8800d80_u02.bin differ diff --git a/fw/aic8800D80/lmacfw_rf_8800d80_u02.bin b/fw/aic8800D80/lmacfw_rf_8800d80_u02.bin index 80d8313..1cd05ba 100644 Binary files a/fw/aic8800D80/lmacfw_rf_8800d80_u02.bin and b/fw/aic8800D80/lmacfw_rf_8800d80_u02.bin differ diff --git a/fw/aic8800D80N/aic_powerlimit_8800d80n.txt b/fw/aic8800D80N/aic_powerlimit_8800d80n.txt new file mode 100644 index 0000000..9a16186 --- /dev/null +++ b/fw/aic8800D80N/aic_powerlimit_8800d80n.txt @@ -0,0 +1,118 @@ +# AIC POWERLIMIT 2024/1108/1900 +# Max tx power reference: Linux wireless regulatory database for CRDA +# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt +# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment + +# Table 1: +## 2.4G, 20M,#5# +## START +## SRRC FCC ETSI JP UNSET +CH01 15 15 15 15 15 +CH02 16 16 16 16 16 +CH03 16 16 16 16 16 +CH04 16 16 16 16 16 +CH05 16 16 16 16 16 +CH06 16 16 16 16 16 +CH07 16 16 16 16 16 +CH08 16 16 16 16 16 +CH09 16 16 16 16 16 +CH10 16 16 16 16 16 +CH11 16 16 16 16 16 +CH12 12 12 12 12 12 +CH13 12 12 12 12 12 +CH14 NA NA NA 12 12 +## END + +# Table 2: +## 2.4G, 40M,#5# +## START +## SRRC FCC ETSI JP UNSET +CH01 NA NA NA NA NA +CH02 NA NA NA NA NA +CH03 16 16 16 16 16 +CH04 16 16 16 16 16 +CH05 16 16 16 16 16 +CH06 16 16 16 16 16 +CH07 16 16 16 16 16 +CH08 16 16 16 16 16 +CH09 16 16 16 16 16 +CH10 16 16 16 16 16 +CH11 16 16 16 16 16 +CH12 NA NA NA NA NA +CH13 NA NA NA NA NA +CH14 NA NA NA NA NA +## END + +# Table 3: +## 5G, 20M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH36 15 16 16 16 15 +CH40 15 16 16 16 15 +CH44 15 16 16 16 15 +CH48 15 16 16 16 15 +# 5G Band 2 +CH52 15 16 16 16 15 +CH56 15 16 16 16 15 +CH60 15 16 16 16 15 +CH64 15 16 16 16 15 +# 5G Band 3 +CH100 NA 16 16 16 15 +CH104 NA 16 16 16 15 +CH108 NA 16 16 16 15 +CH112 NA 16 16 16 15 +CH116 NA 16 16 16 15 +CH120 NA 16 16 16 15 +CH124 NA 16 16 16 15 +CH128 NA 16 16 16 15 +CH132 NA 16 16 16 15 +CH136 NA 16 16 16 15 +CH140 NA 16 16 16 15 +CH144 NA NA 16 16 15 +# 5G Band 4 +CH149 16 16 11 NA 11 +CH153 16 16 11 NA 11 +CH157 16 16 11 NA 11 +CH161 16 16 11 NA 11 +CH165 16 16 11 NA 11 +## END + +# Table 4: +## 5G, 40M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH38 15 16 16 16 15 +CH46 15 16 16 16 15 +# 5G Band 2 +CH54 15 16 16 16 15 +CH62 15 16 16 16 15 +# 5G Band 3 +CH102 NA 16 16 16 15 +CH110 NA 16 16 16 15 +CH118 NA 16 16 16 15 +CH126 NA 16 16 16 15 +CH134 NA 16 16 16 15 +CH142 NA 16 NA 16 15 +# 5G Band 4 +CH151 16 16 11 NA 11 +CH159 16 16 11 NA 11 +## END + +# Table 5: +## 5G, 80M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH42 15 16 16 16 15 +# 5G Band 2 +CH58 15 16 16 16 15 +# 5G Band 3 +CH106 NA 16 16 16 15 +CH122 NA 16 16 16 15 +CH138 NA 16 NA NA 15 +# 5G Band 4 +CH155 16 16 11 NA 11 +## END + diff --git a/fw/aic8800D80N/aic_userconfig_8800d80n.txt b/fw/aic8800D80N/aic_userconfig_8800d80n.txt new file mode 100644 index 0000000..80a05dd --- /dev/null +++ b/fw/aic8800D80N/aic_userconfig_8800d80n.txt @@ -0,0 +1,124 @@ +# AIC USERCONFIG 2026/01/1707 + +# txpwr_lvl +enable=1 +lvl_11b_11ag_1m_2g4=22 +lvl_11b_11ag_2m_2g4=22 +lvl_11b_11ag_5m5_2g4=22 +lvl_11b_11ag_11m_2g4=22 +lvl_11b_11ag_6m_2g4=22 +lvl_11b_11ag_9m_2g4=22 +lvl_11b_11ag_12m_2g4=22 +lvl_11b_11ag_18m_2g4=22 +lvl_11b_11ag_24m_2g4=21 +lvl_11b_11ag_36m_2g4=21 +lvl_11b_11ag_48m_2g4=20 +lvl_11b_11ag_54m_2g4=20 +lvl_11n_11ac_mcs0_2g4=20 +lvl_11n_11ac_mcs1_2g4=20 +lvl_11n_11ac_mcs2_2g4=20 +lvl_11n_11ac_mcs3_2g4=20 +lvl_11n_11ac_mcs4_2g4=18 +lvl_11n_11ac_mcs5_2g4=18 +lvl_11n_11ac_mcs6_2g4=18 +lvl_11n_11ac_mcs7_2g4=18 +lvl_11n_11ac_mcs8_2g4=17 +lvl_11n_11ac_mcs9_2g4=17 +lvl_11ax_mcs0_2g4=22 +lvl_11ax_mcs1_2g4=22 +lvl_11ax_mcs2_2g4=22 +lvl_11ax_mcs3_2g4=20 +lvl_11ax_mcs4_2g4=20 +lvl_11ax_mcs5_2g4=20 +lvl_11ax_mcs6_2g4=20 +lvl_11ax_mcs7_2g4=20 +lvl_11ax_mcs8_2g4=19 +lvl_11ax_mcs9_2g4=19 +lvl_11ax_mcs10_2g4=17 +lvl_11ax_mcs11_2g4=17 +lvl_11a_6m_5g=20 +lvl_11a_9m_5g=19 +lvl_11a_12m_5g=19 +lvl_11a_18m_5g=19 +lvl_11a_24m_5g=19 +lvl_11a_36m_5g=19 +lvl_11a_48m_5g=19 +lvl_11a_54m_5g=18 +lvl_11n_11ac_mcs0_5g=20 +lvl_11n_11ac_mcs1_5g=20 +lvl_11n_11ac_mcs2_5g=20 +lvl_11n_11ac_mcs3_5g=19 +lvl_11n_11ac_mcs4_5g=19 +lvl_11n_11ac_mcs5_5g=19 +lvl_11n_11ac_mcs6_5g=18 +lvl_11n_11ac_mcs7_5g=17 +lvl_11n_11ac_mcs8_5g=14 +lvl_11n_11ac_mcs9_5g=14 +lvl_11ax_mcs0_5g=20 +lvl_11ax_mcs1_5g=20 +lvl_11ax_mcs2_5g=20 +lvl_11ax_mcs3_5g=19 +lvl_11ax_mcs4_5g=19 +lvl_11ax_mcs5_5g=19 +lvl_11ax_mcs6_5g=19 +lvl_11ax_mcs7_5g=18 +lvl_11ax_mcs8_5g=13 +lvl_11ax_mcs9_5g=13 +lvl_11ax_mcs10_5g=13 +lvl_11ax_mcs11_5g=13 + +# txpwr_lvl_adj +lvl_adj_enable=0 +lvl_adj_2g4_chan_1_4=0 +lvl_adj_2g4_chan_5_9=0 +lvl_adj_2g4_chan_10_13=0 +lvl_adj_5g_chan_42=0 +lvl_adj_5g_chan_58=0 +lvl_adj_5g_chan_106=0 +lvl_adj_5g_chan_122=0 +lvl_adj_5g_chan_138=0 +lvl_adj_5g_chan_155=0 + +# txpwr_loss +loss_enable_2g4=0 +loss_value_2g4=2 +loss_enable_5g=0 +loss_value_5g=5 + +# txpwr_ofst +ofst_enable=0 +ofst_2g4_11b_chan_1_4=0 +ofst_2g4_11b_chan_5_9=0 +ofst_2g4_11b_chan_10_13=0 +ofst_2g4_ofdm_highrate_chan_1_4=0 +ofst_2g4_ofdm_highrate_chan_5_9=0 +ofst_2g4_ofdm_highrate_chan_10_13=0 +ofst_2g4_ofdm_lowrate_chan_1_4=0 +ofst_2g4_ofdm_lowrate_chan_5_9=0 +ofst_2g4_ofdm_lowrate_chan_10_13=0 +ofst_5g_ofdm_lowrate_chan_42=0 +ofst_5g_ofdm_lowrate_chan_58=0 +ofst_5g_ofdm_lowrate_chan_106=0 +ofst_5g_ofdm_lowrate_chan_122=0 +ofst_5g_ofdm_lowrate_chan_138=0 +ofst_5g_ofdm_lowrate_chan_155=0 +ofst_5g_ofdm_highrate_chan_42=0 +ofst_5g_ofdm_highrate_chan_58=0 +ofst_5g_ofdm_highrate_chan_106=0 +ofst_5g_ofdm_highrate_chan_122=0 +ofst_5g_ofdm_highrate_chan_138=0 +ofst_5g_ofdm_highrate_chan_155=0 +ofst_5g_ofdm_midrate_chan_42=0 +ofst_5g_ofdm_midrate_chan_58=0 +ofst_5g_ofdm_midrate_chan_106=0 +ofst_5g_ofdm_midrate_chan_122=0 +ofst_5g_ofdm_midrate_chan_138=0 +ofst_5g_ofdm_midrate_chan_155=0 + +# xtal cap +xtal_enable=0 +xtal_cap=24 +xtal_cap_fine=31 + + + diff --git a/fw/aic8800D80N/fmacfw_btusb_8800d80n_u02.bin b/fw/aic8800D80N/fmacfw_btusb_8800d80n_u02.bin new file mode 100644 index 0000000..f13a4b8 Binary files /dev/null and b/fw/aic8800D80N/fmacfw_btusb_8800d80n_u02.bin differ diff --git a/fw/aic8800D80N/fmacfw_calib_8800d80n_u02.bin b/fw/aic8800D80N/fmacfw_calib_8800d80n_u02.bin new file mode 100644 index 0000000..7ea88c0 Binary files /dev/null and b/fw/aic8800D80N/fmacfw_calib_8800d80n_u02.bin differ diff --git a/fw/aic8800D80N/fmacfw_cinit_8800d80n_u02.bin b/fw/aic8800D80N/fmacfw_cinit_8800d80n_u02.bin new file mode 100644 index 0000000..35c24c1 Binary files /dev/null and b/fw/aic8800D80N/fmacfw_cinit_8800d80n_u02.bin differ diff --git a/fw/aic8800D80N/fmacfw_patch_8800d80n_u02.bin b/fw/aic8800D80N/fmacfw_patch_8800d80n_u02.bin new file mode 100644 index 0000000..2cab19a Binary files /dev/null and b/fw/aic8800D80N/fmacfw_patch_8800d80n_u02.bin differ diff --git a/fw/aic8800D80N/fmacfw_patch_tbl_8800d80n_u02.bin b/fw/aic8800D80N/fmacfw_patch_tbl_8800d80n_u02.bin new file mode 100644 index 0000000..4a043f5 Binary files /dev/null and b/fw/aic8800D80N/fmacfw_patch_tbl_8800d80n_u02.bin differ diff --git a/fw/aic8800D80N/fw_patch_8800d80n_rf_u02.bin b/fw/aic8800D80N/fw_patch_8800d80n_rf_u02.bin new file mode 100644 index 0000000..a369f3a Binary files /dev/null and b/fw/aic8800D80N/fw_patch_8800d80n_rf_u02.bin differ diff --git a/fw/aic8800D80N/fw_patch_8800d80n_rf_u02_ext0.bin b/fw/aic8800D80N/fw_patch_8800d80n_rf_u02_ext0.bin new file mode 100644 index 0000000..a4a2475 Binary files /dev/null and b/fw/aic8800D80N/fw_patch_8800d80n_rf_u02_ext0.bin differ diff --git a/fw/aic8800D80N/fw_patch_8800d80n_u02.bin b/fw/aic8800D80N/fw_patch_8800d80n_u02.bin new file mode 100644 index 0000000..2b7e51f Binary files /dev/null and b/fw/aic8800D80N/fw_patch_8800d80n_u02.bin differ diff --git a/fw/aic8800D80N/fw_patch_8800d80n_u02_ext0.bin b/fw/aic8800D80N/fw_patch_8800d80n_u02_ext0.bin new file mode 100644 index 0000000..7b22837 Binary files /dev/null and b/fw/aic8800D80N/fw_patch_8800d80n_u02_ext0.bin differ diff --git a/fw/aic8800D80N/fw_patch_table_8800d80n_rf_u02.bin b/fw/aic8800D80N/fw_patch_table_8800d80n_rf_u02.bin new file mode 100644 index 0000000..215fbc8 Binary files /dev/null and b/fw/aic8800D80N/fw_patch_table_8800d80n_rf_u02.bin differ diff --git a/fw/aic8800D80N/fw_patch_table_8800d80n_u02.bin b/fw/aic8800D80N/fw_patch_table_8800d80n_u02.bin new file mode 100644 index 0000000..bd6b80f Binary files /dev/null and b/fw/aic8800D80N/fw_patch_table_8800d80n_u02.bin differ diff --git a/fw/aic8800D80N/lmacfw_rf_8800d80n.bin b/fw/aic8800D80N/lmacfw_rf_8800d80n.bin new file mode 100644 index 0000000..fe99d24 Binary files /dev/null and b/fw/aic8800D80N/lmacfw_rf_8800d80n.bin differ diff --git a/fw/aic8800D80X2/aic_powerlimit_8800d80x2.txt b/fw/aic8800D80X2/aic_powerlimit_8800d80x2.txt index 9a16186..4fd2ee9 100644 --- a/fw/aic8800D80X2/aic_powerlimit_8800d80x2.txt +++ b/fw/aic8800D80X2/aic_powerlimit_8800d80x2.txt @@ -1,118 +1,117 @@ -# AIC POWERLIMIT 2024/1108/1900 +# AIC POWERLIMIT 2025/0623/1700 # Max tx power reference: Linux wireless regulatory database for CRDA # https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt -# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment +# If loss_value in aic_userconfig.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment # Table 1: -## 2.4G, 20M,#5# +## 2.4G, 20M,#6# ## START -## SRRC FCC ETSI JP UNSET -CH01 15 15 15 15 15 -CH02 16 16 16 16 16 -CH03 16 16 16 16 16 -CH04 16 16 16 16 16 -CH05 16 16 16 16 16 -CH06 16 16 16 16 16 -CH07 16 16 16 16 16 -CH08 16 16 16 16 16 -CH09 16 16 16 16 16 -CH10 16 16 16 16 16 -CH11 16 16 16 16 16 -CH12 12 12 12 12 12 -CH13 12 12 12 12 12 -CH14 NA NA NA 12 12 +## SRRC FCC ETSI JP KCC UNSET +CH01 16 14 14 16 16 15 +CH02 16 14 14 16 16 16 +CH03 16 14 14 16 16 16 +CH04 16 14 14 16 16 16 +CH05 16 14 14 16 16 16 +CH06 16 14 14 16 16 16 +CH07 16 14 14 16 16 16 +CH08 16 14 14 16 16 16 +CH09 16 14 14 16 16 16 +CH10 16 14 14 16 16 16 +CH11 16 14 14 16 16 16 +CH12 15 14 14 16 16 12 +CH13 13 14 14 16 16 12 +CH14 NA NA NA 16 NA 12 ## END # Table 2: -## 2.4G, 40M,#5# +## 2.4G, 40M,#6# ## START -## SRRC FCC ETSI JP UNSET -CH01 NA NA NA NA NA -CH02 NA NA NA NA NA -CH03 16 16 16 16 16 -CH04 16 16 16 16 16 -CH05 16 16 16 16 16 -CH06 16 16 16 16 16 -CH07 16 16 16 16 16 -CH08 16 16 16 16 16 -CH09 16 16 16 16 16 -CH10 16 16 16 16 16 -CH11 16 16 16 16 16 -CH12 NA NA NA NA NA -CH13 NA NA NA NA NA -CH14 NA NA NA NA NA +## SRRC FCC ETSI JP KCC UNSET +CH01 NA NA NA NA NA NA +CH02 NA NA NA NA NA NA +CH03 16 13 14 16 16 16 +CH04 16 13 14 16 16 16 +CH05 16 13 14 16 16 16 +CH06 16 13 14 16 16 16 +CH07 16 13 14 16 16 16 +CH08 16 13 14 16 16 16 +CH09 16 11 14 16 16 16 +CH10 16 11 14 16 16 16 +CH11 16 11 14 16 16 16 +CH12 NA NA NA NA NA NA +CH13 NA NA NA NA NA NA +CH14 NA NA NA NA NA NA ## END # Table 3: -## 5G, 20M,#5# +## 5G, 20M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH36 15 16 16 16 15 -CH40 15 16 16 16 15 -CH44 15 16 16 16 15 -CH48 15 16 16 16 15 +CH36 15 16 16 16 16 15 +CH40 15 16 16 16 16 15 +CH44 15 16 16 16 16 15 +CH48 15 16 16 16 16 15 # 5G Band 2 -CH52 15 16 16 16 15 -CH56 15 16 16 16 15 -CH60 15 16 16 16 15 -CH64 15 16 16 16 15 +CH52 15 16 16 16 16 15 +CH56 15 16 16 16 16 15 +CH60 15 16 16 16 16 15 +CH64 15 16 16 16 16 15 # 5G Band 3 -CH100 NA 16 16 16 15 -CH104 NA 16 16 16 15 -CH108 NA 16 16 16 15 -CH112 NA 16 16 16 15 -CH116 NA 16 16 16 15 -CH120 NA 16 16 16 15 -CH124 NA 16 16 16 15 -CH128 NA 16 16 16 15 -CH132 NA 16 16 16 15 -CH136 NA 16 16 16 15 -CH140 NA 16 16 16 15 -CH144 NA NA 16 16 15 +CH100 NA 16 16 16 16 15 +CH104 NA 16 16 16 16 15 +CH108 NA 16 16 16 16 15 +CH112 NA 16 16 16 16 15 +CH116 NA 16 16 16 16 15 +CH120 NA 16 16 16 16 15 +CH124 NA 16 16 16 16 15 +CH128 NA 16 16 16 16 15 +CH132 NA 16 16 16 16 15 +CH136 NA 16 16 16 16 15 +CH140 NA 16 16 16 16 15 +CH144 NA NA 16 16 16 15 # 5G Band 4 -CH149 16 16 11 NA 11 -CH153 16 16 11 NA 11 -CH157 16 16 11 NA 11 -CH161 16 16 11 NA 11 -CH165 16 16 11 NA 11 +CH149 20 16 8 NA 20 11 +CH153 20 16 8 NA 20 11 +CH157 20 16 8 NA 20 11 +CH161 20 16 8 NA 20 11 +CH165 20 16 8 NA 20 11 ## END # Table 4: -## 5G, 40M,#5# +## 5G, 40M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH38 15 16 16 16 15 -CH46 15 16 16 16 15 +CH38 15 16 16 16 20 15 +CH46 15 16 16 16 20 15 # 5G Band 2 -CH54 15 16 16 16 15 -CH62 15 16 16 16 15 +CH54 15 16 16 16 20 15 +CH62 15 16 16 16 20 15 # 5G Band 3 -CH102 NA 16 16 16 15 -CH110 NA 16 16 16 15 -CH118 NA 16 16 16 15 -CH126 NA 16 16 16 15 -CH134 NA 16 16 16 15 -CH142 NA 16 NA 16 15 +CH102 NA 16 16 16 20 15 +CH110 NA 16 16 16 20 15 +CH118 NA 16 16 16 20 15 +CH126 NA 16 16 16 20 15 +CH134 NA 16 16 16 20 15 +CH142 NA 16 NA 16 20 15 # 5G Band 4 -CH151 16 16 11 NA 11 -CH159 16 16 11 NA 11 +CH151 16 15 8 NA 18 11 +CH159 17 16 8 NA 17 11 ## END # Table 5: -## 5G, 80M,#5# +## 5G, 80M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH42 15 16 16 16 15 +CH42 15 16 16 16 20 15 # 5G Band 2 -CH58 15 16 16 16 15 +CH58 15 16 16 16 20 15 # 5G Band 3 -CH106 NA 16 16 16 15 -CH122 NA 16 16 16 15 -CH138 NA 16 NA NA 15 +CH106 NA 16 16 16 20 15 +CH122 NA 16 16 16 20 15 +CH138 NA 16 NA NA 20 15 # 5G Band 4 -CH155 16 16 11 NA 11 -## END - +CH155 15 14 8 NA 16 11 +## END \ No newline at end of file diff --git a/fw/aic8800D80X2/aicbt.conf b/fw/aic8800D80X2/aicbt.conf new file mode 100644 index 0000000..4d9b6f7 --- /dev/null +++ b/fw/aic8800D80X2/aicbt.conf @@ -0,0 +1,8 @@ +BTMODE=5 # 模式 0 ~ 5 (ONLY_SW|WIFI_COMBO|ONLY|ONLY_TEST|WIFI_COMBO_TEST|ONLY_COANT) +BTPORT=2 # 1 (USB) | 2(Uart) +UART_BAUD=1500000 # 115200 ~ 3250000 +UART_FC=0 # 0 (Disable) | 1(Enable) +LPM_ENABLE=0 # 0 (Disable) | 1(Enable) +TXPWR_LVL=00006F2F # first byte, min pwr lvl; second byte, max pwr lvl; 20(min), 30 , 40 , 50 , 60(max) + + diff --git a/fw/aic8800D80X2/fmacfw_8800d80x2.bin b/fw/aic8800D80X2/fmacfw_8800d80x2.bin index 91beb8b..713d6a3 100644 Binary files a/fw/aic8800D80X2/fmacfw_8800d80x2.bin and b/fw/aic8800D80X2/fmacfw_8800d80x2.bin differ diff --git a/fw/aic8800D80X2/fw_patch_8800d80x2_u05.bin b/fw/aic8800D80X2/fw_patch_8800d80x2_u05.bin index a99d090..4c81d43 100644 Binary files a/fw/aic8800D80X2/fw_patch_8800d80x2_u05.bin and b/fw/aic8800D80X2/fw_patch_8800d80x2_u05.bin differ diff --git a/fw/aic8800D80X2/fw_patch_8800d80x2_u05_ext0.bin b/fw/aic8800D80X2/fw_patch_8800d80x2_u05_ext0.bin new file mode 100644 index 0000000..b5484d3 Binary files /dev/null and b/fw/aic8800D80X2/fw_patch_8800d80x2_u05_ext0.bin differ diff --git a/fw/aic8800D80X2/fw_patch_8800d80x2_u05_ext1.bin b/fw/aic8800D80X2/fw_patch_8800d80x2_u05_ext1.bin new file mode 100644 index 0000000..e98711b Binary files /dev/null and b/fw/aic8800D80X2/fw_patch_8800d80x2_u05_ext1.bin differ diff --git a/fw/aic8800D80X2/fw_patch_table_8800d80x2_u05.bin b/fw/aic8800D80X2/fw_patch_table_8800d80x2_u05.bin index cfdc874..7468996 100644 Binary files a/fw/aic8800D80X2/fw_patch_table_8800d80x2_u05.bin and b/fw/aic8800D80X2/fw_patch_table_8800d80x2_u05.bin differ diff --git a/fw/aic8800D80X2/lmacfw_rf_8800d80x2.bin b/fw/aic8800D80X2/lmacfw_rf_8800d80x2.bin index 593f9e4..8ebe418 100644 Binary files a/fw/aic8800D80X2/lmacfw_rf_8800d80x2.bin and b/fw/aic8800D80X2/lmacfw_rf_8800d80x2.bin differ diff --git a/fw/aic8800DC/aic_powerlimit_8800dc.txt b/fw/aic8800DC/aic_powerlimit_8800dc.txt index 9a16186..4fd2ee9 100644 --- a/fw/aic8800DC/aic_powerlimit_8800dc.txt +++ b/fw/aic8800DC/aic_powerlimit_8800dc.txt @@ -1,118 +1,117 @@ -# AIC POWERLIMIT 2024/1108/1900 +# AIC POWERLIMIT 2025/0623/1700 # Max tx power reference: Linux wireless regulatory database for CRDA # https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt -# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment +# If loss_value in aic_userconfig.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment # Table 1: -## 2.4G, 20M,#5# +## 2.4G, 20M,#6# ## START -## SRRC FCC ETSI JP UNSET -CH01 15 15 15 15 15 -CH02 16 16 16 16 16 -CH03 16 16 16 16 16 -CH04 16 16 16 16 16 -CH05 16 16 16 16 16 -CH06 16 16 16 16 16 -CH07 16 16 16 16 16 -CH08 16 16 16 16 16 -CH09 16 16 16 16 16 -CH10 16 16 16 16 16 -CH11 16 16 16 16 16 -CH12 12 12 12 12 12 -CH13 12 12 12 12 12 -CH14 NA NA NA 12 12 +## SRRC FCC ETSI JP KCC UNSET +CH01 16 14 14 16 16 15 +CH02 16 14 14 16 16 16 +CH03 16 14 14 16 16 16 +CH04 16 14 14 16 16 16 +CH05 16 14 14 16 16 16 +CH06 16 14 14 16 16 16 +CH07 16 14 14 16 16 16 +CH08 16 14 14 16 16 16 +CH09 16 14 14 16 16 16 +CH10 16 14 14 16 16 16 +CH11 16 14 14 16 16 16 +CH12 15 14 14 16 16 12 +CH13 13 14 14 16 16 12 +CH14 NA NA NA 16 NA 12 ## END # Table 2: -## 2.4G, 40M,#5# +## 2.4G, 40M,#6# ## START -## SRRC FCC ETSI JP UNSET -CH01 NA NA NA NA NA -CH02 NA NA NA NA NA -CH03 16 16 16 16 16 -CH04 16 16 16 16 16 -CH05 16 16 16 16 16 -CH06 16 16 16 16 16 -CH07 16 16 16 16 16 -CH08 16 16 16 16 16 -CH09 16 16 16 16 16 -CH10 16 16 16 16 16 -CH11 16 16 16 16 16 -CH12 NA NA NA NA NA -CH13 NA NA NA NA NA -CH14 NA NA NA NA NA +## SRRC FCC ETSI JP KCC UNSET +CH01 NA NA NA NA NA NA +CH02 NA NA NA NA NA NA +CH03 16 13 14 16 16 16 +CH04 16 13 14 16 16 16 +CH05 16 13 14 16 16 16 +CH06 16 13 14 16 16 16 +CH07 16 13 14 16 16 16 +CH08 16 13 14 16 16 16 +CH09 16 11 14 16 16 16 +CH10 16 11 14 16 16 16 +CH11 16 11 14 16 16 16 +CH12 NA NA NA NA NA NA +CH13 NA NA NA NA NA NA +CH14 NA NA NA NA NA NA ## END # Table 3: -## 5G, 20M,#5# +## 5G, 20M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH36 15 16 16 16 15 -CH40 15 16 16 16 15 -CH44 15 16 16 16 15 -CH48 15 16 16 16 15 +CH36 15 16 16 16 16 15 +CH40 15 16 16 16 16 15 +CH44 15 16 16 16 16 15 +CH48 15 16 16 16 16 15 # 5G Band 2 -CH52 15 16 16 16 15 -CH56 15 16 16 16 15 -CH60 15 16 16 16 15 -CH64 15 16 16 16 15 +CH52 15 16 16 16 16 15 +CH56 15 16 16 16 16 15 +CH60 15 16 16 16 16 15 +CH64 15 16 16 16 16 15 # 5G Band 3 -CH100 NA 16 16 16 15 -CH104 NA 16 16 16 15 -CH108 NA 16 16 16 15 -CH112 NA 16 16 16 15 -CH116 NA 16 16 16 15 -CH120 NA 16 16 16 15 -CH124 NA 16 16 16 15 -CH128 NA 16 16 16 15 -CH132 NA 16 16 16 15 -CH136 NA 16 16 16 15 -CH140 NA 16 16 16 15 -CH144 NA NA 16 16 15 +CH100 NA 16 16 16 16 15 +CH104 NA 16 16 16 16 15 +CH108 NA 16 16 16 16 15 +CH112 NA 16 16 16 16 15 +CH116 NA 16 16 16 16 15 +CH120 NA 16 16 16 16 15 +CH124 NA 16 16 16 16 15 +CH128 NA 16 16 16 16 15 +CH132 NA 16 16 16 16 15 +CH136 NA 16 16 16 16 15 +CH140 NA 16 16 16 16 15 +CH144 NA NA 16 16 16 15 # 5G Band 4 -CH149 16 16 11 NA 11 -CH153 16 16 11 NA 11 -CH157 16 16 11 NA 11 -CH161 16 16 11 NA 11 -CH165 16 16 11 NA 11 +CH149 20 16 8 NA 20 11 +CH153 20 16 8 NA 20 11 +CH157 20 16 8 NA 20 11 +CH161 20 16 8 NA 20 11 +CH165 20 16 8 NA 20 11 ## END # Table 4: -## 5G, 40M,#5# +## 5G, 40M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH38 15 16 16 16 15 -CH46 15 16 16 16 15 +CH38 15 16 16 16 20 15 +CH46 15 16 16 16 20 15 # 5G Band 2 -CH54 15 16 16 16 15 -CH62 15 16 16 16 15 +CH54 15 16 16 16 20 15 +CH62 15 16 16 16 20 15 # 5G Band 3 -CH102 NA 16 16 16 15 -CH110 NA 16 16 16 15 -CH118 NA 16 16 16 15 -CH126 NA 16 16 16 15 -CH134 NA 16 16 16 15 -CH142 NA 16 NA 16 15 +CH102 NA 16 16 16 20 15 +CH110 NA 16 16 16 20 15 +CH118 NA 16 16 16 20 15 +CH126 NA 16 16 16 20 15 +CH134 NA 16 16 16 20 15 +CH142 NA 16 NA 16 20 15 # 5G Band 4 -CH151 16 16 11 NA 11 -CH159 16 16 11 NA 11 +CH151 16 15 8 NA 18 11 +CH159 17 16 8 NA 17 11 ## END # Table 5: -## 5G, 80M,#5# +## 5G, 80M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH42 15 16 16 16 15 +CH42 15 16 16 16 20 15 # 5G Band 2 -CH58 15 16 16 16 15 +CH58 15 16 16 16 20 15 # 5G Band 3 -CH106 NA 16 16 16 15 -CH122 NA 16 16 16 15 -CH138 NA 16 NA NA 15 +CH106 NA 16 16 16 20 15 +CH122 NA 16 16 16 20 15 +CH138 NA 16 NA NA 20 15 # 5G Band 4 -CH155 16 16 11 NA 11 -## END - +CH155 15 14 8 NA 16 11 +## END \ No newline at end of file diff --git a/fw/aic8800DC/aic_powerlimit_8800dw.txt b/fw/aic8800DC/aic_powerlimit_8800dw.txt index 9a16186..4fd2ee9 100644 --- a/fw/aic8800DC/aic_powerlimit_8800dw.txt +++ b/fw/aic8800DC/aic_powerlimit_8800dw.txt @@ -1,118 +1,117 @@ -# AIC POWERLIMIT 2024/1108/1900 +# AIC POWERLIMIT 2025/0623/1700 # Max tx power reference: Linux wireless regulatory database for CRDA # https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt -# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment +# If loss_value in aic_userconfig.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment # Table 1: -## 2.4G, 20M,#5# +## 2.4G, 20M,#6# ## START -## SRRC FCC ETSI JP UNSET -CH01 15 15 15 15 15 -CH02 16 16 16 16 16 -CH03 16 16 16 16 16 -CH04 16 16 16 16 16 -CH05 16 16 16 16 16 -CH06 16 16 16 16 16 -CH07 16 16 16 16 16 -CH08 16 16 16 16 16 -CH09 16 16 16 16 16 -CH10 16 16 16 16 16 -CH11 16 16 16 16 16 -CH12 12 12 12 12 12 -CH13 12 12 12 12 12 -CH14 NA NA NA 12 12 +## SRRC FCC ETSI JP KCC UNSET +CH01 16 14 14 16 16 15 +CH02 16 14 14 16 16 16 +CH03 16 14 14 16 16 16 +CH04 16 14 14 16 16 16 +CH05 16 14 14 16 16 16 +CH06 16 14 14 16 16 16 +CH07 16 14 14 16 16 16 +CH08 16 14 14 16 16 16 +CH09 16 14 14 16 16 16 +CH10 16 14 14 16 16 16 +CH11 16 14 14 16 16 16 +CH12 15 14 14 16 16 12 +CH13 13 14 14 16 16 12 +CH14 NA NA NA 16 NA 12 ## END # Table 2: -## 2.4G, 40M,#5# +## 2.4G, 40M,#6# ## START -## SRRC FCC ETSI JP UNSET -CH01 NA NA NA NA NA -CH02 NA NA NA NA NA -CH03 16 16 16 16 16 -CH04 16 16 16 16 16 -CH05 16 16 16 16 16 -CH06 16 16 16 16 16 -CH07 16 16 16 16 16 -CH08 16 16 16 16 16 -CH09 16 16 16 16 16 -CH10 16 16 16 16 16 -CH11 16 16 16 16 16 -CH12 NA NA NA NA NA -CH13 NA NA NA NA NA -CH14 NA NA NA NA NA +## SRRC FCC ETSI JP KCC UNSET +CH01 NA NA NA NA NA NA +CH02 NA NA NA NA NA NA +CH03 16 13 14 16 16 16 +CH04 16 13 14 16 16 16 +CH05 16 13 14 16 16 16 +CH06 16 13 14 16 16 16 +CH07 16 13 14 16 16 16 +CH08 16 13 14 16 16 16 +CH09 16 11 14 16 16 16 +CH10 16 11 14 16 16 16 +CH11 16 11 14 16 16 16 +CH12 NA NA NA NA NA NA +CH13 NA NA NA NA NA NA +CH14 NA NA NA NA NA NA ## END # Table 3: -## 5G, 20M,#5# +## 5G, 20M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH36 15 16 16 16 15 -CH40 15 16 16 16 15 -CH44 15 16 16 16 15 -CH48 15 16 16 16 15 +CH36 15 16 16 16 16 15 +CH40 15 16 16 16 16 15 +CH44 15 16 16 16 16 15 +CH48 15 16 16 16 16 15 # 5G Band 2 -CH52 15 16 16 16 15 -CH56 15 16 16 16 15 -CH60 15 16 16 16 15 -CH64 15 16 16 16 15 +CH52 15 16 16 16 16 15 +CH56 15 16 16 16 16 15 +CH60 15 16 16 16 16 15 +CH64 15 16 16 16 16 15 # 5G Band 3 -CH100 NA 16 16 16 15 -CH104 NA 16 16 16 15 -CH108 NA 16 16 16 15 -CH112 NA 16 16 16 15 -CH116 NA 16 16 16 15 -CH120 NA 16 16 16 15 -CH124 NA 16 16 16 15 -CH128 NA 16 16 16 15 -CH132 NA 16 16 16 15 -CH136 NA 16 16 16 15 -CH140 NA 16 16 16 15 -CH144 NA NA 16 16 15 +CH100 NA 16 16 16 16 15 +CH104 NA 16 16 16 16 15 +CH108 NA 16 16 16 16 15 +CH112 NA 16 16 16 16 15 +CH116 NA 16 16 16 16 15 +CH120 NA 16 16 16 16 15 +CH124 NA 16 16 16 16 15 +CH128 NA 16 16 16 16 15 +CH132 NA 16 16 16 16 15 +CH136 NA 16 16 16 16 15 +CH140 NA 16 16 16 16 15 +CH144 NA NA 16 16 16 15 # 5G Band 4 -CH149 16 16 11 NA 11 -CH153 16 16 11 NA 11 -CH157 16 16 11 NA 11 -CH161 16 16 11 NA 11 -CH165 16 16 11 NA 11 +CH149 20 16 8 NA 20 11 +CH153 20 16 8 NA 20 11 +CH157 20 16 8 NA 20 11 +CH161 20 16 8 NA 20 11 +CH165 20 16 8 NA 20 11 ## END # Table 4: -## 5G, 40M,#5# +## 5G, 40M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH38 15 16 16 16 15 -CH46 15 16 16 16 15 +CH38 15 16 16 16 20 15 +CH46 15 16 16 16 20 15 # 5G Band 2 -CH54 15 16 16 16 15 -CH62 15 16 16 16 15 +CH54 15 16 16 16 20 15 +CH62 15 16 16 16 20 15 # 5G Band 3 -CH102 NA 16 16 16 15 -CH110 NA 16 16 16 15 -CH118 NA 16 16 16 15 -CH126 NA 16 16 16 15 -CH134 NA 16 16 16 15 -CH142 NA 16 NA 16 15 +CH102 NA 16 16 16 20 15 +CH110 NA 16 16 16 20 15 +CH118 NA 16 16 16 20 15 +CH126 NA 16 16 16 20 15 +CH134 NA 16 16 16 20 15 +CH142 NA 16 NA 16 20 15 # 5G Band 4 -CH151 16 16 11 NA 11 -CH159 16 16 11 NA 11 +CH151 16 15 8 NA 18 11 +CH159 17 16 8 NA 17 11 ## END # Table 5: -## 5G, 80M,#5# +## 5G, 80M,#6# ## START -## SRRC FCC ETSI JP UNSET +## SRRC FCC ETSI JP KCC UNSET # 5G Band 1 -CH42 15 16 16 16 15 +CH42 15 16 16 16 20 15 # 5G Band 2 -CH58 15 16 16 16 15 +CH58 15 16 16 16 20 15 # 5G Band 3 -CH106 NA 16 16 16 15 -CH122 NA 16 16 16 15 -CH138 NA 16 NA NA 15 +CH106 NA 16 16 16 20 15 +CH122 NA 16 16 16 20 15 +CH138 NA 16 NA NA 20 15 # 5G Band 4 -CH155 16 16 11 NA 11 -## END - +CH155 15 14 8 NA 16 11 +## END \ No newline at end of file diff --git a/fw/aic8800DC/fmacfw_calib_8800dc_h_u02.bin b/fw/aic8800DC/fmacfw_calib_8800dc_h_u02.bin index 236bb7f..19f5dd7 100644 Binary files a/fw/aic8800DC/fmacfw_calib_8800dc_h_u02.bin and b/fw/aic8800DC/fmacfw_calib_8800dc_h_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_calib_8800dc_u02.bin b/fw/aic8800DC/fmacfw_calib_8800dc_u02.bin index 40f7f2e..a5354f3 100644 Binary files a/fw/aic8800DC/fmacfw_calib_8800dc_u02.bin and b/fw/aic8800DC/fmacfw_calib_8800dc_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_patch_8800dc_h_u02.bin b/fw/aic8800DC/fmacfw_patch_8800dc_h_u02.bin index 7893a05..346c6c2 100644 Binary files a/fw/aic8800DC/fmacfw_patch_8800dc_h_u02.bin and b/fw/aic8800DC/fmacfw_patch_8800dc_h_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_patch_8800dc_u02.bin b/fw/aic8800DC/fmacfw_patch_8800dc_u02.bin index ba06fd4..7c9cae7 100644 Binary files a/fw/aic8800DC/fmacfw_patch_8800dc_u02.bin and b/fw/aic8800DC/fmacfw_patch_8800dc_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_patch_tbl_8800dc_h_u02.bin b/fw/aic8800DC/fmacfw_patch_tbl_8800dc_h_u02.bin index bc6eb39..d5a3954 100644 Binary files a/fw/aic8800DC/fmacfw_patch_tbl_8800dc_h_u02.bin and b/fw/aic8800DC/fmacfw_patch_tbl_8800dc_h_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_patch_tbl_8800dc_u02.bin b/fw/aic8800DC/fmacfw_patch_tbl_8800dc_u02.bin index 428720c..1d64b80 100644 Binary files a/fw/aic8800DC/fmacfw_patch_tbl_8800dc_u02.bin and b/fw/aic8800DC/fmacfw_patch_tbl_8800dc_u02.bin differ diff --git a/fw/aic8800DC/fw_patch_8800dc_u02.bin b/fw/aic8800DC/fw_patch_8800dc_u02.bin index 359b05e..be4dcf0 100644 Binary files a/fw/aic8800DC/fw_patch_8800dc_u02.bin and b/fw/aic8800DC/fw_patch_8800dc_u02.bin differ diff --git a/fw/aic8800DC/fw_patch_8800dc_u02_ext0.bin b/fw/aic8800DC/fw_patch_8800dc_u02_ext0.bin index b37c883..14e3945 100644 Binary files a/fw/aic8800DC/fw_patch_8800dc_u02_ext0.bin and b/fw/aic8800DC/fw_patch_8800dc_u02_ext0.bin differ diff --git a/fw/aic8800DC/fw_patch_8800dc_u02h.bin b/fw/aic8800DC/fw_patch_8800dc_u02h.bin index b403ff9..092d19a 100644 Binary files a/fw/aic8800DC/fw_patch_8800dc_u02h.bin and b/fw/aic8800DC/fw_patch_8800dc_u02h.bin differ diff --git a/fw/aic8800DC/fw_patch_table_8800dc_u02.bin b/fw/aic8800DC/fw_patch_table_8800dc_u02.bin index a7a33b7..d39e497 100644 Binary files a/fw/aic8800DC/fw_patch_table_8800dc_u02.bin and b/fw/aic8800DC/fw_patch_table_8800dc_u02.bin differ diff --git a/fw/aic8800DC/fw_patch_table_8800dc_u02h.bin b/fw/aic8800DC/fw_patch_table_8800dc_u02h.bin index d117d1e..5b367a0 100644 Binary files a/fw/aic8800DC/fw_patch_table_8800dc_u02h.bin and b/fw/aic8800DC/fw_patch_table_8800dc_u02h.bin differ diff --git a/fw/aic8800DC/lmacfw_rf_8800dc.bin b/fw/aic8800DC/lmacfw_rf_8800dc.bin index 1373376..9015d2c 100644 Binary files a/fw/aic8800DC/lmacfw_rf_8800dc.bin and b/fw/aic8800DC/lmacfw_rf_8800dc.bin differ diff --git a/fw/aic8800DLN/aic_powerlimit_8800dln.txt b/fw/aic8800DLN/aic_powerlimit_8800dln.txt new file mode 100644 index 0000000..9a16186 --- /dev/null +++ b/fw/aic8800DLN/aic_powerlimit_8800dln.txt @@ -0,0 +1,118 @@ +# AIC POWERLIMIT 2024/1108/1900 +# Max tx power reference: Linux wireless regulatory database for CRDA +# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt +# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment + +# Table 1: +## 2.4G, 20M,#5# +## START +## SRRC FCC ETSI JP UNSET +CH01 15 15 15 15 15 +CH02 16 16 16 16 16 +CH03 16 16 16 16 16 +CH04 16 16 16 16 16 +CH05 16 16 16 16 16 +CH06 16 16 16 16 16 +CH07 16 16 16 16 16 +CH08 16 16 16 16 16 +CH09 16 16 16 16 16 +CH10 16 16 16 16 16 +CH11 16 16 16 16 16 +CH12 12 12 12 12 12 +CH13 12 12 12 12 12 +CH14 NA NA NA 12 12 +## END + +# Table 2: +## 2.4G, 40M,#5# +## START +## SRRC FCC ETSI JP UNSET +CH01 NA NA NA NA NA +CH02 NA NA NA NA NA +CH03 16 16 16 16 16 +CH04 16 16 16 16 16 +CH05 16 16 16 16 16 +CH06 16 16 16 16 16 +CH07 16 16 16 16 16 +CH08 16 16 16 16 16 +CH09 16 16 16 16 16 +CH10 16 16 16 16 16 +CH11 16 16 16 16 16 +CH12 NA NA NA NA NA +CH13 NA NA NA NA NA +CH14 NA NA NA NA NA +## END + +# Table 3: +## 5G, 20M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH36 15 16 16 16 15 +CH40 15 16 16 16 15 +CH44 15 16 16 16 15 +CH48 15 16 16 16 15 +# 5G Band 2 +CH52 15 16 16 16 15 +CH56 15 16 16 16 15 +CH60 15 16 16 16 15 +CH64 15 16 16 16 15 +# 5G Band 3 +CH100 NA 16 16 16 15 +CH104 NA 16 16 16 15 +CH108 NA 16 16 16 15 +CH112 NA 16 16 16 15 +CH116 NA 16 16 16 15 +CH120 NA 16 16 16 15 +CH124 NA 16 16 16 15 +CH128 NA 16 16 16 15 +CH132 NA 16 16 16 15 +CH136 NA 16 16 16 15 +CH140 NA 16 16 16 15 +CH144 NA NA 16 16 15 +# 5G Band 4 +CH149 16 16 11 NA 11 +CH153 16 16 11 NA 11 +CH157 16 16 11 NA 11 +CH161 16 16 11 NA 11 +CH165 16 16 11 NA 11 +## END + +# Table 4: +## 5G, 40M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH38 15 16 16 16 15 +CH46 15 16 16 16 15 +# 5G Band 2 +CH54 15 16 16 16 15 +CH62 15 16 16 16 15 +# 5G Band 3 +CH102 NA 16 16 16 15 +CH110 NA 16 16 16 15 +CH118 NA 16 16 16 15 +CH126 NA 16 16 16 15 +CH134 NA 16 16 16 15 +CH142 NA 16 NA 16 15 +# 5G Band 4 +CH151 16 16 11 NA 11 +CH159 16 16 11 NA 11 +## END + +# Table 5: +## 5G, 80M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH42 15 16 16 16 15 +# 5G Band 2 +CH58 15 16 16 16 15 +# 5G Band 3 +CH106 NA 16 16 16 15 +CH122 NA 16 16 16 15 +CH138 NA 16 NA NA 15 +# 5G Band 4 +CH155 16 16 11 NA 11 +## END + diff --git a/fw/aic8800DLN/aic_userconfig_8800dln.txt b/fw/aic8800DLN/aic_userconfig_8800dln.txt new file mode 100644 index 0000000..061d86f --- /dev/null +++ b/fw/aic8800DLN/aic_userconfig_8800dln.txt @@ -0,0 +1,68 @@ +# AIC USERCONFIG 2025/1016/1157 + +# txpwr_lvl +enable=1 +lvl_11b_11ag_1m_2g4=18 +lvl_11b_11ag_2m_2g4=18 +lvl_11b_11ag_5m5_2g4=18 +lvl_11b_11ag_11m_2g4=18 +lvl_11b_11ag_6m_2g4=18 +lvl_11b_11ag_9m_2g4=18 +lvl_11b_11ag_12m_2g4=18 +lvl_11b_11ag_18m_2g4=18 +lvl_11b_11ag_24m_2g4=16 +lvl_11b_11ag_36m_2g4=16 +lvl_11b_11ag_48m_2g4=15 +lvl_11b_11ag_54m_2g4=15 +lvl_11n_11ac_mcs0_2g4=18 +lvl_11n_11ac_mcs1_2g4=18 +lvl_11n_11ac_mcs2_2g4=18 +lvl_11n_11ac_mcs3_2g4=18 +lvl_11n_11ac_mcs4_2g4=16 +lvl_11n_11ac_mcs5_2g4=16 +lvl_11n_11ac_mcs6_2g4=15 +lvl_11n_11ac_mcs7_2g4=15 +lvl_11n_11ac_mcs8_2g4=14 +lvl_11n_11ac_mcs9_2g4=14 +lvl_11ax_mcs0_2g4=18 +lvl_11ax_mcs1_2g4=18 +lvl_11ax_mcs2_2g4=18 +lvl_11ax_mcs3_2g4=18 +lvl_11ax_mcs4_2g4=16 +lvl_11ax_mcs5_2g4=16 +lvl_11ax_mcs6_2g4=15 +lvl_11ax_mcs7_2g4=15 +lvl_11ax_mcs8_2g4=14 +lvl_11ax_mcs9_2g4=14 +lvl_11ax_mcs10_2g4=13 +lvl_11ax_mcs11_2g4=13 + +# txpwr_lvl_adj +lvl_adj_enable=0 +lvl_adj_2g4_chan_1_4=0 +lvl_adj_2g4_chan_5_9=0 +lvl_adj_2g4_chan_10_13=0 + +# txpwr_loss +loss_enable_2g4=0 +loss_value_2g4=2 + +# txpwr_ofst +ofst_enable=0 +ofst_2g4_11b_chan_1_4=0 +ofst_2g4_11b_chan_5_9=0 +ofst_2g4_11b_chan_10_13=0 +ofst_2g4_ofdm_highrate_chan_1_4=0 +ofst_2g4_ofdm_highrate_chan_5_9=0 +ofst_2g4_ofdm_highrate_chan_10_13=0 +ofst_2g4_ofdm_lowrate_chan_1_4=0 +ofst_2g4_ofdm_lowrate_chan_5_9=0 +ofst_2g4_ofdm_lowrate_chan_10_13=0 + +# xtal cap +xtal_enable=0 +xtal_cap=24 +xtal_cap_fine=31 + + + diff --git a/fw/aic8800DLN/fmacfw_gaintbl_8800dln.bin b/fw/aic8800DLN/fmacfw_gaintbl_8800dln.bin new file mode 100644 index 0000000..ad855c3 Binary files /dev/null and b/fw/aic8800DLN/fmacfw_gaintbl_8800dln.bin differ diff --git a/fw/aic8800DLN/fmacfw_initvar_8800dln.bin b/fw/aic8800DLN/fmacfw_initvar_8800dln.bin new file mode 100644 index 0000000..b3c0646 Binary files /dev/null and b/fw/aic8800DLN/fmacfw_initvar_8800dln.bin differ diff --git a/install.sh b/install.sh index d3efa44..6ad08ff 100755 --- a/install.sh +++ b/install.sh @@ -241,27 +241,38 @@ install_dependencies() { install_firmware() { print_step "Installing firmware..." - - local fw_source="${SCRIPT_DIR}/fw/aic8800D80" - local fw_dest="/lib/firmware/aic8800D80" - - if [ ! -d "$fw_source" ]; then - print_error "Firmware directory not found: $fw_source" + + local fw_base="${SCRIPT_DIR}/fw" + + if [ ! -d "$fw_base" ]; then + print_error "Firmware directory not found: $fw_base" echo "Please ensure you're running the script from the repository root." exit 1 fi - + # Remove old firmware versions - if [ -d "$fw_dest" ]; then + if [ -d "/lib/firmware" ] && [ -n "$(find /lib/firmware -maxdepth 1 -name 'aic8800*' -type d 2>/dev/null)" ]; 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 + rm -rf /lib/firmware/aic8800* >> "$LOG_FILE" 2>&1 fi - - # Copy new firmware - print_info "Copying firmware to $fw_dest..." - cp -r "$fw_source" "$fw_dest" >> "$LOG_FILE" 2>&1 + + # Copy all firmware variants + print_info "Installing firmware for all chip variants..." + for fw_dir in "$fw_base"/aic8800*; do + if [ -d "$fw_dir" ]; then + local fw_name=$(basename "$fw_dir") + local fw_dest="/lib/firmware/$fw_name" + print_info "Copying $fw_name firmware to $fw_dest..." + cp -r "$fw_dir" "$fw_dest" >> "$LOG_FILE" 2>&1 + fi + done + + print_success "Firmware installed for all chip variants:" + print_info " - aic8800D80 (standard)" + print_info " - aic8800D80N (N variant)" + print_info " - aic8800D80X2 (X2 variant)" + print_info " - aic8800DC/DW (DC/DW series)" + print_info " - aic8800DLN (DLN variant)" # Install udev rules local rules_source="${SCRIPT_DIR}/aic.rules" @@ -440,8 +451,15 @@ load_module() { print_info "Try rebooting or check: sudo dmesg | grep aic8800" fi - # Bluetooth is handled by the standard btusb driver after firmware upload - print_info "Bluetooth will be available via the standard btusb driver once hardware is connected." + # Load the standard Bluetooth driver (btusb) + # The aic_load_fw module uploads the Bluetooth firmware, then btusb handles the BT interface + print_info "Loading standard Bluetooth driver (btusb)..." + if modprobe btusb >> "$LOG_FILE" 2>&1; then + print_success "Bluetooth driver (btusb) loaded successfully." + else + print_warning "Could not load btusb driver automatically." + print_info "You can manually load it with: sudo modprobe btusb" + fi } ############################################################################# @@ -481,8 +499,16 @@ verify_installation() { lsmod | grep aic || echo " (none)" # Check firmware - if [ -d "/lib/firmware/aic8800D80" ]; then - print_success "Firmware installed in /lib/firmware/aic8800D80" + local fw_count=0 + for fw_dir in /lib/firmware/aic8800*; do + if [ -d "$fw_dir" ]; then + ((fw_count++)) + fi + done + if [ $fw_count -gt 0 ]; then + print_success "Firmware installed for $fw_count chip variant(s) in /lib/firmware/" + else + print_warning "No firmware found in /lib/firmware/" fi # Check for wireless interfaces @@ -562,7 +588,7 @@ show_final_instructions() { 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 " ${BLUE}sudo rm -rf /lib/firmware/aic8800*${NC}" echo "" }