feat: update to SDK v5.0 with comprehensive kernel and device support

Major updates:
- Add Linux kernel 6.12-6.19 compatibility support
- Add Linux 6.16 timer_container_of and wakelock API support
- Add Debian 6.1.0-26 backport support
- Fix Bluetooth firmware upload for chip_mcu_id == 1 (cache_mem_addr)
- Add USB device ID 368b:8d81 support
- Add AIC8800DW device support
- Add TP-Link Archer TX1U Nano support (USB_VENDOR_ID_TENDA_V2:0x0110)
- Add TENDA series device support (U2, U11, U11 PRO)
- Add AIC8800FC_CUS4/5/6 series support
- Add AIC8800M80_CUS7/8 series support
- Add UGREEN AIC8800D80 adapter support
- Fix CONFIG_USB_BT interface number check (allow 1 or 3 interfaces)
- Update firmware files for all chip variants

Device support:
- AIC8800D80/D81/DC/DW series
- AIC8800D80X2/D81X2/D89X2 series
- AIC8800D80N/D80LN/D80WN/DLN/DWN series
- TENDA U2/U11/U11 PRO/TX1U Nano adapters
- Multiple OEM variants (FC_CUS1-6, M80_CUS1-8)

Kernel compatibility:
- Linux 3.10 - 6.19+
- Debian 6.1.0-26 with backported APIs
- Ubuntu and other distributions

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Shen Mintao
2026-03-11 10:10:30 +08:00
co-authored by Claude Sonnet 4.5
parent b0787d9989
commit 165a346c4d
128 changed files with 5659 additions and 2544 deletions
-1
View File
@@ -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
+4 -9
View File
@@ -1,16 +1,14 @@
CONFIG_AIC_LOADFW_SUPPORT := m
CONFIG_AIC8800_WLAN_SUPPORT := m
CONFIG_AIC8800_BTUSB_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/
obj-$(CONFIG_AIC8800_BTUSB_SUPPORT) += aic_btusb/
########## config option ##########
export CONFIG_USE_FW_REQUEST = n
export CONFIG_PREALLOC_RX_SKB = y
export CONFIG_PREALLOC_TXQ = y
export CONFIG_AIC8800_BTUSB_SUPPORT
export CONFIG_WOWLAN = n
###################################
########## platform support list ##########
@@ -49,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)
@@ -70,17 +68,14 @@ install:
mkdir -p $(MODDESTDIR)
install -p -m 644 aic_load_fw/aic_load_fw.ko $(MODDESTDIR)/
install -p -m 644 aic8800_fdrv/aic8800_fdrv.ko $(MODDESTDIR)/
install -p -m 644 aic_btusb/aic_btusb.ko $(MODDESTDIR)/
/sbin/depmod -a ${KVER}
uninstall:
rm -rfv $(MODDESTDIR)/aic_load_fw.ko
rm -rfv $(MODDESTDIR)/aic8800_fdrv.ko
rm -rfv $(MODDESTDIR)/aic_btusb.ko
/sbin/depmod -a ${KVER}
clean:
cd aic_load_fw/;make clean;cd ..
cd aic8800_fdrv/;make clean;cd ..
cd aic_btusb/;make clean;cd ..
rm -rf modules.order Module.symvers .modules.order.cmd .Module.symvers.cmd .tmp_versions/
+17 -6
View File
@@ -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
+59 -19
View File
@@ -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 <linux/version.h>
#ifdef __KERNEL__
#include <linux/if_arp.h>
#include <net/ip.h>
#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 15, 0)
#include <net/ipx.h>
#endif
#include <linux/atalk.h>
#include <linux/udp.h>
#include <linux/if_pppox.h>
@@ -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");
+13 -9
View File
@@ -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_
+143 -20
View File
@@ -11,8 +11,6 @@
*/
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/vmalloc.h>
#include <linux/ctype.h>
#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,
"<func> <freq> <tx_pwr> = 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,
"<val> = txpwr will change ,val can be negative" },
{ "set_ant", aic_priv_cmd_set_ant_mode,
"<val> = 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);
}
@@ -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_ */
@@ -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) {
@@ -2,6 +2,7 @@
#define _AIC_VENDOR_H
#include <linux/types.h>
#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 */
@@ -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;
}
@@ -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);
@@ -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
@@ -0,0 +1,32 @@
#include <linux/types.h>
#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);
@@ -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);
+287 -194
View File
@@ -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);
@@ -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);
@@ -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
@@ -0,0 +1,17 @@
#include <linux/types.h>
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);
+1 -5
View File
@@ -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
+4 -4
View File
@@ -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) {
+2 -9
View File
@@ -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);
@@ -8,6 +8,7 @@
#include <linux/moduleparam.h>
#include <net/tcp.h>
#include <linux/timer.h>
#include <linux/version.h>
#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
+3 -2
View File
@@ -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
+51 -34
View File
@@ -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)},
+14 -4
View File
@@ -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);
@@ -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;
@@ -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);
+57 -33
View File
@@ -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_
File diff suppressed because it is too large Load Diff
+24 -22
View File
@@ -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);
}
+1
View File
@@ -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_ */
+2 -1
View File
@@ -41,7 +41,7 @@
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK
#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) \
+4 -5
View File
@@ -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;
@@ -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_ */
+33 -11
View File
@@ -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);
+2
View File
@@ -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_ */
+1 -1
View File
@@ -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
*
+367 -70
View File
@@ -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,24 @@ 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
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 +5266,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 +6427,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 +6492,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 +6532,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 +8528,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 +8687,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 +8700,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 +8763,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 +8791,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 +8903,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 +8958,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 +8967,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 +8986,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 +9129,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 +9150,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 +9242,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 +9336,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)) {
+60 -2
View File
@@ -37,6 +37,21 @@ extern u8 chip_mcu_id;
#define PWR_LOSS_LVL3 (0)//(2) //RSSI <RSSI_THD_2
#define PWR_DELAY_TIME (10 * 1000) //pwr reduced latency time (ms)
#define PWR_FAST_SWITCH_PROTECT_TIME (2 * 1000) //quickly switch protection time (ms)
#define RSSI_HYSTERESIS_OFFSET 2 //buffer zone (dB)
#define RSSI_HYSTERESIS_THRESHOLD 2 //range of signal variation (dB)
#ifdef CONFIG_TEMP_CONTROL
#define TEMP_GET_INTERVAL (10 * 1000) //time interval
#define TEMP_THD_0 (110) //℃
#define TEMP_THD_1 (95) //℃
#define TEMP_THD_2 (85) //℃
#define TC_LOSS_LVL0 (-10) //TEMP >= 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_ */
+27 -18
View File
@@ -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
}
@@ -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_ */
+95 -15
View File
@@ -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;
+212 -79
View File
@@ -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
+8 -6
View File
@@ -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_ */
+1
View File
@@ -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
+268 -9
View File
@@ -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 <linux/firmware.h>
#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;
+19 -1
View File
@@ -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_ */
+45 -49
View File
@@ -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;
}
/* */
+31
View File
@@ -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 <linux/workqueue.h>
#include <linux/spinlock.h>
@@ -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
+133 -29
View File
@@ -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;
+14
View File
@@ -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,
+5 -5
View File
@@ -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
+4 -1
View File
@@ -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_ */
+1
View File
@@ -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_ */
@@ -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_ */
@@ -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"
+1
View File
@@ -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
+4 -8
View File
@@ -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)
File diff suppressed because it is too large Load Diff
+68 -52
View File
@@ -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 <linux/usb/audio.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#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
@@ -0,0 +1,130 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <linux/usb.h>
#include <linux/poll.h>
#include <linux/cdev.h>
#include <linux/device.h>
#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");
@@ -0,0 +1,3 @@
void btchr_external_write(char* data, int len);
+16 -9
View File
@@ -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
@@ -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;
}
@@ -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;
}
@@ -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);
+1 -1
View File
@@ -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
+154 -40
View File
@@ -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)
@@ -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);
@@ -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,
@@ -1,5 +1,6 @@
#include <linux/slab.h>
#include "aicwf_debug.h"
#include "aicwf_txq_prealloc.h"
struct prealloc_txq{
int prealloced;
@@ -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
+12 -7
View File
@@ -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 */
{}
};
+4 -1
View File
@@ -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_ */
@@ -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"