drivers: aic8800: upgrade to 20231212

This commit is contained in:
Lu Hui
2023-12-25 11:07:25 +08:00
committed by Han Gao/Revy/Rabenda
parent b8c5d35460
commit 1fd93bc1a9
51 changed files with 3178 additions and 512 deletions

View File

@@ -2,11 +2,13 @@ obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) += aic8800_btlpm/
obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/
obj-$(CONFIG_AIC_WLAN_SUPPORT) += aic8800_bsp/
# Platform support list
CONFIG_PLATFORM_ROCKCHIP ?= n
CONFIG_PLATFORM_ALLWINNER ?= n
CONFIG_PLATFORM_AMLOGIC ?= n
CONFIG_PLATFORM_UBUNTU ?= y
CONFIG_PLATFORM_ROCKCHIP = n
CONFIG_PLATFORM_ROCKCHIP2 = n
CONFIG_PLATFORM_ALLWINNER = n
CONFIG_PLATFORM_AMLOGIC = n
CONFIG_PLATFORM_UBUNTU = y
ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
#KDIR = /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/kernel
@@ -22,6 +24,15 @@ ccflags-y += -DANDROID_PLATFORM
ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP
endif
ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
ARCH = arm64
KDIR = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
CROSS_COMPILE = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
ccflags-y += -DANDROID_PLATFORM
ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP2
endif
ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
KDIR = /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/kernel/linux-4.9
ARCH = arm64

View File

@@ -0,0 +1,10 @@
*.o
*.ko
*.order
*.symvers
*.o.d
*.o.cmd
*.ko.cmd
*.mod
*.mod.c
*.mod.cmd

View File

@@ -12,6 +12,8 @@ ccflags-$(CONFIG_SDIO_PWRCTRL) += -DCONFIG_SDIO_PWRCTRL
endif
CONFIG_GPIO_WAKEUP = n
CONFIG_M2D_OTA_AUTO_SUPPORT = n
CONFIG_M2D_OTA_LZMA_SUPPORT = n
CONFIG_LINK_DET_5G = y
CONFIG_MCU_MESSAGE = n
CONFIG_FIRMWARE_ARRAY = n
@@ -22,10 +24,14 @@ CONFIG_VRF_DCDC_MODE = y
CONFIG_OOB = n
CONFIG_PREALLOC_TXQ = y
CONFIG_ONE_TXQ = n
CONFIG_DPD = n
CONFIG_FORCE_DPD_CALIB = n
CONFIG_DPD = y
CONFIG_FORCE_DPD_CALIB = y
CONFIG_RESV_MEM_SUPPORT = y
CONFIG_AMSDU_RX ?=n
ccflags-$(CONFIG_GPIO_WAKEUP) += -DCONFIG_GPIO_WAKEUP
ccflags-$(CONFIG_M2D_OTA_AUTO_SUPPORT) += -DCONFIG_M2D_OTA_AUTO_SUPPORT
ccflags-$(CONFIG_M2D_OTA_LZMA_SUPPORT) += -DCONFIG_M2D_OTA_LZMA_SUPPORT
ccflags-$(CONFIG_LINK_DET_5G) += -DCONFIG_LINK_DET_5G
ccflags-$(CONFIG_MCU_MESSAGE) += -DCONFIG_MCU_MESSAGE
ccflags-$(CONFIG_FIRMWARE_ARRAY) += -DCONFIG_FIRMWARE_ARRAY
@@ -37,6 +43,8 @@ ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ
ccflags-$(CONFIG_ONE_TXQ) += -DCONFIG_ONE_TXQ
ccflags-$(CONFIG_DPD) += -DCONFIG_DPD
ccflags-$(CONFIG_FORCE_DPD_CALIB) += -DCONFIG_FORCE_DPD_CALIB -DCONFIG_DPD
ccflags-$(CONFIG_RESV_MEM_SUPPORT) += -DCONFIG_RESV_MEM_SUPPORT
ccflags-$(CONFIG_AMSDU_RX) += -DCONFIG_AMSDU_RX
obj-m := $(MODULE_NAME).o
$(MODULE_NAME)-y := \
@@ -56,6 +64,7 @@ endif
# Platform support list
CONFIG_PLATFORM_ROCKCHIP ?= n
CONFIG_PLATFORM_ROCKCHIP2 ?= n
CONFIG_PLATFORM_ALLWINNER ?=n
CONFIG_PLATFORM_INGENIC_T20 ?= n
CONFIG_PLATFORM_AMLOGIC ?= n
@@ -88,6 +97,13 @@ ARCH ?= arm64
CROSS_COMPILE ?= /home/yaya/E/Rockchip/3566/Android11/rk3566_rk3568_android11_oranth/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
endif
ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2
ARCH ?= arm64
KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
CROSS_COMPILE ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
endif
ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
#KDIR ?= /home/yaya/E/Allwinner/A133/a133-sdk/android/longan/out/kernel/build/

View File

@@ -53,6 +53,12 @@ u32 patch_tbl_8800d80[][2] = {
#else
{0x00b4, 0xf3010000},
#endif
#if defined(CONFIG_AMSDU_RX)
{0x170, 0x0100000a}
#endif
#if AIC_IRQ_WAKE_FLAG
{0x00000170, 0x0000010a}, //irqf
#endif
};
#ifdef CONFIG_OOB
@@ -99,6 +105,7 @@ int aicwifi_patch_config_8800d80(struct aic_sdio_dev *sdiodev)
int adap_patch_cnt = 0;
if (adap_test) {
printk("%s for adaptivity test \r\n", __func__);
adap_patch_cnt = sizeof(adaptivity_patch_tbl_8800d80)/sizeof(u32)/2;
}

View File

@@ -1500,7 +1500,7 @@ uint32_t txgain_map[96] = {
0x00ffcc85,
0x00ffcd70,
0x00ffcd80,
0x00ffce70,
0x00ffcd90,
0x00ffce80,
0x00ffce93,
0x00ffcf90,
@@ -1523,6 +1523,108 @@ uint32_t txgain_map[96] = {
#endif
};
const uint32_t txgain_map_h[96] =
{
//11b
0xffd888, //11
0xffd979, //12
0xffd988, //13
0xffda79, //14
0xffda88, //15
0xffdb79, //16
0xffdb88, //17
0xffdc72, //18
0xffdc80, //19
0xffdd80, //20
0xffde66, //21
0xffde72, //22
0xffde80, //23
0xffdf79, //24
0xffdf88, //25
0xffdf98, //26
0xffd079, //-5
0xffd088, //-4
0xffd179, //-3
0xffd188, //-2
0xffd288, //-1
0xffd36c, //0
0xffd379, //1
0xffd388, //2
0xffd479, //3
0xffd488, //4
0xffd579, //5
0xffd588, //6
0xffd679, //7
0xffd688, //8
0xffd779, //9
0xffd879, //10
//high
0xffc879, //8
0xffc96b, //9
0xffc979, //10
0xffca6b, //11
0xffca79, //12
0xffcc56, //13
0xffcc60, //14
0xffcc6b, //15
0xffcc79, //16
0xffcd72, //17
0xffce60, //18
0xffce72, //19
0xffcf72, //20
0xffcf80, //21
0xffcf90, //22
0xffcf90, //23
0xffc079, //-8
0xffc16b, //-7
0xffc179, //-6
0xffc26b, //-5
0xffc279, //-4
0xffc36b, //-3
0xffc379, //-2
0xffc46b, //-1
0xffc479, //0
0xffc56b, //1
0xffc579, //2
0xffc66b, //3
0xffc679, //4
0xffc76b, //5
0xffc779, //6
0xffc86b, //7
//low
0xffc879, //8
0xffc96b, //9
0xffc979, //10
0xffca6b, //11
0xffca79, //12
0xffcc56, //13
0xffcc60, //14
0xffcc6b, //15
0xffcc79, //16
0xffcd72, //17
0xffce60, //18
0xffce72, //19
0xffcf72, //20
0xffcf80, //21
0xffcf90, //22
0xffcf90, //23
0xffc079, //-8
0xffc16b, //-7
0xffc179, //-6
0xffc26b, //-5
0xffc279, //-4
0xffc36b, //-3
0xffc379, //-2
0xffc46b, //-1
0xffc479, //0
0xffc56b, //1
0xffc579, //2
0xffc66b, //3
0xffc679, //4
0xffc76b, //5
0xffc779, //6
0xffc86b, //7
};
u32 jump_tbl[][2] =
@@ -1585,6 +1687,7 @@ u32 patch_tbl_rf_func[][2] =
{0x00110bf0, 0x00180001},
};
static u8 chip_id = 0;
#define CHIP_ID_H_MASK 0xC0
#define IS_CHIP_ID_H() ((chip_id & CHIP_ID_H_MASK) == CHIP_ID_H_MASK)
@@ -1594,7 +1697,6 @@ void system_config_8800dc(struct aic_sdio_dev *rwnx_hw)
array3_tbl_t p_syscfg_msk_tbl;
int ret, cnt;
const u32 mem_addr = 0x40500000;
u8 chip_id = 0;
struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
@@ -1716,7 +1818,7 @@ void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw)
u32 patch_tbl_wifisetting_num;// = sizeof(patch_tbl_wifisetting_8800dc_u02)/sizeof(u32)/2;
u32 ldpc_cfg_size = sizeof(ldpc_cfg_ram);
u32 agc_cfg_size = sizeof(agc_cfg_ram);
u32 txgain_cfg_size = sizeof(txgain_map);
u32 txgain_cfg_size, *txgain_cfg_array;
u32 jump_tbl_size = 0;
u32 patch_tbl_func_num = 0;
@@ -1731,7 +1833,7 @@ void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw)
patch_tbl_func_num = sizeof(patch_tbl_func)/sizeof(u32)/2;
patch_tbl_wifisetting_num = sizeof(patch_tbl_wifisetting_8800dc_u01)/sizeof(u32)/2;
patch_tbl_wifisetting_8800dc_base = patch_tbl_wifisetting_8800dc_u01;
} else if (chip_sub_id == 1) {
} else if ((chip_sub_id == 1) || (chip_sub_id == 2)) {
patch_tbl_wifisetting_num = sizeof(patch_tbl_wifisetting_8800dc_u02)/sizeof(u32)/2;
patch_tbl_wifisetting_8800dc_base = patch_tbl_wifisetting_8800dc_u02;
} else {
@@ -1812,29 +1914,42 @@ void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw)
}
#if !defined(CONFIG_FPGA_VERIFICATION)
ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, txgain_cfg_addr, txgain_cfg_size, txgain_map);
if ((IS_CHIP_ID_H())) {
txgain_cfg_size = sizeof(txgain_map_h);
txgain_cfg_array = (u32 *)txgain_map_h;
} else {
txgain_cfg_size = sizeof(txgain_map);
txgain_cfg_array = (u32 *)txgain_map;
}
ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, txgain_cfg_addr, txgain_cfg_size, txgain_cfg_array);
if (ret) {
AICWFDBG(LOGERROR, "txgain upload fail: %x, err:%d\r\n", txgain_cfg_addr, ret);
}
if(chip_sub_id == 0){
for (cnt = 0; cnt < jump_tbl_size/4; cnt+=1) {
AICWFDBG(LOGDEBUG, "%x = %x\n", jump_tbl_base[cnt][0]*4+jump_tbl_addr, jump_tbl_base[cnt][1]);
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, jump_tbl_base[cnt][0]*4+jump_tbl_addr, jump_tbl_base[cnt][1]))) {
AICWFDBG(LOGERROR, "%x write fail\n", jump_tbl_addr+8*cnt);
}
}
for (cnt = 0; cnt < patch_tbl_func_num; cnt++) {
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_func_base[cnt][0], patch_tbl_func_base[cnt][1]))) {
AICWFDBG(LOGERROR, "patch_tbl_func %x write fail\n", patch_tbl_func_base[cnt][0]);
}
}
}
else{
if (chip_sub_id == 0) {
for (cnt = 0; cnt < jump_tbl_size/4; cnt+=1) {
AICWFDBG(LOGDEBUG, "%x = %x\n", jump_tbl_base[cnt][0]*4+jump_tbl_addr, jump_tbl_base[cnt][1]);
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, jump_tbl_base[cnt][0]*4+jump_tbl_addr, jump_tbl_base[cnt][1]))) {
AICWFDBG(LOGERROR, "%x write fail\n", jump_tbl_addr+8*cnt);
}
}
for (cnt = 0; cnt < patch_tbl_func_num; cnt++) {
if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_func_base[cnt][0], patch_tbl_func_base[cnt][1]))) {
AICWFDBG(LOGERROR, "patch_tbl_func %x write fail\n", patch_tbl_func_base[cnt][0]);
}
}
} else if (chip_sub_id == 1) {
ret = aicwf_patch_table_load(rwnx_hw, RWNX_MAC_PATCH_TABLE_8800DC_U02);
if(ret){
printk("patch_tbl upload fail: err:%d\r\n", ret);
printk("patch_tbl upload fail: err:%d\r\n", ret);
}
} else if (chip_sub_id == 2) {
ret = aicwf_patch_table_load(rwnx_hw, RWNX_MAC_PATCH_TABLE_8800DC_H_U02);
if(ret){
printk("patch_tbl upload fail: err:%d\r\n", ret);
}
} else {
printk("unsupported id: %d\n", chip_sub_id);
}
#endif
@@ -1853,11 +1968,15 @@ void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw)
int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev)
{
int ret = 0;
const uint32_t cfg_base = 0x10164;
uint32_t cfg_base = 0x10164;
struct dbg_mem_read_cfm cfm;
uint32_t misc_ram_addr;
uint32_t misc_ram_size = 12;
int i;
if (testmode == FW_RFTEST_MODE) {
cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
}
// init misc ram
ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x14, &cfm);
if (ret) {
@@ -1877,13 +1996,23 @@ int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev)
}
#ifdef CONFIG_DPD
int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, uint32_t *dpd_res)
int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res)
{
int ret = 0;
uint32_t fw_addr, boot_type;
int valid_flag;
printk("%s\n", __func__);
ret = aicwf_misc_ram_valid_check_8800dc(sdiodev, &valid_flag);
if (ret) {
AICWFDBG(LOGINFO, "misc ram check fail: %d\n", ret);
return ret;
}
if (valid_flag) {
AICWFDBG(LOGINFO, "misc ram valid, skip calib process\n");
return ret;
}
ret = aicwf_plat_calib_load_8800dc(sdiodev);
if (ret) {
AICWFDBG(LOGINFO, "load calib bin fail: %d\n", ret);
@@ -1902,7 +2031,7 @@ int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, uint32_t *dpd_res)
const uint32_t cfg_base = 0x10164;
struct dbg_mem_read_cfm cfm;
uint32_t misc_ram_addr;
uint32_t misc_ram_size = DPD_RESULT_SIZE_8800DC;
uint32_t ram_base_addr, ram_word_cnt;
int i;
ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x14, &cfm);
if (ret) {
@@ -1910,50 +2039,137 @@ int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, uint32_t *dpd_res)
return ret;
}
misc_ram_addr = cfm.memdata;
for (i = 0; i < (misc_ram_size / 4); i++) {
ret = rwnx_send_dbg_mem_read_req(sdiodev, misc_ram_addr + i * 4, &cfm);
// 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(sdiodev, ram_base_addr + i * 4, &cfm);
if (ret) {
AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", misc_ram_addr + i * 4, ret);
AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret);
return ret;
}
dpd_res[i] = cfm.memdata;
dpd_res->bit_mask[i] = cfm.memdata;
}
// dpd_high
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high);
ram_word_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high) / 4;
for (i = 0; i < ram_word_cnt; i++) {
ret = rwnx_send_dbg_mem_read_req(sdiodev, 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;
}
dpd_res->dpd_high[i] = cfm.memdata;
}
// loft_res
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res);
ram_word_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res) / 4;
for (i = 0; i < ram_word_cnt; i++) {
ret = rwnx_send_dbg_mem_read_req(sdiodev, 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;
}
dpd_res->loft_res[i] = cfm.memdata;
}
}
return ret;
}
int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev)
int aicwf_dpd_result_apply_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res)
{
printk("%s\n", __func__);
int ret = 0;
uint32_t cfg_base = 0x10164;
struct dbg_mem_read_cfm cfm;
uint32_t misc_ram_addr;
if (testmode == 1) {
cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
}
uint32_t ram_base_addr, ram_byte_cnt;
AICWFDBG(LOGINFO, "bit_mask[1]=%x\n", dpd_res->bit_mask[1]);
if (dpd_res->bit_mask[1] == 0) {
AICWFDBG(LOGERROR, "void dpd_res, bypass it.\n");
return 0;
}
if (testmode == FW_RFTEST_MODE) {
cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
}
if ((ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x14, &cfm))) {
AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
return ret;
}
misc_ram_addr = cfm.memdata;
ret = rwnx_plat_bin_fw_upload_android(sdiodev, misc_ram_addr, FW_DPDRESULT_NAME_8800DC);
AICWFDBG(LOGINFO, "misc_ram_addr: %x\n", misc_ram_addr);
/* Copy dpd_res on the Embedded side */
// bit_mask
AICWFDBG(LOGINFO, "bit_mask[0]=%x\n", dpd_res->bit_mask[0]);
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask);
ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved);
ret = rwnx_send_dbg_mem_block_write_req(sdiodev, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->bit_mask[0]);
if (ret) {
AICWFDBG(LOGINFO, "load calib bin fail: %d\n", ret);
AICWFDBG(LOGERROR, "bit_mask wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
return ret;
}
// dpd_high
AICWFDBG(LOGINFO, "dpd_high[0]=%x\n", dpd_res->dpd_high[0]);
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high);
ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high);
ret = rwnx_send_dbg_mem_block_write_req(sdiodev, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->dpd_high[0]);
if (ret) {
AICWFDBG(LOGERROR, "dpd_high wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
return ret;
}
// loft_res
AICWFDBG(LOGINFO, "loft_res[0]=%x\n", dpd_res->loft_res[0]);
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res);
ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res);
ret = rwnx_send_dbg_mem_block_write_req(sdiodev, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->loft_res[0]);
if (ret) {
AICWFDBG(LOGERROR, "loft_res wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
return ret;
}
return ret;
}
#ifndef CONFIG_FORCE_DPD_CALIB
int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res)
{
int ret = 0;
int size;
u32 *dst=NULL;
char *filename = FW_DPDRESULT_NAME_8800DC;
struct device *dev = sdiodev->dev;
AICWFDBG(LOGINFO, "%s: dpd_res file path:%s \r\n", __func__, filename);
/* load file */
size = rwnx_load_firmware(&dst, filename, dev);
if (size <= 0) {
AICWFDBG(LOGERROR, "wrong size of dpd_res file\n");
if (dst) {
#ifndef CONFIG_FIRMWARE_ARRAY
vfree(dst);
#endif
dst = NULL;
}
return -1;
}
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d, dst[0]=%x\n", filename, size, dst[0]);
memcpy((u8 *)dpd_res, (u8 *)dst, sizeof(rf_misc_ram_lite_t));
if (dst) {
#ifndef CONFIG_FIRMWARE_ARRAY
vfree(dst);
#endif
dst = NULL;
}
return ret;
}
int aicwf_dpd_result_write_8800dc(void *buf, int buf_len)
{
printk("%s\n", __func__);
int sum = 0, len = 0;
char *path = NULL;
struct file *fp = NULL;
loff_t pos = 0;
mm_segment_t fs;
AICWFDBG(LOGINFO, "%s\n", __func__);
path = __getname();
if (!path) {
AICWFDBG(LOGINFO, "get path fail\n");
@@ -1988,6 +2204,7 @@ int aicwf_dpd_result_write_8800dc(void *buf, int buf_len)
return 0;
}
#endif /* !CONFIG_FORCE_DPD_CALIB */
#endif

View File

@@ -16,7 +16,6 @@ typedef uint64_t u64_l;
extern u8 chip_sub_id;
extern u8 chip_mcu_id;
#define DPD_RESULT_SIZE_8800DC 1880
#define FW_PATH_MAX_LEN 200
void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw);
@@ -24,9 +23,12 @@ void system_config_8800dc(struct aic_sdio_dev *rwnx_hw);
int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev);
#ifdef CONFIG_DPD
int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, uint32_t *dpd_res);
int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev);
int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res);
int aicwf_dpd_result_apply_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res);
#ifndef CONFIG_FORCE_DPD_CALIB
int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res);
int aicwf_dpd_result_write_8800dc(void *buf, int buf_len);
#endif/* !CONFIG_FORCE_DPD_CALIB */
#endif
#endif

View File

@@ -655,6 +655,239 @@ int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *device)
#endif
}
extern int testmode;
#ifdef CONFIG_M2D_OTA_AUTO_SUPPORT
extern char saved_sdk_ver[64];
int rwnx_plat_m2d_flash_ota_android(struct aic_sdio_dev *sdiodev, char *filename)
{
struct device *dev = sdiodev->dev;
unsigned int i=0;
int size;
u32 *dst=NULL;
int err=0;
int ret;
u8 bond_id;
const u32 mem_addr = 0x40500000;
struct dbg_mem_read_cfm rd_mem_addr_cfm;
ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm);
if (ret) {
printk("m2d %x rd fail: %d\n", mem_addr, ret);
return ret;
}
bond_id = (u8)(rd_mem_addr_cfm.memdata >> 24);
printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
if (bond_id & (1<<1)) {
//flash is invalid
printk("m2d flash is invalid\n");
return -1;
}
/* load aic firmware */
size = rwnx_load_firmware(&dst, filename, dev);
if(size<=0){
printk("wrong size of m2d file\n");
vfree(dst);
dst = NULL;
return -1;
}
/* Copy the file on the Embedded side */
printk("### Upload m2d %s flash, size=%d\n", filename, size);
/*send info first*/
err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_INFO_ADDR, 4, (u32 *)&size);
/*send data first*/
if (size > 1024) {// > 1KB data
for (i = 0; i < (size - 1024); i += 1024) {//each time write 1KB
err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, 1024, dst + i / 4);
if (err) {
printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err);
break;
}
}
}
if (!err && (i < size)) {// <1KB data
err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, size - i, dst + i / 4);
if (err) {
printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err);
}
}
if (dst) {
vfree(dst);
dst = NULL;
}
testmode = FW_NORMAL_MODE;
aicbsp_info.cpmode = testmode;
printk("m2d flash update complete\n\n");
return err;
}
int rwnx_plat_m2d_flash_ota_check(struct aic_sdio_dev *sdiodev, char *filename)
{
struct device *dev = sdiodev->dev;
unsigned int i=0,j=0;
int size;
u32 *dst=NULL;
int err=0;
int ret=0;
u8 bond_id;
const u32 mem_addr = 0x40500000;
const u32 mem_addr_code_start = AIC_M2D_OTA_CODE_START_ADDR;
const u32 mem_addr_sdk_ver = AIC_M2D_OTA_VER_ADDR;
const u32 driver_code_start_idx = (AIC_M2D_OTA_CODE_START_ADDR-AIC_M2D_OTA_FLASH_ADDR)/4;
const u32 driver_sdk_ver_idx = (AIC_M2D_OTA_VER_ADDR-AIC_M2D_OTA_FLASH_ADDR)/4;
u32 driver_sdk_ver_addr_idx = 0;
u32 code_start_addr = 0xffffffff;
u32 sdk_ver_addr = 0xffffffff;
u32 drv_code_start_addr = 0xffffffff;
u32 drv_sdk_ver_addr = 0xffffffff;
struct dbg_mem_read_cfm rd_mem_addr_cfm;
char m2d_sdk_ver[64];
char flash_sdk_ver[64];
u32 flash_ver[16];
u32 ota_ver[16];
ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm);
if (ret) {
printk("m2d %x rd fail: %d\n", mem_addr, ret);
return ret;
}
bond_id = (u8)(rd_mem_addr_cfm.memdata >> 24);
printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
if (bond_id & (1<<1)) {
//flash is invalid
printk("m2d flash is invalid\n");
return -1;
}
ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr_code_start, &rd_mem_addr_cfm);
if (ret){
printk("mem_addr_code_start %x rd fail: %d\n", mem_addr_code_start, ret);
return ret;
}
code_start_addr = rd_mem_addr_cfm.memdata;
#if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT)
ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr_sdk_ver, &rd_mem_addr_cfm);
if (ret){
printk("mem_addr_sdk_ver %x rd fail: %d\n", mem_addr_code_start, ret);
return ret;
}
sdk_ver_addr = rd_mem_addr_cfm.memdata;
#else
sdk_ver_addr = mem_addr_sdk_ver;
#endif
printk("code_start_addr: 0x%x, sdk_ver_addr: 0x%x\n", code_start_addr,sdk_ver_addr);
/* load aic firmware */
size = rwnx_load_firmware(&dst, filename, dev);
if(size<=0){
printk("wrong size of m2d file\n");
vfree(dst);
dst = NULL;
return -1;
}
if(code_start_addr == 0xffffffff && sdk_ver_addr == 0xffffffff) {
printk("########m2d flash old version , must be upgrade\n");
drv_code_start_addr = dst[driver_code_start_idx];
drv_sdk_ver_addr = dst[driver_sdk_ver_idx];
printk("drv_code_start_addr: 0x%x, drv_sdk_ver_addr: 0x%x\n", drv_code_start_addr,drv_sdk_ver_addr);
if(drv_sdk_ver_addr == 0xffffffff){
printk("########driver m2d_ota.bin is old ,not need upgrade\n");
return -1;
}
} else {
for(i=0;i<16;i++){
ret = rwnx_send_dbg_mem_read_req(sdiodev, (sdk_ver_addr+i*4), &rd_mem_addr_cfm);
if (ret){
printk("mem_addr_sdk_ver %x rd fail: %d\n", mem_addr_code_start, ret);
return ret;
}
flash_ver[i] = rd_mem_addr_cfm.memdata;
}
memcpy((u8 *)flash_sdk_ver,(u8 *)flash_ver,64);
memcpy((u8 *)saved_sdk_ver,(u8 *)flash_sdk_ver,64);
printk("flash SDK Version: %s\r\n\r\n", flash_sdk_ver);
drv_code_start_addr = dst[driver_code_start_idx];
drv_sdk_ver_addr = dst[driver_sdk_ver_idx];
printk("drv_code_start_addr: 0x%x, drv_sdk_ver_addr: 0x%x\n", drv_code_start_addr,drv_sdk_ver_addr);
if(drv_sdk_ver_addr == 0xffffffff){
printk("########driver m2d_ota.bin is old ,not need upgrade\n");
return -1;
}
#if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT)
driver_sdk_ver_addr_idx = (drv_sdk_ver_addr-drv_code_start_addr)/4;
#else
driver_sdk_ver_addr_idx = driver_sdk_ver_idx;
#endif
printk("driver_sdk_ver_addr_idx %d\n",driver_sdk_ver_addr_idx);
if (driver_sdk_ver_addr_idx){
for(j = 0; j < 16; j++){
ota_ver[j] = dst[driver_sdk_ver_addr_idx+j];
}
memcpy((u8 *)m2d_sdk_ver,(u8 *)ota_ver,64);
printk("m2d_ota SDK Version: %s\r\n\r\n", m2d_sdk_ver);
} else {
return -1;
}
if(!strcmp(m2d_sdk_ver,flash_sdk_ver)){
printk("######## m2d %s flash is not need upgrade\r\n", filename);
return -1;
}
}
/* Copy the file on the Embedded side */
printk("### Upload m2d %s flash, size=%d\n", filename, size);
/*send info first*/
err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_INFO_ADDR, 4, (u32 *)&size);
/*send data first*/
if (size > 1024) {// > 1KB data
for (i = 0; i < (size - 1024); i += 1024) {//each time write 1KB
err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, 1024, dst + i / 4);
if (err) {
printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err);
break;
}
}
}
if (!err && (i < size)) {// <1KB data
err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, size - i, dst + i / 4);
if (err) {
printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err);
}
}
if (dst) {
vfree(dst);
dst = NULL;
}
testmode = FW_NORMAL_MODE;
printk("m2d flash update complete\n\n");
return err;
}
#endif//CONFIG_M2D_OTA_AUTO_SUPPORT
int aicwf_patch_table_load(struct aic_sdio_dev *rwnx_hw, char *filename)
{
struct device *dev = rwnx_hw->dev;
@@ -720,7 +953,6 @@ int aicwf_patch_table_load(struct aic_sdio_dev *rwnx_hw, char *filename)
}
extern char aic_fw_path[200];
extern int testmode;
int aicwf_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev)
{
int ret = 0;
@@ -731,6 +963,9 @@ int aicwf_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev)
} else if (chip_sub_id == 1) {
printk("u02 is loaing ###############\n");
ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_8800DC_U02);
} else if (chip_sub_id == 2) {
printk("h_u02 is loaing ###############\n");
ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_8800DC_H_U02);
} else {
printk("unsupported id: %d\n", chip_sub_id);
}
@@ -750,6 +985,76 @@ int aicwf_plat_rftest_load_8800dc(struct aic_sdio_dev *sdiodev)
}
#ifdef CONFIG_DPD
int aicwf_misc_ram_valid_check_8800dc(struct aic_sdio_dev *sdiodev, int *valid_out)
{
int ret = 0;
uint32_t cfg_base = 0x10164;
struct dbg_mem_read_cfm cfm;
uint32_t misc_ram_addr;
uint32_t ram_base_addr, ram_word_cnt;
uint32_t bit_mask[4];
int i;
if (valid_out) {
*valid_out = 0;
}
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(sdiodev, 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(sdiodev, 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;
}
// init misc ram
ret = rwnx_send_dbg_mem_read_req(sdiodev, 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(sdiodev, 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;
}
}
return ret;
}
int aicwf_plat_calib_load_8800dc(struct aic_sdio_dev *sdiodev)
{
int ret = 0;
@@ -759,10 +1064,17 @@ int aicwf_plat_calib_load_8800dc(struct aic_sdio_dev *sdiodev)
AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret);
return ret;
}
} else if (chip_sub_id == 2) {
ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_CALIB_ADDR, RWNX_MAC_CALIB_NAME_8800DC_H_U02);
if (ret) {
AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret);
return ret;
}
}
return ret;
}
#ifndef CONFIG_FORCE_DPD_CALIB
int is_file_exist(char* name)
{
char *path = NULL;
@@ -792,6 +1104,12 @@ int is_file_exist(char* name)
EXPORT_SYMBOL(is_file_exist);
#endif
#endif
#ifdef CONFIG_DPD
rf_misc_ram_lite_t dpd_res = {{0},};
EXPORT_SYMBOL(dpd_res);
#endif
static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
{
@@ -816,7 +1134,7 @@ static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
return ret;
}
}
} else if (chip_sub_id == 1) {
} else if (chip_sub_id >= 1) {
if (testmode == FW_NORMAL_MODE) {
AICWFDBG(LOGINFO, "rwnx_plat_patch_loading\n");
ret = aicwf_plat_patch_load_8800dc(sdiodev);
@@ -827,39 +1145,41 @@ static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
#ifdef CONFIG_DPD
#ifdef CONFIG_FORCE_DPD_CALIB
if (1) {
uint32_t dpd_res[DPD_RESULT_SIZE_8800DC / 4] = {0,};
AICWFDBG(LOGINFO, "dpd calib & write\n");
ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res[0]);
ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res);
if (ret) {
AICWFDBG(LOGINFO, "dpd calib fail: %d\n", ret);
return ret;
}
ret = aicwf_dpd_result_write_8800dc((void *)dpd_res, DPD_RESULT_SIZE_8800DC);
if (ret) {
AICWFDBG(LOGINFO, "file write fail: %d\n", ret);
return ret;
}
}
#else
if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) {
AICWFDBG(LOGINFO, "dpd bin load\n");
ret = aicwf_dpd_result_load_8800dc(sdiodev);
ret = aicwf_dpd_result_load_8800dc(sdiodev, &dpd_res);
if (ret) {
AICWFDBG(LOGINFO, "load dpd bin fail: %d\n", ret);
return ret;
}
ret = aicwf_dpd_result_apply_8800dc(sdiodev, &dpd_res);
if (ret) {
AICWFDBG(LOGINFO, "apply dpd bin fail: %d\n", ret);
return ret;
}
}
#endif
else
#endif
{
aicwf_misc_ram_init_8800dc(sdiodev);
ret = aicwf_misc_ram_init_8800dc(sdiodev);
if (ret) {
AICWFDBG(LOGINFO, "misc ram init fail: %d\n", ret);
return ret;
}
}
} else if (testmode == FW_RFTEST_MODE) {
#ifdef CONFIG_DPD
#ifdef CONFIG_FORCE_DPD_CALIB
if (1) {
uint32_t dpd_res[DPD_RESULT_SIZE_8800DC / 4] = {0,};
AICWFDBG(LOGINFO, "patch load\n");
ret = aicwf_plat_patch_load_8800dc(sdiodev);
if (ret) {
@@ -867,16 +1187,11 @@ static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
return ret;
}
AICWFDBG(LOGINFO, "dpd calib & write\n");
ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res[0]);
ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res);
if (ret) {
AICWFDBG(LOGINFO, "dpd calib fail: %d\n", ret);
return ret;
}
ret = aicwf_dpd_result_write_8800dc((void *)dpd_res, DPD_RESULT_SIZE_8800DC);
if (ret) {
AICWFDBG(LOGINFO, "file write fail: %d\n", ret);
return ret;
}
}
#endif
#endif
@@ -886,9 +1201,8 @@ static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
return ret;
}
} else if (testmode == FW_DPDCALIB_MODE) {
#ifdef CONFIG_DPD
#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 0) {
uint32_t dpd_res[DPD_RESULT_SIZE_8800DC / 4] = {0,};
AICWFDBG(LOGINFO, "patch load\n");
ret = aicwf_plat_patch_load_8800dc(sdiodev);
if (ret) {
@@ -896,12 +1210,12 @@ static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
return ret;
}
AICWFDBG(LOGINFO, "dpd calib & write\n");
ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res[0]);
ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res);
if (ret) {
AICWFDBG(LOGINFO, "dpd calib fail: %d\n", ret);
return ret;
}
ret = aicwf_dpd_result_write_8800dc((void *)dpd_res, DPD_RESULT_SIZE_8800DC);
ret = aicwf_dpd_result_write_8800dc((void *)&dpd_res, DPD_RESULT_SIZE_8800DC);
if (ret) {
AICWFDBG(LOGINFO, "file write fail: %d\n", ret);
return ret;
@@ -1116,23 +1430,41 @@ int aicbt_patch_trap_data_load(struct aic_sdio_dev *sdiodev, struct aicbt_patch_
}
static struct aicbt_info_t aicbt_info = {
.btmode = AICBT_BTMODE_DEFAULT,
.btport = AICBT_BTPORT_DEFAULT,
.uart_baud = AICBT_UART_BAUD_DEFAULT,
.uart_flowctrl = AICBT_UART_FC_DEFAULT,
.lpm_enable = AICBT_LPM_ENABLE_DEFAULT,
.txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT,
static struct aicbt_info_t aicbt_info[]={
{
.btmode = AICBT_BTMODE_DEFAULT,
.btport = AICBT_BTPORT_DEFAULT,
.uart_baud = AICBT_UART_BAUD_DEFAULT,
.uart_flowctrl = AICBT_UART_FC_DEFAULT,
.lpm_enable = AICBT_LPM_ENABLE_DEFAULT,
.txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT,
},//PRODUCT_ID_AIC8801
{
.btmode = AICBT_BTMODE_BT_WIFI_COMBO,
.btport = AICBT_BTPORT_DEFAULT,
.uart_baud = AICBT_UART_BAUD_DEFAULT,
.uart_flowctrl = AICBT_UART_FC_DEFAULT,
.lpm_enable = AICBT_LPM_ENABLE_DEFAULT,
.txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT_8800dc,
},//PRODUCT_ID_AIC8800DC
{
.btmode = AICBT_BTMODE_BT_WIFI_COMBO,
.btport = AICBT_BTPORT_DEFAULT,
.uart_baud = AICBT_UART_BAUD_DEFAULT,
.uart_flowctrl = AICBT_UART_FC_DEFAULT,
.lpm_enable = AICBT_LPM_ENABLE_DEFAULT,
.txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT_8800dc,
},//PRODUCT_ID_AIC8800DW
{
.btmode = AICBT_BTMODE_DEFAULT_8800d80,
.btport = AICBT_BTPORT_DEFAULT,
.uart_baud = AICBT_UART_BAUD_DEFAULT,
.uart_flowctrl = AICBT_UART_FC_DEFAULT,
.lpm_enable = AICBT_LPM_ENABLE_DEFAULT,
.txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT_8800d80,
}//PRODUCT_ID_AIC8800D80
};
struct aicbt_info_t aicbt_info_8800dc = {
.btmode = AICBT_BTMODE_BT_WIFI_COMBO,
.btport = AICBT_BTPORT_DEFAULT,
.uart_baud = AICBT_UART_BAUD_DEFAULT,
.uart_flowctrl = AICBT_UART_FC_DEFAULT,
.lpm_enable = AICBT_LPM_ENABLE_DEFAULT,
.txpwr_lvl = AICBT_TXPWR_LVL_8800dc,
};
int aicbt_patch_table_load(struct aic_sdio_dev *sdiodev, struct aicbt_patch_table *head)
{
@@ -1142,87 +1474,44 @@ int aicbt_patch_table_load(struct aic_sdio_dev *sdiodev, struct aicbt_patch_tabl
if(head == NULL){
return -1;
}
if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800D80){
if (sdiodev->chipid == PRODUCT_ID_AIC8800D80) {
//aicbt_info.btmode = AICBT_BTMODE_BT_ONLY_COANT;
aicbt_info.txpwr_lvl = AICBT_TXPWR_LVL_8800d80;
}
for (p = head; p != NULL; p = p->next) {
data = p->data;
if (AICBT_PT_BTMODE == p->type) {
*(data + 1) = aicbsp_info.hwinfo < 0;
*(data + 3) = aicbsp_info.hwinfo;
*(data + 5) = 0;//aicbsp_info.cpmode;
*(data + 7) = aicbt_info.btmode;
*(data + 9) = aicbt_info.btport;
*(data + 11) = aicbt_info.uart_baud;
*(data + 13) = aicbt_info.uart_flowctrl;
*(data + 15) = aicbt_info.lpm_enable;
*(data + 17) = aicbt_info.txpwr_lvl;
for (p = head; p != NULL; p = p->next) {
data = p->data;
if (AICBT_PT_BTMODE == p->type) {
*(data + 1) = aicbsp_info.hwinfo < 0;
*(data + 3) = aicbsp_info.hwinfo;
*(data + 5) = (sdiodev->chipid == PRODUCT_ID_AIC8800DC?aicbsp_info.cpmode:0);//0;//aicbsp_info.cpmode;
printk("%s bt btmode:%d \r\n", __func__, aicbt_info.btmode);
printk("%s bt uart_baud:%d \r\n", __func__, aicbt_info.uart_baud);
printk("%s bt uart_flowctrl:%d \r\n", __func__, aicbt_info.uart_flowctrl);
printk("%s bt lpm_enable:%d \r\n", __func__, aicbt_info.lpm_enable);
printk("%s bt tx_pwr:%d \r\n", __func__, aicbt_info.txpwr_lvl);
}
*(data + 7) = aicbt_info[sdiodev->chipid].btmode;
*(data + 9) = aicbt_info[sdiodev->chipid].btport;
*(data + 11) = aicbt_info[sdiodev->chipid].uart_baud;
*(data + 13) = aicbt_info[sdiodev->chipid].uart_flowctrl;
*(data + 15) = aicbt_info[sdiodev->chipid].lpm_enable;
*(data + 17) = aicbt_info[sdiodev->chipid].txpwr_lvl;
if (AICBT_PT_VER == p->type) {
printk("aicbsp: bt patch version: %s\n", (char *)p->data);
continue;
}
printk("%s bt btmode[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].btmode);
printk("%s bt uart_baud[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].uart_baud);
printk("%s bt uart_flowctrl[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].uart_flowctrl);
printk("%s bt lpm_enable[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].lpm_enable);
printk("%s bt tx_pwr[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].txpwr_lvl);
}
for (i = 0; i < p->len; i++) {
ret = rwnx_send_dbg_mem_write_req(sdiodev, *data, *(data + 1));
if (ret != 0)
return ret;
data += 2;
}
if (p->type == AICBT_PT_PWRON)
udelay(500);
}
}
else if(sdiodev->chipid == PRODUCT_ID_AIC8800DC){
for (p = head; p != NULL; p = p->next) {
data = p->data;
if (AICBT_PT_BTMODE == p->type) {
*(data + 1) = aicbsp_info.hwinfo < 0;
*(data + 3) = aicbsp_info.hwinfo;
*(data + 5) = aicbsp_info.cpmode;
if (AICBT_PT_VER == p->type) {
printk("aicbsp: bt patch version: %s\n", (char *)p->data);
continue;
}
*(data + 7) = aicbt_info_8800dc.btmode;
*(data + 9) = aicbt_info_8800dc.btport;
*(data + 11) = aicbt_info_8800dc.uart_baud;
*(data + 13) = aicbt_info_8800dc.uart_flowctrl;
*(data + 15) = aicbt_info_8800dc.lpm_enable;
*(data + 17) = aicbt_info_8800dc.txpwr_lvl;
for (i = 0; i < p->len; i++) {
ret = rwnx_send_dbg_mem_write_req(sdiodev, *data, *(data + 1));
if (ret != 0)
return ret;
data += 2;
}
if (p->type == AICBT_PT_PWRON)
udelay(500);
}
printk("%s bt uart_baud:%d \r\n", __func__, aicbt_info_8800dc.uart_baud);
printk("%s bt uart_flowctrl:%d \r\n", __func__, aicbt_info_8800dc.uart_flowctrl);
printk("%s bt lpm_enable:%d \r\n", __func__, aicbt_info_8800dc.lpm_enable);
printk("%s bt tx_pwr:%d \r\n", __func__, aicbt_info_8800dc.txpwr_lvl);
}
if (AICBT_PT_INF == p->type) {
continue;
}
printk("########## p->type = %d \n",p->type);
printk("AICBT_PT_VER = %d \n",AICBT_PT_VER);
if (AICBT_PT_VER == p->type) {
printk("aicbsp: bt patch version: %s\n", (char *)p->data);
continue;
}
for (i = 0; i < p->len; i++) {
ret = rwnx_send_dbg_mem_write_req(sdiodev, *data, *(data + 1));
if (ret != 0)
return ret;
data += 2;
}
if (p->type == AICBT_PT_PWRON)
udelay(500);
}
}
///aicbt_patch_table_free(&head);
return 0;
}
@@ -1438,6 +1727,13 @@ int aicwifi_init(struct aic_sdio_dev *sdiodev)
{
int ret = 0;
if(sdiodev->chipid == PRODUCT_ID_AIC8801){
#ifdef CONFIG_M2D_OTA_AUTO_SUPPORT
if (testmode == FW_M2D_OTA_MODE) {
rwnx_plat_m2d_flash_ota_android(sdiodev, FW_M2D_OTA_NAME);
} else if (testmode == FW_NORMAL_MODE) {
rwnx_plat_m2d_flash_ota_check(sdiodev, FW_M2D_OTA_NAME);
}
#endif
if (rwnx_plat_bin_fw_upload_android(sdiodev, RAM_FMAC_FW_ADDR, aicbsp_firmware_list[aicbsp_info.cpmode].wl_fw)) {
printk("download wifi fw fail\n");
return -1;
@@ -1558,6 +1854,7 @@ int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev)
u32 mem_addr;
struct dbg_mem_read_cfm rd_mem_addr_cfm;
u32 btenable = 0;
u8 is_chip_id_h = 0;
int ret = 0;
mem_addr = 0x40500000;
@@ -1589,7 +1886,8 @@ int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev)
if (rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm))
return -1;
aicbsp_info.chip_rev = (u8)(rd_mem_addr_cfm.memdata >> 16);
aicbsp_info.chip_rev = (u8)((rd_mem_addr_cfm.memdata >> 16) & 0x3F);
is_chip_id_h = (u8)(((rd_mem_addr_cfm.memdata >> 16) & 0xC0) == 0xC0);
btenable = ((rd_mem_addr_cfm.memdata >> 26) & 0x1);
AICWFDBG(LOGINFO, "btenable = %d \n",btenable);
@@ -1606,10 +1904,15 @@ int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev)
pr_err("aicbsp: %s, unsupport chip rev: %d\n", __func__, aicbsp_info.chip_rev);
return -1;
}
if(aicbsp_info.chip_rev == CHIP_REV_U01){
aicbsp_firmware_list = fw_8800dc_u01;
}else{
aicbsp_firmware_list = fw_8800dc_u02;
if (is_chip_id_h) {
AICWFDBG(LOGINFO, "IS_CHIP_ID_H \n");
aicbsp_firmware_list = fw_8800dc_h_u02;
} else {
if(aicbsp_info.chip_rev == CHIP_REV_U01){
aicbsp_firmware_list = fw_8800dc_u01;
}else{
aicbsp_firmware_list = fw_8800dc_u02;
}
}
}
else if(sdiodev->chipid == PRODUCT_ID_AIC8800D80){
@@ -1658,6 +1961,7 @@ int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path)
feature->sdio_phase = FEATURE_SDIO_PHASE;
feature->hwinfo = aicbsp_info.hwinfo;
feature->fwlog_en = aicbsp_info.fwlog_en;
feature->irqf = aicbsp_info.irqf;
if(fw_path != NULL){
sprintf(fw_path,"%s", AICBSP_FW_PATH);
}
@@ -1666,7 +1970,7 @@ int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path)
}
EXPORT_SYMBOL_GPL(aicbsp_get_feature);
#if AICBSP_RESV_MEM_SUPPORT
#ifdef CONFIG_RESV_MEM_SUPPORT
static struct skb_buff_pool resv_skb[] = {
{AIC_RESV_MEM_TXDATA, 1536*64, "resv_mem_txdata", 0, NULL},
};

View File

@@ -236,6 +236,12 @@ enum dbg_msg_tag {
DBG_MAX,
};
#if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT)
#define FW_M2D_OTA_NAME "m2d_ota.bin"
#else
#define FW_M2D_OTA_NAME "m2d_ota_lzma.bin"
#endif
enum {
HOST_START_APP_AUTO = 1,
HOST_START_APP_CUSTOM,
@@ -305,6 +311,7 @@ struct dbg_start_app_cfm {
int aicwf_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev);
int aicwf_plat_rftest_load_8800dc(struct aic_sdio_dev *sdiodev);
#ifdef CONFIG_DPD
int aicwf_misc_ram_valid_check_8800dc(struct aic_sdio_dev *sdiodev, int *valid_out);
int aicwf_plat_calib_load_8800dc(struct aic_sdio_dev *sdiodev);
#endif
@@ -326,7 +333,7 @@ void rwnx_rx_handle_msg(struct aic_sdio_dev *sdiodev, struct ipc_e2a_msg *msg);
int aicbsp_platform_init(struct aic_sdio_dev *sdiodev);
void aicbsp_platform_deinit(struct aic_sdio_dev *sdiodev);
int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev);
#ifdef CONFIG_DPD
#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
int is_file_exist(char* name);
#endif
int aicbsp_resv_mem_init(void);
@@ -364,10 +371,13 @@ int aicbsp_resv_mem_deinit(void);
#define RWNX_MAC_CALIB_BASE_NAME_8800DC "fmacfw_calib_8800dc"
#define RWNX_MAC_CALIB_NAME_8800DC_U02 RWNX_MAC_CALIB_BASE_NAME_8800DC"_u02.bin"
#define RWNX_MAC_CALIB_NAME_8800DC_H_U02 RWNX_MAC_CALIB_BASE_NAME_8800DC"_h_u02.bin"
#ifdef CONFIG_DPD
#define ROM_FMAC_CALIB_ADDR 0x00130000
#define FW_DPDRESULT_NAME_8800DC "aic_dpdresult_8800dc.bin"
#ifndef CONFIG_FORCE_DPD_CALIB
#define FW_DPDRESULT_NAME_8800DC "aic_dpdresult_lite_8800dc.bin"
#endif
#endif
#define RWNX_MAC_FW_RF_BASE_NAME_8800DC "lmacfw_rf_8800dc.bin"
@@ -379,11 +389,13 @@ int aicbsp_resv_mem_deinit(void);
#define RWNX_MAC_PATCH_BASE_NAME_8800DC "fmacfw_patch_8800dc"
#define RWNX_MAC_PATCH_NAME2_8800DC RWNX_MAC_PATCH_BASE_NAME_8800DC".bin"
#define RWNX_MAC_PATCH_NAME2_8800DC_U02 RWNX_MAC_PATCH_BASE_NAME_8800DC"_u02.bin"
#define RWNX_MAC_PATCH_NAME2_8800DC_H_U02 RWNX_MAC_PATCH_BASE_NAME_8800DC"_h_u02.bin"
#endif
#define RWNX_MAC_PATCH_TABLE_NAME_8800DC "fmacfw_patch_tbl_8800dc"
#define RWNX_MAC_PATCH_TABLE_8800DC RWNX_MAC_PATCH_TABLE_NAME_8800DC ".bin"
#define RWNX_MAC_PATCH_TABLE_8800DC_U02 RWNX_MAC_PATCH_TABLE_NAME_8800DC "_u02.bin"
#define RWNX_MAC_PATCH_TABLE_8800DC_H_U02 RWNX_MAC_PATCH_TABLE_NAME_8800DC "_h_u02.bin"
#define RWNX_MAC_RF_PATCH_BASE_NAME_8800DC "fmacfw_rf_patch_8800dc"
#define RWNX_MAC_RF_PATCH_NAME_8800DC RWNX_MAC_RF_PATCH_BASE_NAME_8800DC".bin"
@@ -456,6 +468,18 @@ enum chip_rev {
CHIP_REV_U03 = 7,
CHIP_REV_U04 = 7,
};
#define AIC_M2D_OTA_INFO_ADDR 0x88000020
#define AIC_M2D_OTA_DATA_ADDR 0x88000040
#if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT)
#define AIC_M2D_OTA_FLASH_ADDR 0x08004000
#define AIC_M2D_OTA_CODE_START_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x0188)
#define AIC_M2D_OTA_VER_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x018C)
#else
#define AIC_M2D_OTA_FLASH_ADDR 0x08005000
#define AIC_M2D_OTA_CODE_START_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x1188)
#define AIC_M2D_OTA_VER_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x0010)
#endif
///aic bt tx pwr lvl :lsb->msb: first byte, min pwr lvl; second byte, max pwr lvl;
///pwr lvl:20(min), 30 , 40 , 50 , 60(max)
#define AICBT_TXPWR_LVL 0x00006020
@@ -466,13 +490,18 @@ enum chip_rev {
#define AICBSP_CPMODE_DEFAULT AICBSP_CPMODE_WORK
#define AICBSP_FWLOG_EN_DEFAULT 0
#define AICBT_BTMODE_DEFAULT AICBT_BTMODE_BT_ONLY_SW
#define AICBT_BTPORT_DEFAULT AICBT_BTPORT_UART
#define AICBT_UART_BAUD_DEFAULT AICBT_UART_BAUD_1_5M
#define AICBT_UART_FC_DEFAULT AICBT_UART_FLOWCTRL_ENABLE
#define AICBT_LPM_ENABLE_DEFAULT 0
#define AICBT_TXPWR_LVL_DEFAULT AICBT_TXPWR_LVL
#define AICBT_BTMODE_DEFAULT_8800d80 AICBT_BTMODE_BT_ONLY_COANT
#define AICBT_BTMODE_DEFAULT AICBT_BTMODE_BT_ONLY_SW
#define AICBT_BTPORT_DEFAULT AICBT_BTPORT_UART
#define AICBT_UART_BAUD_DEFAULT AICBT_UART_BAUD_1_5M
#define AICBT_UART_FC_DEFAULT AICBT_UART_FLOWCTRL_ENABLE
#define AICBT_LPM_ENABLE_DEFAULT 0
#define AICBT_TXPWR_LVL_DEFAULT AICBT_TXPWR_LVL
#define AICBT_TXPWR_LVL_DEFAULT_8800dc AICBT_TXPWR_LVL_8800dc
#define AICBT_TXPWR_LVL_DEFAULT_8800d80 AICBT_TXPWR_LVL_8800d80
#define AIC_IRQ_WAKE_FLAG 0 // 0: rising edge, 1: falling edge
#define FEATURE_SDIO_CLOCK 50000000 // 0: default, other: target clock rate
#define FEATURE_SDIO_CLOCK_V3 150000000 // 0: default, other: target clock rate
#define FEATURE_SDIO_PHASE 2 // 0: default, 2: 180°
@@ -520,6 +549,7 @@ struct aicbsp_info_t {
uint32_t cpmode;
uint32_t chip_rev;
bool fwlog_en;
uint8_t irqf;
};
extern struct aicbsp_info_t aicbsp_info;
@@ -529,6 +559,7 @@ extern const struct aicbsp_firmware fw_u02[];
extern const struct aicbsp_firmware fw_u03[];
extern const struct aicbsp_firmware fw_8800dc_u01[];
extern const struct aicbsp_firmware fw_8800dc_u02[];
extern const struct aicbsp_firmware fw_8800dc_h_u02[];
extern const struct aicbsp_firmware fw_8800d80_u01[];
extern const struct aicbsp_firmware fw_8800d80_u02[];

View File

@@ -1,8 +1,6 @@
#ifndef __AIC_BSP_EXPORT_H
#define __AIC_BSP_EXPORT_H
#define AICBSP_RESV_MEM_SUPPORT 0
enum aicbsp_subsys {
AIC_BLUETOOTH,
AIC_WIFI,
@@ -30,8 +28,35 @@ struct aicbsp_feature_t {
uint32_t sdio_clock;
uint8_t sdio_phase;
bool fwlog_en;
uint8_t irqf;
};
#ifdef CONFIG_DPD
typedef struct {
uint32_t bit_mask[3];
uint32_t reserved;
uint32_t dpd_high[96];
uint32_t dpd_11b[96];
uint32_t dpd_low[96];
uint32_t idac_11b[48];
uint32_t idac_high[48];
uint32_t idac_low[48];
uint32_t loft_res[18];
uint32_t rx_iqim_res[16];
} rf_misc_ram_t;
typedef struct {
uint32_t bit_mask[4];
uint32_t dpd_high[96];
uint32_t loft_res[18];
} rf_misc_ram_lite_t;
#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
#define DPD_RESULT_SIZE_8800DC sizeof(rf_misc_ram_lite_t)
extern rf_misc_ram_lite_t dpd_res;
#endif
int aicbsp_set_subsys(int, int);
int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path);
struct sk_buff *aicbsp_resv_mem_alloc_skb(unsigned int length, uint32_t id);

View File

@@ -99,6 +99,25 @@ const struct aicbsp_firmware fw_8800dc_u02[] = {
},
};
const struct aicbsp_firmware fw_8800dc_h_u02[] = {
[AICBSP_CPMODE_WORK] = {
.desc = "normal work mode(8800dc_h sdio u02)",
.bt_adid = "fw_adid_8800dc_u02h.bin",
.bt_patch = "fw_patch_8800dc_u02h.bin",
.bt_table = "fw_patch_table_8800dc_u02h.bin",
.wl_fw = "fmacfw_patch_8800dc_h_u02.bin"
},
[AICBSP_CPMODE_TEST] = {
.desc = "rf test mode(8800dc_h sdio u02)",
.bt_adid = "fw_adid_8800dc_u02h.bin",
.bt_patch = "fw_patch_8800dc_u02h.bin",
.bt_table = "fw_patch_table_8800dc_u02h.bin",
.wl_fw = "lmacfw_rf_8800dc.bin" //u01,u02 lmacfw load same bin
},
};
const struct aicbsp_firmware fw_8800d80_u01[] = {
[AICBSP_CPMODE_WORK] = {
.desc = "normal work mode(8800d80 sdio u01)",
@@ -140,6 +159,7 @@ struct aicbsp_info_t aicbsp_info = {
.hwinfo = AICBSP_HWINFO_DEFAULT,
.cpmode = AICBSP_CPMODE_DEFAULT,
.fwlog_en = AICBSP_FWLOG_EN_DEFAULT,
.irqf = AIC_IRQ_WAKE_FLAG,
};
struct mutex aicbsp_power_lock;

View File

@@ -23,6 +23,9 @@
#ifdef CONFIG_PLATFORM_ROCKCHIP
#include <linux/rfkill-wlan.h>
#endif /* CONFIG_PLATFORM_ROCKCHIP */
#ifdef CONFIG_PLATFORM_ROCKCHIP2
#include <linux/rfkill-wlan.h>
#endif /* CONFIG_PLATFORM_ROCKCHIP */
#ifdef CONFIG_PLATFORM_ALLWINNER
@@ -57,6 +60,10 @@ static const char* aic_default_fw_path = CONFIG_AIC_FW_PATH;
//#endif
char aic_fw_path[FW_PATH_MAX];
module_param_string(aic_fw_path, aic_fw_path, FW_PATH_MAX, 0660);
#ifdef CONFIG_M2D_OTA_AUTO_SUPPORT
char saved_sdk_ver[64];
module_param_string(saved_sdk_ver, saved_sdk_ver,64, 0660);
#endif
extern int testmode;
@@ -79,8 +86,8 @@ static int aicbsp_dummy_probe(struct sdio_func *func, const struct sdio_device_i
if (func && (func->num != 2))
return 0;
if(func->vendor != SDIO_VENDOR_ID_AIC8801 &&
func->device != SDIO_DEVICE_ID_AIC8801 &&
if(func->vendor != SDIO_VENDOR_ID_AIC8801 &&
func->device != SDIO_DEVICE_ID_AIC8801 &&
func->device != SDIO_DEVICE_ID_AIC8801_FUNC2 &&
func->vendor != SDIO_VENDOR_ID_AIC8800DC &&
func->device != SDIO_DEVICE_ID_AIC8800DC &&
@@ -137,6 +144,12 @@ void rfkill_rk_sleep_bt(bool sleep);
#endif
#endif
#ifdef CONFIG_PLATFORM_ROCKCHIP2
#if 1//FOR RK SUSPEND
void rfkill_rk_sleep_bt(bool sleep);
#endif
#endif
int aicbsp_set_subsys(int subsys, int state)
{
static int pre_power_map;
@@ -177,7 +190,15 @@ int aicbsp_set_subsys(int subsys, int state)
printk("%s BT wake default to SLEEP\r\n", __func__);
#endif
#endif
#ifdef CONFIG_PLATFORM_ROCKCHIP2
#ifdef CONFIG_GPIO_WAKEUP
//BT_SLEEP:true,BT_WAKEUP:false
rfkill_rk_sleep_bt(true);
printk("%s BT wake default to SLEEP\r\n", __func__);
#endif
#endif
//#ifndef CONFIG_PLATFORM_ROCKCHIP
// aicbsp_sdio_exit();
//#endif
@@ -210,7 +231,7 @@ err0:
EXPORT_SYMBOL_GPL(aicbsp_set_subsys);
bool aicbsp_get_load_fw_in_fdrv(void){
return aicbsp_load_fw_in_fdrv;
return aicbsp_load_fw_in_fdrv;
}
EXPORT_SYMBOL_GPL(aicbsp_get_load_fw_in_fdrv);
@@ -254,8 +275,8 @@ static int aicbsp_sdio_probe(struct sdio_func *func,
sdio_dbg("%s:%d vid:0x%04X did:0x%04X\n", __func__, func->num,
func->vendor, func->device);
if(func->vendor != SDIO_VENDOR_ID_AIC8801 &&
func->device != SDIO_DEVICE_ID_AIC8801 &&
if(func->vendor != SDIO_VENDOR_ID_AIC8801 &&
func->device != SDIO_DEVICE_ID_AIC8801 &&
func->device != SDIO_DEVICE_ID_AIC8801_FUNC2 &&
func->vendor != SDIO_VENDOR_ID_AIC8800DC &&
func->device != SDIO_DEVICE_ID_AIC8800DC &&
@@ -280,7 +301,7 @@ static int aicbsp_sdio_probe(struct sdio_func *func,
return -ENOMEM;
}
sdiodev = kzalloc(sizeof(struct aic_sdio_dev), GFP_KERNEL);
if (!sdiodev) {
sdio_err("alloc sdiodev fail\n");
@@ -343,7 +364,7 @@ static void aicbsp_sdio_remove(struct sdio_func *func)
}
bus_if = aicbsp_get_drvdata(&func->dev);
if (!bus_if) {
AICWFDBG(LOGERROR, "%s bus_if is NULL \r\n", __func__);
return;
@@ -374,12 +395,19 @@ static int aicbsp_sdio_suspend(struct device *dev)
struct sdio_func *func = dev_to_sdio_func(dev);
int err;
mmc_pm_flag_t sdio_flags;
#ifdef CONFIG_PLATFORM_ROCKCHIP
#ifdef CONFIG_GPIO_WAKEUP
//BT_SLEEP:true,BT_WAKEUP:false
rfkill_rk_sleep_bt(false);
#endif
#endif
#ifdef CONFIG_PLATFORM_ROCKCHIP2
#ifdef CONFIG_GPIO_WAKEUP
//BT_SLEEP:true,BT_WAKEUP:false
rfkill_rk_sleep_bt(false);
#endif
#endif
sdio_dbg("%s, func->num = %d\n", __func__, func->num);
@@ -407,6 +435,14 @@ static int aicbsp_sdio_suspend(struct device *dev)
#endif
#endif
#ifdef CONFIG_PLATFORM_ROCKCHIP2
#ifdef CONFIG_GPIO_WAKEUP
//BT_SLEEP:true,BT_WAKEUP:false
rfkill_rk_sleep_bt(true);
printk("%s BT wake to SLEEP\r\n", __func__);
#endif
#endif
return 0;
}
@@ -461,6 +497,13 @@ static int aicbsp_platform_power_on(void)
set_power_control_lock(1);
#endif
#ifdef CONFIG_PLATFORM_ROCKCHIP2
rockchip_wifi_power(0);
mdelay(50);
rockchip_wifi_power(1);
mdelay(50);
rockchip_wifi_set_carddetect(1);
#endif /*CONFIG_PLATFORM_ROCKCHIP2*/
sema_init(&aic_chipup_sem, 0);
ret = aicbsp_reg_sdio_notify(&aic_chipup_sem);
@@ -468,7 +511,7 @@ static int aicbsp_platform_power_on(void)
sdio_dbg("%s aicbsp_reg_sdio_notify fail(%d)\n", __func__, ret);
return ret;
}
#ifdef CONFIG_PLATFORM_ALLWINNER
sunxi_wlan_set_power(0);
mdelay(50);
@@ -477,12 +520,6 @@ static int aicbsp_platform_power_on(void)
sunxi_mmc_rescan_card(aicbsp_bus_index);
#endif //CONFIG_PLATFORM_ALLWINNER
#ifdef CONFIG_PLATFORM_ROCKCHIP
// rockchip_wifi_power(1);
// mdelay(200);
// rockchip_wifi_set_carddetect(1);
#endif /*CONFIG_PLATFORM_ROCKCHIP*/
if (down_timeout(&aic_chipup_sem, msecs_to_jiffies(2000)) == 0) {
aicbsp_unreg_sdio_notify();
if(aicbsp_load_fw_in_fdrv){
@@ -491,7 +528,7 @@ static int aicbsp_platform_power_on(void)
}
return 0;
}
aicbsp_unreg_sdio_notify();
#ifdef CONFIG_PLATFORM_ALLWINNER
sunxi_wlan_set_power(0);
@@ -502,9 +539,9 @@ static int aicbsp_platform_power_on(void)
#endif
#ifdef CONFIG_PLATFORM_ROCKCHIP
// rockchip_wifi_power(0);
#endif /*CONFIG_PLATFORM_ROCKCHIP*/
#ifdef CONFIG_PLATFORM_ROCKCHIP2
rockchip_wifi_power(0);
#endif /*CONFIG_PLATFORM_ROCKCHIP2*/
return -1;
}
@@ -524,11 +561,11 @@ static void aicbsp_platform_power_off(void)
sunxi_mmc_rescan_card(aicbsp_bus_index);
#endif //CONFIG_PLATFORM_ALLWINNER
#ifdef CONFIG_PLATFORM_ROCKCHIP
// rockchip_wifi_set_carddetect(0);
// mdelay(200);
// rockchip_wifi_power(0);
// mdelay(200);
#ifdef CONFIG_PLATFORM_ROCKCHIP2
rockchip_wifi_set_carddetect(0);
mdelay(200);
rockchip_wifi_power(0);
mdelay(200);
#endif /*CONFIG_PLATFORM_ROCKCHIP*/
#ifdef CONFIG_PLATFORM_AMLOGIC
extern_wifi_set_enable(0);
@@ -698,7 +735,7 @@ int aicwf_sdio_wakeup(struct aic_sdio_dev *sdiodev)
int ret = 0;
int read_retry;
int write_retry = 20;
int wakeup_reg_val;
int wakeup_reg_val = 0;
if (sdiodev->chipid == PRODUCT_ID_AIC8801 ||
sdiodev->chipid == PRODUCT_ID_AIC8800DC ||
@@ -1608,7 +1645,7 @@ void aicwf_sdio_reg_init(struct aic_sdio_dev *sdiodev)
{
sdio_dbg("%s\n", __func__);
if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC ||
if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC ||
sdiodev->chipid == PRODUCT_ID_AIC8800DW){
sdiodev->sdio_reg.bytemode_len_reg = SDIOWIFI_BYTEMODE_LEN_REG;
sdiodev->sdio_reg.intr_config_reg = SDIOWIFI_INTR_CONFIG_REG;
@@ -1900,7 +1937,7 @@ void get_fw_path(char* fw_path){
}else{
memcpy(fw_path, aic_default_fw_path, strlen(aic_default_fw_path));
}
}
}
int get_testmode(void){
return testmode;

View File

@@ -9,7 +9,7 @@ struct prealloc_txq{
};
struct prealloc_txq prealloc_txq;
#define MAX_TXQ_SIZE 30 * 1024
#define MAX_TXQ_SIZE 100 * 1024
void *aicwf_prealloc_txq_alloc(size_t size)
{

View File

@@ -1,4 +1,4 @@
#define RWNX_VERS_REV "241c091M (master)"
#define RWNX_VERS_MOD "6.4.3.0"
#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - - 241c091M (master)"
#define RELEASE_DATE "2023_0904_1726"
#define RELEASE_DATE "2023_1212_15dcf017"

View File

@@ -0,0 +1,10 @@
*.o
*.ko
*.order
*.symvers
*.o.d
*.o.cmd
*.ko.cmd
*.mod
*.mod.c
*.mod.cmd

View File

@@ -4,19 +4,29 @@ obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) := aic8800_btlpm.o
ccflags-y += -I$(srctree)/$(src)/../aic8800_bsp
aic8800_btlpm-y := \
aic_bluetooth_main.o \
rfkill.o \
lpm.o
# Platform support list
CONFIG_PLATFORM_ROCKCHIP ?= n
CONFIG_PLATFORM_ROCKCHIP2 ?= n
CONFIG_PLATFORM_ALLWINNER ?= n
CONFIG_PLATFORM_AMLOGIC ?= n
CONFIG_PLATFORM_UBUNTU ?= y
CONFIG_SUPPORT_LPM = y
CONFIG_AUTO_PM ?= n
aic8800_btlpm-y := \
aic_bluetooth_main.o \
rfkill.o \
ifeq ($(CONFIG_PLATFORM_UBUNTU), n)
aic8800_btlpm-$(CONFIG_SUPPORT_LPM) += lpm.o
endif
ccflags-y += -DAIC_TRACE_INCLUDE_PATH=$(src)
ccflags-$(CONFIG_AUTO_PM) += -DCONFIG_AUTO_PM
ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
KDIR ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/kernel
ARCH ?= arm
@@ -38,6 +48,14 @@ ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
ARCH = arm64
KDIR = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
CROSS_COMPILE = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
KDIR ?= /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/kernel/linux-4.9/

View File

@@ -44,6 +44,8 @@
#include <linux/wakelock.h>
#endif
#include "aic_bsp_export.h"
/*
* #define BT_SLEEP_DBG
*/
@@ -407,6 +409,24 @@ static ssize_t bluesleep_write_proc_btwrite(struct file *file,
return count;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
static const struct proc_ops lpm_fops = {
.proc_open = bluesleep_lpm_proc_open,
.proc_read = seq_read,
.proc_lseek = seq_lseek,
.proc_release = single_release,
.proc_write = bluesleep_write_proc_lpm,
};
static const struct proc_ops btwrite_fops = {
.proc_open = bluesleep_btwrite_proc_open,
.proc_read = seq_read,
.proc_lseek = seq_lseek,
.proc_release = single_release,
.proc_write = bluesleep_write_proc_btwrite,
};
#else
static const struct file_operations lpm_fops = {
.owner = THIS_MODULE,
.open = bluesleep_lpm_proc_open,
@@ -423,6 +443,8 @@ static const struct file_operations btwrite_fops = {
.release = single_release,
.write = bluesleep_write_proc_btwrite,
};
#endif
#else
/**
* Handles HCI device events.
@@ -773,6 +795,7 @@ static int __init bluesleep_probe(struct platform_device *pdev)
enum of_gpio_flags config;
int ret, uart_index;
u32 val;
struct aicbsp_feature_t bsp_feature_lpm;
bsi = devm_kzalloc(&pdev->dev, sizeof(struct bluesleep_info),
GFP_KERNEL);
@@ -787,7 +810,12 @@ static int __init bluesleep_probe(struct platform_device *pdev)
}
/* set host_wake_assert */
bsi->host_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 0 : 1;
aicbsp_get_feature(&bsp_feature_lpm);
if (bsp_feature_lpm.irqf == 0)
bsi->host_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 0 : 1;
else
bsi->host_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 1 : 0;
BT_DBG("bt_hostwake gpio=%d assert=%d\n", bsi->host_wake, bsi->host_wake_assert);
if (assert_level != -1) {
@@ -816,6 +844,7 @@ static int __init bluesleep_probe(struct platform_device *pdev)
#endif
BT_DBG("wakeup source is disabled!\n");
} else {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
ret = device_init_wakeup(dev, true);
if (ret < 0) {
BT_ERR("device init wakeup failed!\n");
@@ -828,6 +857,9 @@ static int __init bluesleep_probe(struct platform_device *pdev)
goto err2;
}
bsi->wakeup_enable = 1;
#else
BT_ERR("%s kernel unsupport this feature!\r\n", __func__);
#endif
}
bsi->ext_wake = of_get_named_gpio_flags(np, "bt_wake", 0, &config);
@@ -929,26 +961,52 @@ static int bluesleep_remove(struct platform_device *pdev)
#else
wake_lock_destroy(&bsi->wake_lock);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
if (bsi->wakeup_enable) {
BT_DBG("Deinit wakeup source");
device_init_wakeup(&pdev->dev, false);
dev_pm_clear_wake_irq(&pdev->dev);
}
#else
BT_ERR("%s kernel unsupport this feature!\r\n", __func__);
#endif
return 0;
}
#ifdef CONFIG_AUTO_PM
static int bluesleep_suspend(struct platform_device *pdev, pm_message_t state)
{
printk("%s\n", __func__);
bluesleep_tx_allow_sleep();
return 0;
}
static int bluesleep_resume(struct platform_device *pdev)
{
printk("%s\n", __func__);
bluesleep_outgoing_data();
return 0;
}
#endif
static const struct of_device_id sunxi_btlpm_ids[] = {
{ .compatible = "allwinner,sunxi-btlpm" },
{ /* Sentinel */ }
};
static struct platform_driver bluesleep_driver = {
.remove = bluesleep_remove,
.driver = {
.owner = THIS_MODULE,
.name = "sunxi-btlpm",
.of_match_table = sunxi_btlpm_ids,
.remove = bluesleep_remove,
#ifdef CONFIG_AUTO_PM
.suspend = bluesleep_suspend,
.resume = bluesleep_resume,
#endif
.driver = {
.owner = THIS_MODULE,
.name = "sunxi-btlpm",
.of_match_table = sunxi_btlpm_ids,
},
};

View File

@@ -5,7 +5,7 @@
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/platform_device.h>
//#include "lpm.h"
#include "lpm.h"
#include "rfkill.h"
#define DRV_CONFIG_FW_NAME "fw.bin"
@@ -47,7 +47,7 @@ static int __init aic_bluetooth_mod_init(void)
pr_err("rfkill init fail\n");
goto err1;
}
#if 0
#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2)
ret = bluesleep_init(aicbt_pdev);
if (ret) {
pr_err("bluesleep init fail\n");
@@ -57,7 +57,9 @@ static int __init aic_bluetooth_mod_init(void)
return 0;
//err2:
#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2)
err2:
#endif
rfkill_bluetooth_remove(aicbt_pdev);
err1:
platform_device_del(aicbt_pdev);
@@ -69,7 +71,9 @@ err0:
static void __exit aic_bluetooth_mod_exit(void)
{
printk("%s\n", __func__);
//bluesleep_exit(aicbt_pdev);
#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2)
bluesleep_exit(aicbt_pdev);
#endif
rfkill_bluetooth_remove(aicbt_pdev);
platform_device_del(aicbt_pdev);
platform_driver_unregister(&aicbt_driver);

View File

@@ -10,6 +10,7 @@ struct aicbsp_feature_t {
bool band_5g_support;
uint32_t sdio_clock;
uint8_t sdio_phase;
uint8_t irqf;
};
int aicbsp_set_subsys(int, int);

View File

@@ -146,7 +146,7 @@ static unsigned long flags;
static struct tasklet_struct hostwake_task;
/** Reception timer */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
static void bluesleep_rx_timer_expire(struct timer_list *t);
#else
static void bluesleep_rx_timer_expire(unsigned long data);
@@ -485,7 +485,7 @@ static void bluesleep_tx_allow_sleep(void)
* Clear BT_RXTIMER.
* @param data Not used.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
static void bluesleep_rx_timer_expire(struct timer_list *t)
#else
static void bluesleep_rx_timer_expire(unsigned long data)
@@ -896,7 +896,13 @@ static int bluesleep_probe(struct platform_device *pdev)
bluesleep_uart_dev = sw_uart_get_pdev(uart_index);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
bsi->ws = wakeup_source_register(dev, "bluesleep");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
bsi->ws = wakeup_source_register(dev, "bluesleep");
#else
bsi->ws = wakeup_source_register("bluesleep");
#endif
#else
wake_lock_init(&bsi->wake_lock, WAKE_LOCK_SUSPEND, "bluesleep");
#endif
@@ -1045,7 +1051,7 @@ int bluesleep_init(struct platform_device *pdev)
spin_lock_init(&rw_lock);
/* Initialize timer */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
timer_setup(&rx_timer, bluesleep_rx_timer_expire, 0);
#else
init_timer(&rx_timer);

View File

@@ -0,0 +1,10 @@
*.o
*.ko
*.order
*.symvers
*.o.d
*.o.cmd
*.ko.cmd
*.mod
*.mod.c
*.mod.cmd

View File

@@ -1,8 +1,15 @@
EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS)
EXTRA_CFLAGS += -Wno-implicit-fallthrough
#EXTRA_CFLAGS += -Wno-unused-function
#EXTRA_CFLAGS += -Wno-maybe-uninitialized
#EXTRA_CFLAGS += -Wno-unused-variable
RWNX_VERS_NUM := 6.4.3.0
CONFIG_COUNTRY_CODE = "00"
MODULE_NAME = aic8800_fdrv
CONFIG_AIC8800_WLAN_SUPPORT = m
# Support of bootrom start
CONFIG_START_FROM_BOOTROM = y
@@ -69,7 +76,7 @@ CONFIG_USB_BT =y
CONFIG_USE_5G ?= y
CONFIG_SDIO_PWRCTRL ?= y
CONFIG_CREATE_TRACE_POINTS = n
CONFIG_TXRX_THREAD_PRIO = n
CONFIG_TXRX_THREAD_PRIO = y
# CONFIG_COEX = n for BT_ONLY, CONFIG_COEX =y for combo and sw
CONFIG_COEX = y
CONFIG_RX_NETIF_RECV_SKB = y
@@ -87,12 +94,16 @@ CONFIG_USE_P2P0=n
CONFIG_BR_SUPPORT =n
BR_NAME = br0
CONFIG_FDRV_NO_REG_SDIO=n
CONFIG_SCHED_SCAN = y
CONFIG_SCHED_SCAN = n
CONFIG_OOB = n
CONFIG_USE_CUSTOMER_MAC = n
CONFIG_PREALLOC_TXQ = y
CONFIG_DPD = n
CONFIG_FORCE_DPD_CALIB = n
CONFIG_DPD = y
CONFIG_FORCE_DPD_CALIB = y
CONFIG_FILTER_TCP_ACK =n
CONFIG_RESV_MEM_SUPPORT = y
CONFIG_GKI = n
CONFIG_TEMP_COMP = n
# Support of MU-MIMO transmission (need FW support)
ifeq ($(CONFIG_RWNX_BFMER), y)
@@ -117,7 +128,6 @@ CONFIG_DEBUG_FS ?= n
obj-$(CONFIG_AIC8800_WLAN_SUPPORT) := $(MODULE_NAME).o
$(MODULE_NAME)-y := \
rwnx_gki.o \
rwnx_msg_tx.o \
rwnx_msg_rx.o \
rwnx_utils.o \
@@ -155,10 +165,14 @@ $(MODULE_NAME)-$(CONFIG_RWNX_MUMIMO_TX) += rwnx_mu_group.o
$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += sdio_host.o
$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += aicwf_txrxif.o
$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += aicwf_sdio.o
$(MODULE_NAME)-$(CONFIG_FILTER_TCP_ACK) += aicwf_tcp_ack.o
$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += usb_host.o
$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += aicwf_txrxif.o
$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += aicwf_usb.o
$(MODULE_NAME)-$(CONFIG_GKI) += rwnx_gki.o
ccflags-$(CONFIG_DEBUG_FS) += -DCONFIG_RWNX_DEBUGFS
ccflags-$(CONFIG_DEBUG_FS) += -DCONFIG_RWNX_UM_HELPER_DFLT=\"$(CONFIG_RWNX_UM_HELPER_DFLT)\"
@@ -231,6 +245,10 @@ ccflags-$(CONFIG_USE_CUSTOMER_MAC) += -DCONFIG_USE_CUSTOMER_MAC
ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ
ccflags-$(CONFIG_DPD) += -DCONFIG_DPD
ccflags-$(CONFIG_FORCE_DPD_CALIB) += -DCONFIG_FORCE_DPD_CALIB -DCONFIG_DPD
ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK
ccflags-$(CONFIG_RESV_MEM_SUPPORT) += -DCONFIG_RESV_MEM_SUPPORT
ccflags-$(CONFIG_GKI) += -DCONFIG_GKI
ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP
ifeq ($(CONFIG_SDIO_SUPPORT), y)
@@ -272,6 +290,7 @@ ccflags-$(CONFIG_RX_NETIF_RECV_SKB) += -DCONFIG_RX_NETIF_RECV_SKB
# Platform support list
CONFIG_PLATFORM_ROCKCHIP ?= n
CONFIG_PLATFORM_ROCKCHIP2 ?= n
CONFIG_PLATFORM_ALLWINNER ?= n
CONFIG_PLATFORM_INGENIC_T20 ?= n
CONFIG_PLATFORM_AMLOGIC ?= n
@@ -307,6 +326,16 @@ ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
ARCH := arm64
KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
CROSS_COMPILE := /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
ccflags-y += -DANDROID_PLATFORM

View File

@@ -1,8 +1,6 @@
#ifndef __AIC_BSP_EXPORT_H
#define __AIC_BSP_EXPORT_H
#define AICBSP_RESV_MEM_SUPPORT 0
enum aicbsp_subsys {
AIC_BLUETOOTH,
AIC_WIFI,
@@ -17,13 +15,40 @@ struct aicbsp_feature_t {
int hwinfo;
uint32_t sdio_clock;
uint8_t sdio_phase;
int fwlog_en;
int fwlog_en;
uint8_t irqf;
};
enum skb_buff_id {
AIC_RESV_MEM_TXDATA,
};
#ifdef CONFIG_DPD
typedef struct {
uint32_t bit_mask[3];
uint32_t reserved;
uint32_t dpd_high[96];
uint32_t dpd_11b[96];
uint32_t dpd_low[96];
uint32_t idac_11b[48];
uint32_t idac_high[48];
uint32_t idac_low[48];
uint32_t loft_res[18];
uint32_t rx_iqim_res[16];
} rf_misc_ram_t;
typedef struct {
uint32_t bit_mask[4];
uint32_t dpd_high[96];
uint32_t loft_res[18];
} rf_misc_ram_lite_t;
#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
#define DPD_RESULT_SIZE_8800DC sizeof(rf_misc_ram_lite_t)
extern rf_misc_ram_lite_t dpd_res;
#endif
int aicbsp_set_subsys(int, int);
int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path);
bool aicbsp_get_load_fw_in_fdrv(void);

View File

@@ -658,7 +658,7 @@ aicwf_cfg80211_subcmd_set_mac_policy[WIFI_VENDOR_ATTR_DRIVER_MAX + 1] = {
[0] = {.type = NLA_UNSPEC },
[WIFI_VENDOR_ATTR_DRIVER_MAC_ADDR] = { .type = NLA_MSECS, .len = ETH_ALEN },
};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
static int aicwf_dump_interface(struct wiphy *wiphy,
struct wireless_dev *wdev, struct sk_buff *skb,
const void *data, int data_len,
@@ -666,7 +666,9 @@ static int aicwf_dump_interface(struct wiphy *wiphy,
{
return 0;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
{
{
@@ -675,7 +677,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_start_mkeep_alive,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_mkeep_alive_policy,
.maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX
@@ -688,7 +692,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_stop_mkeep_alive,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_mkeep_alive_policy,
.maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX
@@ -701,7 +707,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_get_ver,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_logger_policy,
.maxattr = LOGGER_ATTRIBUTE_MAX
@@ -714,7 +722,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_subcmd_get_channel_list,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_subcmd_policy,
.maxattr = GSCAN_ATTRIBUTE_MAX
@@ -727,7 +737,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_subcmd_set_country_code,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_andr_wifi_policy,
.maxattr = ANDR_WIFI_ATTRIBUTE_MAX
@@ -740,7 +752,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_trigger_memory_dump,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
@@ -752,7 +766,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_subcmd_get_feature_set,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
@@ -764,7 +780,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_get_feature,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
@@ -776,7 +794,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_get_ring_status,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
@@ -788,7 +808,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_start_logging,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_logger_policy,
.maxattr = LOGGER_ATTRIBUTE_MAX
@@ -801,7 +823,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_get_ring_data,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_logger_policy,
.maxattr = LOGGER_ATTRIBUTE_MAX
@@ -814,7 +838,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_get_wake_reason_stats,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
@@ -826,7 +852,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_apf_subcmd_get_capabilities,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
@@ -838,7 +866,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = aicwf_vendor_sub_cmd_set_mac,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_subcmd_set_mac_policy,
.maxattr = WIFI_VENDOR_ATTR_DRIVER_MAX,
@@ -851,7 +881,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = aicwf_vendor_sub_cmd_set_mac,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_subcmd_set_mac_policy,
.maxattr = WIFI_VENDOR_ATTR_DRIVER_MAX,

View File

@@ -1,14 +1,12 @@
#include "rwnx_main.h"
#include "rwnx_msg_tx.h"
#include "reg_access.h"
#include "aic_bsp_export.h"
#define RWNX_MAC_RF_PATCH_BASE_NAME_8800DC "fmacfw_rf_patch_8800dc"
#define RWNX_MAC_RF_PATCH_NAME_8800DC RWNX_MAC_RF_PATCH_BASE_NAME_8800DC".bin"
#define FW_USERCONFIG_NAME_8800DC "aic_userconfig_8800dc.txt"
#define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt"
#ifdef CONFIG_DPD
#define FW_DPDRESULT_NAME_8800DC "aic_dpdresult_8800dc.bin"
#endif
int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
char *filename);
@@ -296,18 +294,25 @@ u32 wifi_rxgain_table_24g_40m_8800dcdw[64] = {
0x000000f0
};
#ifdef CONFIG_DPD
#define RAM_LMAC_FW_ADDR 0x00150000
#ifdef CONFIG_DPD
#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
extern int is_file_exist(char* name);
#endif
extern rf_misc_ram_lite_t dpd_res;
int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw)
int aicwf_fdrv_dpd_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res)
{
int ret = 0;
uint32_t cfg_base = 0x10164;
struct dbg_mem_read_cfm cfm;
uint32_t misc_ram_addr;
printk("%s\n", __func__);
uint32_t ram_base_addr, ram_byte_cnt;
AICWFDBG(LOGINFO, "bit_mask[1]=%x\n", dpd_res->bit_mask[1]);
if (dpd_res->bit_mask[1] == 0) {
AICWFDBG(LOGERROR, "void dpd_res, bypass it.\n");
return 0;
}
if (testmode == 1) {
cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
}
@@ -316,23 +321,75 @@ int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw)
return ret;
}
misc_ram_addr = cfm.memdata;
ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, misc_ram_addr, FW_DPDRESULT_NAME_8800DC);
AICWFDBG(LOGINFO, "misc_ram_addr: %x\n", misc_ram_addr);
/* Copy dpd_res on the Embedded side */
// bit_mask
AICWFDBG(LOGINFO, "bit_mask[0]=%x\n", dpd_res->bit_mask[0]);
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask);
ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved);
ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->bit_mask[0]);
if (ret) {
AICWFDBG(LOGINFO, "load calib bin fail: %d\n", ret);
AICWFDBG(LOGERROR, "bit_mask wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
return ret;
}
// dpd_high
AICWFDBG(LOGINFO, "dpd_high[0]=%x\n", dpd_res->dpd_high[0]);
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high);
ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high);
ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->dpd_high[0]);
if (ret) {
AICWFDBG(LOGERROR, "dpd_high wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
return ret;
}
// loft_res
AICWFDBG(LOGINFO, "loft_res[0]=%x\n", dpd_res->loft_res[0]);
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res);
ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res);
ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->loft_res[0]);
if (ret) {
AICWFDBG(LOGERROR, "loft_res wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
return ret;
}
return ret;
}
#ifndef CONFIG_FORCE_DPD_CALIB
int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res)
{
int ret = 0;
int size;
u32 *dst=NULL;
char *filename = FW_DPDRESULT_NAME_8800DC;
AICWFDBG(LOGINFO, "dpd_res 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 dpd_res file\n");
dst = NULL;
return -1;
}
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d, dst[0]=%x\n", filename, size, dst[0]);
memcpy((u8 *)dpd_res, (u8 *)dst, sizeof(rf_misc_ram_lite_t));
if (dst) {
rwnx_release_firmware_common(&dst);
}
return ret;
}
#endif
#endif
int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw)
{
int ret = 0;
const uint32_t cfg_base = 0x10164;
uint32_t cfg_base = 0x10164;
struct dbg_mem_read_cfm cfm;
uint32_t misc_ram_addr;
uint32_t misc_ram_size = 12;
int i;
if (testmode == 1) {
cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
}
// init misc ram
printk("%s\n", __func__);
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm);
@@ -390,26 +447,43 @@ int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_c
return -1;
}
} else if (testmode == 1) {
if (chip_sub_id == 1) {
if (chip_sub_id >= 1) {
#ifdef CONFIG_DPD
#ifndef CONFIG_FORCE_DPD_CALIB
if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) {
AICWFDBG(LOGINFO, "%s load dpd bin\n", __func__);
ret = aicwf_fdrv_dpd_result_load_8800dc(rwnx_hw);
ret = aicwf_fdrv_dpd_result_load_8800dc(rwnx_hw, &dpd_res);
if (ret) {
AICWFDBG(LOGINFO, "load dpd bin fail: %d\n", ret);
return ret;
}
}
#endif
if (dpd_res.bit_mask[1]) {
ret = aicwf_fdrv_dpd_result_apply_8800dc(rwnx_hw, &dpd_res);
if (ret) {
AICWFDBG(LOGINFO, "apply dpd bin fail: %d\n", ret);
return ret;
}
}
#else
{
ret = aicwf_fdrv_misc_ram_init_8800dc(rwnx_hw);
if (ret) {
AICWFDBG(LOGINFO, "misc ram init fail: %d\n", ret);
return ret;
}
}
#endif
ret = rwnx_send_rf_calib_req(rwnx_hw, cfm);
if (ret) {
AICWFDBG(LOGINFO, "rf calib req fail: %d\n", ret);
return ret;
}
}
}
}
return 0 ;
return 0 ;
}
int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw){

View File

@@ -1,7 +1,11 @@
#include <linux/types.h>
#include "aic_bsp_export.h"
#ifdef CONFIG_DPD
int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw);
int aicwf_fdrv_dpd_result_apply_8800dc(struct rwnx_hw * rwnx_hw, rf_misc_ram_lite_t * dpd_res);
#ifndef CONFIG_FORCE_DPD_CALIB
int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res);
#endif
#endif
int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw);
int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);

View File

@@ -34,6 +34,10 @@
#ifdef CONFIG_PLATFORM_ROCKCHIP
#include <linux/rfkill-wlan.h>
#endif
#ifdef CONFIG_PLATFORM_ROCKCHIP2
#include <linux/rfkill-wlan.h>
#endif
#include "aic_bsp_export.h"
extern uint8_t scanning;
@@ -327,7 +331,9 @@ static irqreturn_t rwnx_hostwake_irq_handler(int irq, void *para)
#if 0//old oob feature
complete(&g_rwnx_plat->sdiodev->bus_if->busrx_trgg);
#else//new oob feature
complete(&g_rwnx_plat->sdiodev->bus_if->busirq_trgg);
if(g_rwnx_plat->sdiodev->oob_enable){
complete(&g_rwnx_plat->sdiodev->bus_if->busirq_trgg);
}
#endif//old oob feature
#endif
@@ -344,9 +350,18 @@ static int rwnx_register_hostwake_irq(struct device *dev)
{
int ret = 0;//-1;
#ifdef CONFIG_GPIO_WAKEUP
unsigned long flag_edge;
struct aicbsp_feature_t aicwf_feature;
int irq_flags;
//TODO hostwake_irq_num hostwake_irq_num and wakeup_enable
aicbsp_get_feature(&aicwf_feature, NULL);
if (aicwf_feature.irqf == 0)
flag_edge = IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND;
else
flag_edge = IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND;
#ifdef CONFIG_PLATFORM_ALLWINNER
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
hostwake_irq_num = sunxi_wlan_get_oob_irq(&irq_flags, &wakeup_enable);
@@ -365,6 +380,14 @@ static int rwnx_register_hostwake_irq(struct device *dev)
printk("%s irq_flags:%d \r\n", __func__, irq_flags);
wakeup_enable = 1;
#endif //CONFIG_PLATFORM_ROCKCHIP
//For Rockchip
#ifdef CONFIG_PLATFORM_ROCKCHIP2
hostwake_irq_num = rockchip_wifi_get_oob_irq();
printk("%s hostwake_irq_num:%d \r\n", __func__, hostwake_irq_num);
irq_flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE) & IRQF_TRIGGER_MASK;
printk("%s irq_flags:%d \r\n", __func__, irq_flags);
wakeup_enable = 1;
#endif //CONFIG_PLATFORM_ROCKCHIP
@@ -391,9 +414,7 @@ static int rwnx_register_hostwake_irq(struct device *dev)
goto fail1;
}
ret = request_irq(hostwake_irq_num,
rwnx_hostwake_irq_handler, IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
"rwnx_hostwake_irq", NULL);
ret = request_irq(hostwake_irq_num, rwnx_hostwake_irq_handler, flag_edge, "rwnx_hostwake_irq", NULL);
if (ret < 0) {
pr_err("%s(%d): request_irq fail! ret = %d\n", __func__, __LINE__, ret);
@@ -535,16 +556,20 @@ static int aicwf_sdio_probe(struct sdio_func *func,
err = aicwf_sdio_chipmatch(sdiodev, func->vendor, func->device);
sdiodev->func = func;
sdiodev->bus_if = bus_if;
#ifdef CONFIG_OOB
if(sdiodev->chipid == PRODUCT_ID_AIC8801){
AICWFDBG(LOGERROR, "%s ERROR!!! 8801 not support OOB \r\n", __func__);
goto fail;
sdiodev->oob_enable = false;
}else{
sdiodev->oob_enable = true;
}
#endif //CONFIG_OOB
#else
sdiodev->oob_enable = false;
#endif
sdiodev->func = func;
sdiodev->bus_if = bus_if;
sdiodev->oob_enable = false;
atomic_set(&sdiodev->is_bus_suspend, 0);
bus_if->bus_priv.sdio = sdiodev;
@@ -578,20 +603,24 @@ static int aicwf_sdio_probe(struct sdio_func *func,
#ifdef CONFIG_GPIO_WAKEUP
#ifdef CONFIG_OOB
AICWFDBG(LOGINFO, "%s SDIOWIFI_INTR_CONFIG_REG Disable\n", __func__);
sdio_claim_host(sdiodev->func);
//disable sdio interrupt
err = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x0);
if (err < 0) {
sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG);
}
sdio_release_irq(sdiodev->func);
sdio_release_host(sdiodev->func);
if(sdiodev->oob_enable){
AICWFDBG(LOGINFO, "%s SDIOWIFI_INTR_CONFIG_REG Disable\n", __func__);
sdio_claim_host(sdiodev->func);
//disable sdio interrupt
err = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x0);
if (err < 0) {
sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG);
}
sdio_release_irq(sdiodev->func);
sdio_release_host(sdiodev->func);
#if 0
#if 0//old oob feature
sdiodev->oob_enable = true;
sdiodev->oob_enable = true;
#else//new oob feature
sdiodev->oob_enable = false;
sdiodev->oob_enable = true;
#endif//old oob feature
#endif
}
#endif
#ifdef CONFIG_WIFI_SUSPEND_FOR_LINUX
@@ -689,16 +718,20 @@ static int aicwf_sdio_suspend(struct device *dev)
#ifdef CONFIG_GPIO_WAKEUP
// rwnx_enable_hostwake_irq();
#endif
#if 0
sdio_dbg("%s SDIOWIFI_INTR_CONFIG_REG Disable\n", __func__);
sdio_claim_host(sdiodev->func);
//disable sdio interrupt
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x0);
if (ret < 0) {
sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG);
#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2)
if(sdiodev->chipid == PRODUCT_ID_AIC8801){
sdio_dbg("%s SDIOWIFI_INTR_CONFIG_REG Disable\n", __func__);
sdio_claim_host(sdiodev->func);
//disable sdio interrupt
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x0);
if (ret < 0) {
sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG);
}
sdio_release_irq(sdiodev->func);
sdio_release_host(sdiodev->func);
}
sdio_release_irq(sdiodev->func);
sdio_release_host(sdiodev->func);
#endif
atomic_set(&sdiodev->is_bus_suspend, 1);
// smp_mb();
@@ -713,7 +746,9 @@ static int aicwf_sdio_resume(struct device *dev)
struct aicwf_bus *bus_if = dev_get_drvdata(dev);
struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
struct rwnx_vif *rwnx_vif, *tmp;
//int ret;
#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2)
int ret;
#endif
sdio_dbg("%s enter \n", __func__);
//#ifdef CONFIG_GPIO_WAKEUP
@@ -736,16 +771,18 @@ static int aicwf_sdio_resume(struct device *dev)
// aicwf_sdio_hal_irqhandler(sdiodev->func);
#if 0
sdio_dbg("%s SDIOWIFI_INTR_CONFIG_REG Enable\n", __func__);
sdio_claim_host(sdiodev->func);
sdio_claim_irq(sdiodev->func, aicwf_sdio_hal_irqhandler);
#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2)
if(sdiodev->chipid == PRODUCT_ID_AIC8801){
sdio_dbg("%s SDIOWIFI_INTR_CONFIG_REG Enable\n", __func__);
sdio_claim_host(sdiodev->func);
sdio_claim_irq(sdiodev->func, aicwf_sdio_hal_irqhandler);
//enable sdio interrupt
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x07);
if (ret != 0)
sdio_err("intr register failed:%d\n", ret);
sdio_release_host(sdiodev->func);
//enable sdio interrupt
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x07);
if (ret != 0)
sdio_err("intr register failed:%d\n", ret);
sdio_release_host(sdiodev->func);
}
#endif
atomic_set(&sdiodev->is_bus_suspend, 0);
// smp_mb();
@@ -883,7 +920,7 @@ int aicwf_sdio_wakeup(struct aic_sdio_dev *sdiodev)
int ret = 0;
int read_retry;
int write_retry = 20;
int wakeup_reg_val;
int wakeup_reg_val = 0;
if (sdiodev->chipid == PRODUCT_ID_AIC8801 ||
sdiodev->chipid == PRODUCT_ID_AIC8800DC ||
@@ -1538,7 +1575,7 @@ static int aicwf_sdio_bus_start(struct device *dev)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
#include "uapi/linux/sched/types.h"
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0))
#include "linux/sched/types.h"
#else
#include "linux/sched/rt.h"
@@ -1755,7 +1792,7 @@ int sdio_busrx_thread(void *data)
cpumask_set_cpu(3, &cpumask);
sched_setaffinity(0, &cpumask);
#endif
#if 0
#ifdef CONFIG_THREAD_INFO_IN_TASK
int set_cpu_ret = 0;
@@ -1764,7 +1801,7 @@ int sdio_busrx_thread(void *data)
AICWFDBG(LOGINFO, "%s set_cpu_ret is:%d\n", __func__, set_cpu_ret);
AICWFDBG(LOGINFO, "%s change cpu to:%d\n", __func__, current->cpu);
#endif
#endif
#ifdef CONFIG_TXRX_THREAD_PRIO
if (busrx_thread_prio > 0) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
@@ -1943,8 +1980,7 @@ void aicwf_sdio_hal_irqhandler(struct sdio_func *func)
if (pkt)
aicwf_sdio_enq_rxpkt(sdiodev, pkt);
if(atomic_read(&sdiodev->rx_priv->rx_cnt) == 1 &&
sdiodev->oob_enable == false){
if(atomic_read(&sdiodev->rx_priv->rx_cnt) == 1){
complete(&bus_if->busrx_trgg);
}
@@ -2005,8 +2041,7 @@ void aicwf_sdio_hal_irqhandler(struct sdio_func *func)
if (pkt)
aicwf_sdio_enq_rxpkt(sdiodev, pkt);
if(atomic_read(&sdiodev->rx_priv->rx_cnt) == 1 &&
sdiodev->oob_enable == false){
if(atomic_read(&sdiodev->rx_priv->rx_cnt) == 1){
complete(&bus_if->busrx_trgg);
}
}
@@ -2046,22 +2081,24 @@ static struct aicwf_bus_ops aicwf_sdio_bus_ops = {
void aicwf_sdio_release(struct aic_sdio_dev *sdiodev)
{
struct aicwf_bus *bus_if;
#ifndef CONFIG_OOB
#ifdef CONFIG_OOB
int ret;
#endif
AICWFDBG(LOGINFO, "%s Enter\n", __func__);
bus_if = dev_get_drvdata(sdiodev->dev);
bus_if->state = BUS_DOWN_ST;
#ifndef CONFIG_OOB
sdio_claim_host(sdiodev->func);
//disable sdio interrupt
ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x0);
if (ret < 0) {
AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.intr_config_reg);
}
sdio_release_irq(sdiodev->func);
sdio_release_host(sdiodev->func);
#ifdef CONFIG_OOB
if(sdiodev->oob_enable){
sdio_claim_host(sdiodev->func);
//disable sdio interrupt
ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x0);
if (ret < 0) {
AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.intr_config_reg);
}
sdio_release_irq(sdiodev->func);
sdio_release_host(sdiodev->func);
}
#endif
if (sdiodev->dev)
aicwf_bus_deinit(sdiodev->dev);

View File

@@ -0,0 +1,633 @@
#include"aicwf_tcp_ack.h"
//#include"rwnx_tx.h"
//#include "aicwf_tcp_ack.h"
#include"rwnx_defs.h"
extern int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg);
struct msg_buf *intf_tcp_alloc_msg(struct msg_buf *msg)
{
//printk("%s \n",__func__);
int len=sizeof(struct msg_buf) ;
msg = kzalloc(len , GFP_KERNEL);
if(!msg)
printk("%s: alloc failed \n", __func__);
memset(msg,0,len);
return msg;
}
void intf_tcp_drop_msg(struct rwnx_hw *priv,
struct msg_buf *msg)
{
//printk("%s \n",__func__);
if (msg->skb)
dev_kfree_skb_any(msg->skb);
kfree(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
{
//printk("%s \n",__func__);
struct tcp_ack_info *ack_info;
struct msg_buf *msg;
struct tcp_ack_manage *ack_m = NULL;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
ack_info = (struct tcp_ack_info *)data;
#else
ack_info = container_of(t,struct tcp_ack_info,timer);
#endif
ack_m = container_of(ack_info, struct tcp_ack_manage,
ack_info[ack_info->ack_info_num]);
write_seqlock_bh(&ack_info->seqlock);
msg = ack_info->msgbuf;
if (ack_info->busy && msg && !ack_info->in_send_msg) {
ack_info->msgbuf = NULL;
ack_info->drop_cnt = 0;
ack_info->in_send_msg = msg;
write_sequnlock_bh(&ack_info->seqlock);
intf_tx(ack_m->priv, msg);//send skb
//ack_info->in_send_msg = NULL;//add by dwx
//write_sequnlock_bh(&ack_info->seqlock);
//intf_tx(ack_m->priv, msg);
return;
}
write_sequnlock_bh(&ack_info->seqlock);
}
void tcp_ack_init(struct rwnx_hw *priv)
{
int i;
struct tcp_ack_info *ack_info;
struct tcp_ack_manage *ack_m = &priv->ack_m;
printk("%s \n",__func__);
memset(ack_m, 0, sizeof(struct tcp_ack_manage));
ack_m->priv = priv;
spin_lock_init(&ack_m->lock);
atomic_set(&ack_m->max_drop_cnt, TCP_ACK_DROP_CNT);
ack_m->last_time = jiffies;
ack_m->timeout = msecs_to_jiffies(ACK_OLD_TIME);
for (i = 0; i < TCP_ACK_NUM; i++) {
ack_info = &ack_m->ack_info[i];
ack_info->ack_info_num = i;
seqlock_init(&ack_info->seqlock);
ack_info->last_time = jiffies;
ack_info->timeout = msecs_to_jiffies(ACK_OLD_TIME);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
setup_timer(&ack_info->timer, tcp_ack_timeout,
(unsigned long)ack_info);
#else
timer_setup(&ack_info->timer,tcp_ack_timeout,0);
#endif
}
atomic_set(&ack_m->enable, 1);
ack_m->ack_winsize = MIN_WIN;
}
void tcp_ack_deinit(struct rwnx_hw *priv)
{
int i;
struct tcp_ack_manage *ack_m = &priv->ack_m;
struct msg_buf *drop_msg = NULL;
printk("%s \n",__func__);
atomic_set(&ack_m->enable, 0);
for (i = 0; i < TCP_ACK_NUM; i++) {
drop_msg = NULL;
write_seqlock_bh(&ack_m->ack_info[i].seqlock);
del_timer(&ack_m->ack_info[i].timer);
drop_msg = ack_m->ack_info[i].msgbuf;
ack_m->ack_info[i].msgbuf = NULL;
write_sequnlock_bh(&ack_m->ack_info[i].seqlock);
if (drop_msg)
intf_tcp_drop_msg(priv, drop_msg);//drop skb
}
}
int tcp_check_quick_ack(unsigned char *buf,
struct tcp_ack_msg *msg)
{
int ip_hdr_len;
unsigned char *temp;
struct ethhdr *ethhdr;
struct iphdr *iphdr;
struct tcphdr *tcphdr;
ethhdr = (struct ethhdr *)buf;
if (ethhdr->h_proto != htons(ETH_P_IP))
return 0;
iphdr = (struct iphdr *)(ethhdr + 1);
if (iphdr->version != 4 || iphdr->protocol != IPPROTO_TCP)
return 0;
ip_hdr_len = iphdr->ihl * 4;
temp = (unsigned char *)(iphdr) + ip_hdr_len;
tcphdr = (struct tcphdr *)temp;
/* TCP_FLAG_ACK */
if (!(temp[13] & 0x10))
return 0;
if (temp[13] & 0x8) {
msg->saddr = iphdr->daddr;
msg->daddr = iphdr->saddr;
msg->source = tcphdr->dest;
msg->dest = tcphdr->source;
msg->seq = ntohl(tcphdr->seq);
return 1;
}
return 0;
}
int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len,
unsigned short *win_scale)
{
//printk("%s \n",__func__);
int drop = 1;
int len = tcphdr->doff * 4;
unsigned char *ptr;
if(tcp_tot_len > len) {
drop = 0;
} else {
len -= sizeof(struct tcphdr);
ptr = (unsigned char *)(tcphdr + 1);
while ((len > 0) && drop) {
int opcode = *ptr++;
int opsize;
switch (opcode) {
case TCPOPT_EOL:
break;
case TCPOPT_NOP:
len--;
continue;
default:
opsize = *ptr++;
if (opsize < 2)
break;
if (opsize > len)
break;
switch (opcode) {
/* TODO: Add other ignore opt */
case TCPOPT_TIMESTAMP:
break;
case TCPOPT_WINDOW:
if (*ptr < 15)
*win_scale = (1 << (*ptr));
printk("%d\n",*win_scale);
break;
default:
drop = 2;
}
ptr += opsize - 2;
len -= opsize;
}
}
}
return drop;
}
/* flag:0 for not tcp ack
* 1 for ack which can be drop
* 2 for other ack whith more info
*/
int tcp_check_ack(unsigned char *buf,
struct tcp_ack_msg *msg,
unsigned short *win_scale)
{
int ret;
int ip_hdr_len;
int tcp_tot_len;
unsigned char *temp;
struct ethhdr *ethhdr;
struct iphdr *iphdr;
struct tcphdr *tcphdr;
ethhdr =(struct ethhdr *)buf;
if (ethhdr->h_proto != htons(ETH_P_IP))
return 0;
iphdr = (struct iphdr *)(ethhdr + 1);
if (iphdr->version != 4 || iphdr->protocol != IPPROTO_TCP)
return 0;
ip_hdr_len = iphdr->ihl * 4;
temp = (unsigned char *)(iphdr) + ip_hdr_len;
tcphdr = (struct tcphdr *)temp;
/* TCP_FLAG_ACK */
if (!(temp[13] & 0x10))
return 0;
tcp_tot_len = ntohs(iphdr->tot_len) - ip_hdr_len;// tcp total len
ret = is_drop_tcp_ack(tcphdr, tcp_tot_len, win_scale);
//printk("is drop:%d \n",ret);
if (ret > 0) {
msg->saddr = iphdr->saddr;
msg->daddr = iphdr->daddr;
msg->source = tcphdr->source;
msg->dest = tcphdr->dest;
msg->seq = ntohl(tcphdr->ack_seq);
msg->win = ntohs(tcphdr->window);
}
return ret;
}
/* return val: -1 for not match, others for match */
int tcp_ack_match(struct tcp_ack_manage *ack_m,
struct tcp_ack_msg *ack_msg)
{
int i, ret = -1;
unsigned start;
struct tcp_ack_info *ack_info;
struct tcp_ack_msg *ack;
for (i = 0; ((ret < 0) && (i < TCP_ACK_NUM)); i++) {
ack_info = &ack_m->ack_info[i];
do {
start = read_seqbegin(&ack_info->seqlock);
ret = -1;
ack = &ack_info->ack_msg;
if (ack_info->busy &&
ack->dest == ack_msg->dest &&
ack->source == ack_msg->source &&
ack->saddr == ack_msg->saddr &&
ack->daddr == ack_msg->daddr)
ret = i;
} while(read_seqretry(&ack_info->seqlock, start));
}
return ret;
}
void tcp_ack_update(struct tcp_ack_manage *ack_m)
{
int i;
struct tcp_ack_info *ack_info;
if (time_after(jiffies, ack_m->last_time + ack_m->timeout)) {
spin_lock_bh(&ack_m->lock);
ack_m->last_time = jiffies;
for (i = TCP_ACK_NUM - 1; i >= 0; i--) {
ack_info = &ack_m->ack_info[i];
write_seqlock_bh(&ack_info->seqlock);
if (ack_info->busy &&
time_after(jiffies, ack_info->last_time +
ack_info->timeout)) {
ack_m->free_index = i;
ack_m->max_num--;
ack_info->busy = 0;
}
write_sequnlock_bh(&ack_info->seqlock);
}
spin_unlock_bh(&ack_m->lock);
}
}
/* return val: -1 for no index, others for index */
int tcp_ack_alloc_index(struct tcp_ack_manage *ack_m)
{
int i, ret = -1;
struct tcp_ack_info *ack_info;
unsigned start;
spin_lock_bh(&ack_m->lock);
if (ack_m->max_num == TCP_ACK_NUM) {
spin_unlock_bh(&ack_m->lock);
return -1;
}
if (ack_m->free_index >= 0) {
i = ack_m->free_index;
ack_m->free_index = -1;
ack_m->max_num++;
spin_unlock_bh(&ack_m->lock);
return i;
}
for (i = 0; ((ret < 0) && (i < TCP_ACK_NUM)); i++) {
ack_info = &ack_m->ack_info[i];
do {
start = read_seqbegin(&ack_info->seqlock);
ret = -1;
if (!ack_info->busy) {
ack_m->free_index = -1;
ack_m->max_num++;
ret = i;
}
} while(read_seqretry(&ack_info->seqlock, start));
}
spin_unlock_bh(&ack_m->lock);
return ret;
}
/* return val: 0 for not handle tx, 1 for handle tx */
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 quick_ack = 0;
struct tcp_ack_msg *ack;
int ret = 0;
struct msg_buf *drop_msg = NULL;
//printk("%s %d",__func__,type);
write_seqlock_bh(&ack_info->seqlock);
ack_info->last_time = jiffies;
ack = &ack_info->ack_msg;
if (type == 2) {
if (U32_BEFORE(ack->seq, ack_msg->seq)) {
ack->seq = ack_msg->seq;
if (ack_info->psh_flag &&
!U32_BEFORE(ack_msg->seq,
ack_info->psh_seq)) {
ack_info->psh_flag = 0;
}
if (ack_info->msgbuf) {
//printk("%lx \n",ack_info->msgbuf);
drop_msg = ack_info->msgbuf;
ack_info->msgbuf = NULL;
del_timer(&ack_info->timer);
}else{
//printk("msgbuf is NULL \n");
}
ack_info->in_send_msg = NULL;
ack_info->drop_cnt = atomic_read(&ack_m->max_drop_cnt);
} else {
printk("%s before abnormal ack: %d, %d\n",
__func__, ack->seq, ack_msg->seq);
drop_msg = new_msgbuf;
ret = 1;
}
} else if (U32_BEFORE(ack->seq, ack_msg->seq)) {
if (ack_info->msgbuf) {
drop_msg = ack_info->msgbuf;
ack_info->msgbuf = NULL;
}
if (ack_info->psh_flag &&
!U32_BEFORE(ack_msg->seq, ack_info->psh_seq)) {
ack_info->psh_flag = 0;
quick_ack = 1;
} else {
ack_info->drop_cnt++;
}
ack->seq = ack_msg->seq;
if (quick_ack || (!ack_info->in_send_msg &&
(ack_info->drop_cnt >=
atomic_read(&ack_m->max_drop_cnt)))) {
ack_info->drop_cnt = 0;
ack_info->in_send_msg = new_msgbuf;
del_timer(&ack_info->timer);
} else {
ret = 1;
ack_info->msgbuf = new_msgbuf;
if (!timer_pending(&ack_info->timer))
mod_timer(&ack_info->timer,
(jiffies + msecs_to_jiffies(5)));
}
} else {
printk("%s before ack: %d, %d\n",
__func__, ack->seq, ack_msg->seq);
drop_msg = new_msgbuf;
ret = 1;
}
write_sequnlock_bh(&ack_info->seqlock);
if (drop_msg)
intf_tcp_drop_msg(ack_m->priv, drop_msg);// drop skb
return ret;
}
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)
{
int quick_ack = 0;
struct tcp_ack_msg *ack;
int ret = 0;
struct msg_buf *drop_msg = NULL;
struct msg_buf * send_msg = NULL;
//printk("",);
write_seqlock_bh(&ack_info->seqlock);
ack_info->last_time = jiffies;
ack = &ack_info->ack_msg;
if(U32_BEFORE(ack->seq, ack_msg->seq)){
if (ack_info->msgbuf) {
drop_msg = ack_info->msgbuf;
ack_info->msgbuf = NULL;
//ack_info->drop_cnt++;
}
if (ack_info->psh_flag &&
!U32_BEFORE(ack_msg->seq, ack_info->psh_seq)) {
ack_info->psh_flag = 0;
quick_ack = 1;
} else {
ack_info->drop_cnt++;
}
ack->seq = ack_msg->seq;
if(quick_ack || (!ack_info->in_send_msg &&
(ack_info->drop_cnt >=
atomic_read(&ack_m->max_drop_cnt)))){
ack_info->drop_cnt = 0;
send_msg = new_msgbuf;
ack_info->in_send_msg = send_msg;
del_timer(&ack_info->timer);
}else{
ret = 1;
ack_info->msgbuf = new_msgbuf;
if (!timer_pending(&ack_info->timer))
mod_timer(&ack_info->timer,
(jiffies + msecs_to_jiffies(5)));
}
//ret = 1;
}else {
printk("%s before ack: %d, %d\n",
__func__, ack->seq, ack_msg->seq);
drop_msg = new_msgbuf;
ret = 1;
}
/*if(send_msg){
intf_tx(ack_m->priv,send_msg);
ack_info->in_send_msg=NULL;
}*/
//ack_info->in_send_msg=NULL;
write_sequnlock_bh(&ack_info->seqlock);
/*if(send_msg){
intf_tx(ack_m->priv,send_msg);
//ack_info->in_send_msg=NULL;
}*/
if (drop_msg)
intf_tcp_drop_msg(ack_m->priv, drop_msg);// drop skb
return ret;
}
void filter_rx_tcp_ack(struct rwnx_hw *priv,
unsigned char *buf, unsigned plen)
{
int index;
struct tcp_ack_msg ack_msg;
struct tcp_ack_info *ack_info;
struct tcp_ack_manage *ack_m = &priv->ack_m;
if (!atomic_read(&ack_m->enable))
return;
if ((plen > MAX_TCP_ACK) ||
!tcp_check_quick_ack(buf, &ack_msg))
return;
index = tcp_ack_match(ack_m, &ack_msg);
if (index >= 0) {
ack_info = ack_m->ack_info + index;
write_seqlock_bh(&ack_info->seqlock);
ack_info->psh_flag = 1;
ack_info->psh_seq = ack_msg.seq;
write_sequnlock_bh(&ack_info->seqlock);
}
}
/* return val: 0 for not filter, 1 for filter */
int filter_send_tcp_ack(struct rwnx_hw *priv,
struct msg_buf *msgbuf,
unsigned char *buf, unsigned int plen)
{
//printk("%s \n",__func__);
int ret = 0;
int index, drop;
unsigned short win_scale = 0;
unsigned int win = 0;
struct tcp_ack_msg ack_msg;
struct tcp_ack_msg *ack;
struct tcp_ack_info *ack_info;
struct tcp_ack_manage *ack_m = &priv->ack_m;
if (plen > MAX_TCP_ACK)
return 0;
tcp_ack_update(ack_m);
drop = tcp_check_ack(buf, &ack_msg, &win_scale);
//printk("drop:%d win_scale:%d",drop,win_scale);
if (!drop && (0 == win_scale))
return 0;
index = tcp_ack_match(ack_m, &ack_msg);
if (index >= 0) {
ack_info = ack_m->ack_info + index;
if ((0 != win_scale) &&
(ack_info->win_scale != win_scale)) {
write_seqlock_bh(&ack_info->seqlock);
ack_info->win_scale = win_scale;
write_sequnlock_bh(&ack_info->seqlock);
}
if (drop > 0 && atomic_read(&ack_m->enable)) {
win = ack_info->win_scale * ack_msg.win;
if ((win_scale!=0) && (win < (ack_m->ack_winsize * SIZE_KB)))
{
drop = 2;
printk("%d %d %d",win_scale,win,(ack_m->ack_winsize * SIZE_KB));
}
ret = tcp_ack_handle_new(msgbuf, ack_m, ack_info,
&ack_msg, drop);
}
goto out;
}
index = tcp_ack_alloc_index(ack_m);
if (index >= 0) {
write_seqlock_bh(&ack_m->ack_info[index].seqlock);
ack_m->ack_info[index].busy = 1;
ack_m->ack_info[index].psh_flag = 0;
ack_m->ack_info[index].last_time = jiffies;
ack_m->ack_info[index].drop_cnt =
atomic_read(&ack_m->max_drop_cnt);
ack_m->ack_info[index].win_scale =
(win_scale != 0) ? win_scale : 1;
//ack_m->ack_info[index].msgbuf = NULL;
//ack_m->ack_info[index].in_send_msg = NULL;
ack = &ack_m->ack_info[index].ack_msg;
ack->dest = ack_msg.dest;
ack->source = ack_msg.source;
ack->saddr = ack_msg.saddr;
ack->daddr = ack_msg.daddr;
ack->seq = ack_msg.seq;
write_sequnlock_bh(&ack_m->ack_info[index].seqlock);
}
out:
return ret;
}
void move_tcpack_msg(struct rwnx_hw *priv,
struct msg_buf *msg)
{
struct tcp_ack_info *ack_info;
struct tcp_ack_manage *ack_m = &priv->ack_m;
int i = 0;
if (!atomic_read(&ack_m->enable))
return;
//if (msg->len > MAX_TCP_ACK)
// return;
for (i = 0; i < TCP_ACK_NUM; i++) {
ack_info = &ack_m->ack_info[i];
write_seqlock_bh(&ack_info->seqlock);
if (ack_info->busy && (ack_info->in_send_msg == msg))
ack_info->in_send_msg = NULL;
write_sequnlock_bh(&ack_info->seqlock);
}
}

View File

@@ -0,0 +1,111 @@
#ifndef _AICWF_TCP_ACK_H_
#define _AICWF_TCP_ACK_H_
#include <uapi/linux/if_ether.h>
#include <uapi/linux/tcp.h>
#include <uapi/linux/ip.h>
#include <uapi/linux/in.h>
#include <linux/moduleparam.h>
#include <net/tcp.h>
#include <linux/timer.h>
#define TCP_ACK_NUM 32
#define TCP_ACK_EXIT_VAL 0x800
#define TCP_ACK_DROP_CNT 10
#define ACK_OLD_TIME 4000
#define U32_BEFORE(a, b) ((__s32)((__u32)a - (__u32)b) <= 0)
#define MAX_TCP_ACK 200
/*min window size in KB, it's 256KB*/
#define MIN_WIN 256
#define SIZE_KB 1024
struct msg_buf {
//struct list_head list;
struct sk_buff *skb;
struct rwnx_vif *rwnx_vif;
/* data just tx cmd use,not include the head */
/*void *data;
void *tran_data;
unsigned long pcie_addr;
u8 type;
u8 mode;
u16 len;
unsigned long timeout;*/
/* marlin 2 */
/*unsigned int fifo_id;
struct sprdwl_msg_list *msglist;*/
/* marlin 3 */
/*unsigned char buffer_type;
struct sprdwl_xmit_msg_list *xmit_msg_list;
unsigned char msg_type;
unsigned long last_time;
u8 ctxt_id;*/
};
struct tcp_ack_msg {
u16 source;
u16 dest;
s32 saddr;
s32 daddr;
u32 seq;
u16 win;
};
struct tcp_ack_info {
int ack_info_num;
int busy;
int drop_cnt;
int psh_flag;
u32 psh_seq;
u16 win_scale;
/* seqlock for ack info */
seqlock_t seqlock;
unsigned long last_time;
unsigned long timeout;
struct timer_list timer;
struct msg_buf *msgbuf;
struct msg_buf *in_send_msg;
struct tcp_ack_msg ack_msg;
};
struct tcp_ack_manage {
/* 1 filter */
atomic_t enable;
int max_num;
int free_index;
unsigned long last_time;
unsigned long timeout;
atomic_t max_drop_cnt;
/* lock for tcp ack alloc and free */
spinlock_t lock;
struct rwnx_hw *priv;
struct tcp_ack_info ack_info[TCP_ACK_NUM];
/*size in KB*/
unsigned int ack_winsize;
};
struct msg_buf *intf_tcp_alloc_msg(struct msg_buf *msg);
void tcp_ack_init(struct rwnx_hw *priv);
void tcp_ack_deinit(struct rwnx_hw *priv);
int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len, unsigned short *win_scale);
int is_tcp_ack(struct sk_buff *skb, unsigned short *win_scale);
int filter_send_tcp_ack(struct rwnx_hw *priv, struct msg_buf *msgbuf,unsigned char *buf, unsigned int plen);
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);
#endif

View File

@@ -100,7 +100,9 @@ int aicwf_bus_init(uint bus_hdrlen, struct device *dev)
bus_if->busrx_thread = kthread_run(sdio_busrx_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busrx_thread");
//new oob feature
#ifdef CONFIG_OOB
bus_if->busirq_thread = kthread_run(sdio_busirq_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busirq_thread");
if(bus_if->bus_priv.sdio->oob_enable){
bus_if->busirq_thread = kthread_run(sdio_busirq_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busirq_thread");
}
#endif //CONFIG_OOB
#endif
#ifdef AICWF_USB_SUPPORT
@@ -203,7 +205,7 @@ struct aicwf_tx_priv *aicwf_tx_init(void *arg)
#endif
atomic_set(&tx_priv->aggr_count, 0);
#if AICBSP_RESV_MEM_SUPPORT
#ifdef CONFIG_RESV_MEM_SUPPORT
tx_priv->aggr_buf = aicbsp_resv_mem_alloc_skb(MAX_AGGR_TXPKT_LEN, AIC_RESV_MEM_TXDATA);
#else
tx_priv->aggr_buf = dev_alloc_skb(MAX_AGGR_TXPKT_LEN);
@@ -222,7 +224,7 @@ struct aicwf_tx_priv *aicwf_tx_init(void *arg)
void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv)
{
if (tx_priv && tx_priv->aggr_buf) {
#if AICBSP_RESV_MEM_SUPPORT
#ifdef CONFIG_RESV_MEM_SUPPORT
aicbsp_resv_mem_kfree_skb(tx_priv->aggr_buf, AIC_RESV_MEM_TXDATA);
#else
dev_kfree_skb(tx_priv->aggr_buf);
@@ -532,7 +534,6 @@ static struct recv_msdu *aicwf_rxframe_queue_init(struct list_head *q, int qsize
for (i = 0; i < qsize; i++) {
INIT_LIST_HEAD(&req->rxframe_list);
list_add(&req->rxframe_list, q);
req->len = 0;
req++;
}
@@ -613,11 +614,13 @@ void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv)
rx_priv->sdiodev->bus_if->busrx_thread = NULL;
}
#ifdef CONFIG_OOB
//new oob feature
if (rx_priv->sdiodev->bus_if->busirq_thread) {
complete_all(&rx_priv->sdiodev->bus_if->busirq_trgg);
kthread_stop(rx_priv->sdiodev->bus_if->busirq_thread);
rx_priv->sdiodev->bus_if->busirq_thread = NULL;
if(rx_priv->sdiodev->oob_enable){
//new oob feature
if (rx_priv->sdiodev->bus_if->busirq_thread) {
complete_all(&rx_priv->sdiodev->bus_if->busirq_trgg);
kthread_stop(rx_priv->sdiodev->bus_if->busirq_thread);
rx_priv->sdiodev->bus_if->busirq_thread = NULL;
}
}
#endif //CONFIG_OOB
#endif

View File

@@ -161,7 +161,8 @@ struct recv_msdu {
u8 tid;
u16 seq_num;
u8 forward;
uint len;
//uint len;
u32 is_amsdu;
u8 *rx_data;
//for pending rx reorder list
struct list_head reord_pending_list;

View File

@@ -391,6 +391,9 @@ enum mm_msg_tag {
MM_CFG_RSSI_CFM,
MM_SET_VENDOR_SWCONFIG_REQ,
MM_SET_VENDOR_SWCONFIG_CFM,
/// MAX number of messages
MM_MAX,
};
@@ -1819,6 +1822,7 @@ enum vendor_hwconfig_tag{
MAC_TIMESCALE_REQ,
CCA_THRESHOLD_REQ,
BWMODE_REQ,
CHIP_TEMP_GET_REQ,
};
enum {
@@ -1846,6 +1850,7 @@ struct mm_set_channel_access_req
u8_l long_nav_en;
u8_l cfe_en;
u8_l rc_retry_cnt[3];
s8_l ccademod_th;
};
struct mm_set_mac_timescale_req
@@ -1876,6 +1881,24 @@ struct mm_set_bwmode_req
u8_l bwmode;
};
struct mm_get_chip_temp_req
{
u32_l hwconfig_id;
};
struct mm_get_chip_temp_cfm
{
/// Temp degree val
s8_l degree;
};
struct mm_set_vendor_hwconfig_cfm
{
u32_l hwconfig_id;
union {
struct mm_get_chip_temp_cfm chip_temp_cfm;
};
};
struct mm_set_txop_req
{
@@ -1893,6 +1916,71 @@ struct mm_get_fw_version_cfm
u8_l fw_version[63];
};
struct mm_get_wifi_disable_cfm
{
u8_l wifi_disable;
};
enum vendor_swconfig_tag
{
BCN_CFG_REQ = 0,
TEMP_COMP_SET_REQ,
TEMP_COMP_GET_REQ,
};
struct mm_set_bcn_cfg_req
{
/// Ignore or not bcn tim bcmc bit
bool_l tim_bcmc_ignored_enable;
};
struct mm_set_bcn_cfg_cfm
{
/// Request status
bool_l tim_bcmc_ignored_status;
};
struct mm_set_temp_comp_req
{
/// Enable or not temp comp
u8_l enable;
u8_l reserved[3];
u32_l tmr_period_ms;
};
struct mm_set_temp_comp_cfm
{
/// Request status
u8_l status;
};
struct mm_get_temp_comp_cfm
{
/// Request status
u8_l status;
/// Temp degree val
s8_l degree;
};
struct mm_set_vendor_swconfig_req
{
u32_l swconfig_id;
union {
struct mm_set_bcn_cfg_req bcn_cfg_req;
struct mm_set_temp_comp_req temp_comp_set_req;
};
};
struct mm_set_vendor_swconfig_cfm
{
u32_l swconfig_id;
union {
struct mm_set_bcn_cfg_cfm bcn_cfg_cfm;
struct mm_set_temp_comp_cfm temp_comp_set_cfm;
struct mm_get_temp_comp_cfm temp_comp_get_cfm;
};
};
/// Structure containing the parameters of the @ref ME_RC_STATS_REQ message.
struct me_rc_stats_req {
/// Index of the station for which the RC statistics are requested

View File

@@ -37,12 +37,31 @@
#endif
/* CFG80211 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK
//because android kernel 5.15 uses kernel 6.0 or 6.1 kernel api
#ifdef ANDROID_PLATFORM
#define HIGH_KERNEL_VERSION KERNEL_VERSION(5, 15, 41)
#define HIGH_KERNEL_VERSION2 KERNEL_VERSION(5, 15, 41)
#define HIGH_KERNEL_VERSION3 KERNEL_VERSION(5, 15, 104)
#define HIGH_KERNEL_VERSION4 KERNEL_VERSION(6, 1, 0)
#else
#define HIGH_KERNEL_VERSION KERNEL_VERSION(6, 0, 0)
#define HIGH_KERNEL_VERSION2 KERNEL_VERSION(6, 1, 0)
#define HIGH_KERNEL_VERSION3 KERNEL_VERSION(6, 3, 0)
#define HIGH_KERNEL_VERSION4 KERNEL_VERSION(6, 3, 0)
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 15, 0)
#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 60)
#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE
#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB
#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB
#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
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
#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(4, 19, 0)

View File

@@ -1242,7 +1242,7 @@ static ssize_t rwnx_dbgfs_regdbg_write(struct file *file,
buf[len] = '\0';
if (sscanf(buf, "%x %x %x" , &oper, &addr, &val ) > 0)
if (sscanf(buf, "%x %x %x" , &oper, &addr, &val ) > 0)
printk("addr=%x, val=%x,oper=%d\n", addr, val, oper);
if(oper== 0) {
@@ -1261,7 +1261,8 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file,
{
struct rwnx_hw *priv = file->private_data;
char buf[64];
int32_t addr[12];
int32_t addr[13];
int32_t addr_out[12];
u32_l hwconfig_id;
size_t len = min_t(size_t,count,sizeof(buf)-1);
int ret;
@@ -1274,10 +1275,10 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file,
}
buf[len] = '\0';
ret = sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x",
&hwconfig_id, &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5], &addr[6], &addr[7], &addr[8], &addr[9], &addr[10], &addr[11]);
if(ret > 13) {
printk("param error > 13\n");
ret = sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x",
&hwconfig_id, &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5], &addr[6], &addr[7], &addr[8], &addr[9], &addr[10], &addr[11], &addr[12]);
if(ret > 14) {
printk("param error > 14\n");
} else {
switch(hwconfig_id)
{
@@ -1285,22 +1286,23 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file,
if(ret != 5) {
printk("param error != 5\n");
break;}
ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr);
ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL);
printk("ACS_TXOP_REQ bk:0x%x be:0x%x vi:0x%x vo:0x%x\n",addr[0], addr[1], addr[2], addr[3]);
break;
case 1:
if(ret != 13) {
printk("param error != 13\n");
if(ret != 14) {
printk("param error != 14\n");
break;}
ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr);
printk("CHANNEL_ACCESS_REQ edca:%x,%x,%x,%x, vif:%x, retry_cnt:%x, rts:%x, long_nav:%x, cfe:%x, rc_retry_cnt:%x:%x:%x\n",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11]);
addr[12] = ~addr[12] + 1;
ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL);
printk("CHANNEL_ACCESS_REQ edca:%x,%x,%x,%x, vif:%x, retry_cnt:%x, rts:%x, long_nav:%x, cfe:%x, rc_retry_cnt:%x:%x:%x ccademod_th %x\n",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12]);
break;
case 2:
if(ret != 7) {
printk("param error != 7\n");
break;}
ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr);
ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL);
printk("MAC_TIMESCALE_REQ sifsA:%x,sifsB:%x,slot:%x,ofdm_delay:%x,long_delay:%x,short_delay:%x\n",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
break;
@@ -1312,11 +1314,27 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file,
addr[2] = ~addr[2] + 1;
addr[3] = ~addr[3] + 1;
addr[4] = ~addr[4] + 1;
ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr);
ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL);
printk("CCA_THRESHOLD_REQ auto_cca:%d, cca20p_rise:%d cca20s_rise:%d cca20p_fail:%d cca20s_fail:%d\n",
addr[0], addr[1], addr[2], addr[3], addr[4]);
break;
default:
case 4: // BWMODE_REQ
if (ret != 2) {
printk("param error != 2\n");
} else {
ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL);
printk("BWMODE_REQ md=%d\n", addr[0]);
}
break;
case 5: // CHIP_TEMP_GET_REQ
if (ret != 1) {
printk("param error != 1\n");
} else {
ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, addr_out);
printk("CHIP_TEMP_GET_REQ degree=%d\n", addr_out[0]);
}
break;
default:
printk("param error\n");
break;
}
@@ -1330,6 +1348,73 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file,
DEBUGFS_WRITE_FILE_OPS(vendor_hwconfig)
static ssize_t rwnx_dbgfs_vendor_swconfig_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct rwnx_hw *priv = file->private_data;
char buf[64];
int32_t addr[12];
int32_t addr_out[12];
u32_l swconfig_id;
size_t len = min_t(size_t, count, sizeof(buf) - 1);
int ret;
printk("%s\n", __func__);
if (copy_from_user(buf, user_buf, len)) {
return -EFAULT;
}
buf[len] = '\0';
ret = sscanf(buf, "%x %x %x", &swconfig_id, &addr[0], &addr[1]);
if (ret > 3) {
printk("param error > 3\n");
} else {
switch (swconfig_id)
{
case 0: // BCN_CFG_REQ
if (ret != 2) {
printk("param error != 2\n");
} else {
ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out);
printk("BCN_CFG_REQ set_en=%d, get_en=%d\n", addr[0], addr_out[0]);
}
break;
case 1: // TEMP_COMP_SET_REQ
if (ret != 3) {
printk("param error != 3\n");
} else {
ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out);
printk("TEMP_COMP_SET_REQ set_en=%d, tmr=%dms, get_st=%d\n",
addr[0], addr[1], addr_out[0]);
}
break;
case 2: // TEMP_COMP_GET_REQ
if (ret != 1) {
printk("param error != 1\n");
} else {
ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out);
printk("TEMP_COMP_GET_REQ get_st=%d, degree=%d\n", addr_out[0], addr_out[1]);
}
break;
default:
printk("param error\n");
break;
}
if (ret) {
printk("rwnx_send_vendor_swconfig_req fail: %x\n", ret);
}
}
return count;
}
DEBUGFS_WRITE_FILE_OPS(vendor_swconfig)
#ifdef CONFIG_RWNX_FULLMAC
@@ -1831,8 +1916,8 @@ static ssize_t rwnx_dbgfs_last_rx_read(struct file *file,
if (rate_stats->table[i]) {
union rwnx_rate_ctrl_info rate_config;
int percent = (rate_stats->table[i] * 1000) / rate_stats->cpt;
int p;
int ru_size;
int p = 0;
int ru_size = 0;
idx_to_rate_cfg(i, &rate_config, &ru_size);
len += print_rate_from_cfg(&buf[len], bufsz - len,
@@ -2153,6 +2238,7 @@ int rwnx_dbgfs_register(struct rwnx_hw *rwnx_hw, const char *name)
#endif
DEBUGFS_ADD_FILE(regdbg, dir_drv, S_IWUSR);
DEBUGFS_ADD_FILE(vendor_hwconfig, dir_drv,S_IWUSR);
DEBUGFS_ADD_FILE(vendor_swconfig, dir_drv,S_IWUSR);
#ifdef CONFIG_RWNX_P2P_DEBUGFS
{

View File

@@ -29,8 +29,13 @@
#include "rwnx_mu_group.h"
#include "rwnx_platform.h"
#include "rwnx_cmds.h"
#ifdef CONFIG_GKI
#include "rwnx_gki.h"
#endif
#include "rwnx_compat.h"
#ifdef CONFIG_FILTER_TCP_ACK
#include "aicwf_tcp_ack.h"
#endif
#ifdef AICWF_SDIO_SUPPORT
#include "aicwf_sdio.h"
@@ -295,6 +300,7 @@ struct rwnx_vif {
struct net_device *ndev;
struct net_device_stats net_stats;
struct rwnx_key key[6];
unsigned long drv_flags;
atomic_t drv_conn_state;
u8 drv_vif_index; /* Identifier of the VIF in driver */
u8 vif_index; /* Identifier of the station in FW */
@@ -320,6 +326,13 @@ struct rwnx_vif {
bool external_auth; /* Indicate if external authentication is in progress */
u32 group_cipher_type;
u32 paired_cipher_type;
//connected network info start
char ssid[33];//ssid max is 32, but this has one spare for '\0'
int ssid_len;
u8 bssid[ETH_ALEN];
u32 conn_owner_nlportid;
bool is_roam;
//connected network info end
} sta;
struct {
u16 flags; /* see rwnx_ap_flags */
@@ -602,13 +615,17 @@ struct rwnx_hw {
u8 monitor_vif; /* FW id of the monitor interface, RWNX_INVALID_VIF if no monitor vif at fw level */
#ifdef CONFIG_FILTER_TCP_ACK
/* tcp ack management */
struct tcp_ack_manage ack_m;
#endif
/* RoC Management */
struct rwnx_roc_elem *roc_elem; /* Information provided by cfg80211 in its remain on channel request */
u32 roc_cookie_cnt; /* Counter used to identify RoC request sent by cfg80211 */
struct rwnx_cmd_mgr *cmd_mgr;
unsigned long drv_flags;
struct rwnx_plat *plat;
spinlock_t tx_lock;
@@ -652,7 +669,7 @@ struct rwnx_hw {
struct rwnx_hwq hwq[NX_TXQ_CNT];
u8 avail_idx_map;
u64 avail_idx_map;
u8 vif_started;
bool adding_sta;
struct rwnx_phy_info phy;

View File

@@ -243,7 +243,7 @@ int rwnx_dini_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_pla
pci_read_config_word(pci_dev, PCI_COMMAND, &pci_cmd);
pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
pci_write_config_word(pci_dev, PCI_COMMAND, pci_cmd);
pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2);
//pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2);
ret = pci_enable_device(pci_dev);
if (ret) {
@@ -252,13 +252,13 @@ int rwnx_dini_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_pla
}
pci_set_master(pci_dev);
#if 0
ret = pci_request_regions(pci_dev, KBUILD_MODNAME);
if (ret) {
dev_err(&(pci_dev->dev), "pci_request_regions failed\n");
goto out_request;
}
#endif
rwnx_dini->pci_bar0_vaddr = (u8 *)pci_ioremap_bar(pci_dev, 0);
if (!rwnx_dini->pci_bar0_vaddr) {
dev_err(&(pci_dev->dev), "pci_ioremap_bar(%d) failed\n", 0);
@@ -289,7 +289,7 @@ out_bar4:
iounmap(rwnx_dini->pci_bar0_vaddr);
out_bar0:
pci_release_regions(pci_dev);
out_request:
//out_request:
pci_disable_device(pci_dev);
out_enable:
kfree(*rwnx_plat);

View File

@@ -2,12 +2,12 @@
#ifdef ANDROID_PLATFORM
#include "net/wireless/core.h"
#endif
#include <include/linux/types.h>
#undef NL80211_MCGRP_MLME
#define NL80211_MCGRP_MLME 3
#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
//#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
static struct genl_family rwnx_nl80211_fam;

View File

@@ -5,7 +5,8 @@
#include "net/wireless/core.h"
#endif
#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
//#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
bool rwnx_cfg80211_rx_spurious_frame(struct net_device *dev,

View File

@@ -22,6 +22,7 @@
#include <linux/if_arp.h>
#include <linux/ctype.h>
#include <linux/random.h>
#include <linux/vmalloc.h>
#include "rwnx_defs.h"
#include "rwnx_dini.h"
#include "rwnx_msg_tx.h"
@@ -774,12 +775,12 @@ static void rwnx_csa_finish(struct work_struct *ws)
} else
rwnx_txq_vif_stop(vif, RWNX_TXQ_STOP_CHAN, rwnx_hw);
spin_unlock_bh(&rwnx_hw->cb_lock);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 94))
cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0, 0);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0);
#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION3)
cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0, 0);
#elif (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION)
cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0);
#else
cfg80211_ch_switch_notify(vif->ndev, &csa->chandef);
cfg80211_ch_switch_notify(vif->ndev, &csa->chandef);
#endif
mutex_unlock(&vif->wdev.mtx);
__release(&vif->wdev.mtx);
@@ -924,10 +925,22 @@ static int rwnx_open(struct net_device *dev)
struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw;
struct mm_add_if_cfm add_if_cfm;
int error = 0;
u8 rwnx_rx_gain = 0x0E;
u8 rwnx_rx_gain = 0x0E;
int err = 0;
int waiting_counter = 10;
RWNX_DBG(RWNX_FN_ENTRY_STR);
while(test_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags)){
msleep(100);
AICWFDBG(LOGDEBUG, "%s waiting for rwnx_close \r\n", __func__);
waiting_counter--;
if(waiting_counter == 0){
AICWFDBG(LOGERROR, "%s error waiting for close time out \r\n", __func__);
break;
}
}
#ifdef CONFIG_GPIO_WAKEUP
//close lp mode
// rwnx_send_me_set_lp_level(g_rwnx_plat->sdiodev->rwnx_hw, 0);
@@ -959,7 +972,7 @@ static int rwnx_open(struct net_device *dev)
#endif
/* Device is now started */
set_bit(RWNX_DEV_STARTED, &rwnx_hw->drv_flags);
set_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags);
atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED);
}
#ifdef CONFIG_COEX
@@ -968,6 +981,32 @@ static int rwnx_open(struct net_device *dev)
}
#endif
if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_GO) {
if (!rwnx_hw->is_p2p_alive) {
if (rwnx_hw->p2p_dev_vif && !rwnx_hw->p2p_dev_vif->up) {
err = rwnx_send_add_if (rwnx_hw, rwnx_hw->p2p_dev_vif->wdev.address,
RWNX_VIF_TYPE(rwnx_hw->p2p_dev_vif), false, &add_if_cfm);
if (err) {
return -EIO;
}
if (add_if_cfm.status != 0) {
return -EIO;
}
/* Save the index retrieved from LMAC */
spin_lock_bh(&rwnx_hw->cb_lock);
rwnx_hw->p2p_dev_vif->vif_index = add_if_cfm.inst_nbr;
rwnx_hw->p2p_dev_vif->up = true;
rwnx_hw->vif_started++;
rwnx_hw->vif_table[add_if_cfm.inst_nbr] = rwnx_hw->p2p_dev_vif;
spin_unlock_bh(&rwnx_hw->cb_lock);
}
rwnx_hw->is_p2p_alive = 1;
mod_timer(&rwnx_hw->p2p_alive_timer, jiffies + msecs_to_jiffies(1000));
atomic_set(&rwnx_hw->p2p_alive_timer_count, 0);
}
}
if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP_VLAN) {
/* For AP_vlan use same fw and drv indexes. We ensure that this index
@@ -1059,9 +1098,24 @@ static int rwnx_close(struct net_device *dev)
struct aic_sdio_dev *sdiodev = NULL;
#else
#endif
int waiting_counter = 20;
int test_counter = 0;
RWNX_DBG(RWNX_FN_ENTRY_STR);
test_counter = waiting_counter;
while(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING||
atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING){
AICWFDBG(LOGDEBUG, "%s wifi is connecting or disconnecting, waiting 200ms for state to stable\r\n", __func__);
msleep(200);
test_counter--;
if(test_counter == 0){
AICWFDBG(LOGERROR, "%s connecting or disconnecting, not finish\r\n", __func__);
WARN_ON(1);
break;
}
}
#if defined(AICWF_USB_SUPPORT) || defined(AICWF_SDIO_SUPPORT)
if (scanning) {
scanning = false;
@@ -1143,9 +1197,17 @@ static int rwnx_close(struct net_device *dev)
if (sdiodev->bus_if->state != BUS_DOWN_ST){
if(RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION ||
RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT){
if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING){
test_counter = waiting_counter;
if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED){
atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING);
rwnx_send_sm_disconnect_req(rwnx_hw, rwnx_vif, 3);
atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED);
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__);
msleep(100);
test_counter--;
if (test_counter ==0)
break;
}
}
}
#ifdef CONFIG_USE_P2P0
@@ -1194,7 +1256,7 @@ static int rwnx_close(struct net_device *dev)
}
}
#endif
clear_bit(RWNX_DEV_STARTED, &rwnx_hw->drv_flags);
clear_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags);
}
#ifdef CONFIG_COEX
else {
@@ -1875,7 +1937,7 @@ int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
bytes_written = -EINVAL;
break;
}
if(g_rwnx_plat->sdiodev->chipid != PRODUCT_ID_AIC8800D80){
if(g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800D80){
memcpy(command, &cfm.rftest_result[0], 6 * 12);
bytes_written = 6 * 12;
} else {
@@ -2884,12 +2946,22 @@ static struct rwnx_vif *rwnx_interface_add(struct rwnx_hw *rwnx_hw,
}
if (type == NL80211_IFTYPE_AP_VLAN) {
memcpy(ndev->dev_addr, params->macaddr, ETH_ALEN);
memcpy(vif->wdev.address, params->macaddr, ETH_ALEN);
memcpy((void *)ndev->dev_addr, (const void *)params->macaddr, ETH_ALEN);
memcpy((void *)vif->wdev.address, (const void *)params->macaddr, ETH_ALEN);
} else {
memcpy(ndev->dev_addr, rwnx_hw->wiphy->perm_addr, ETH_ALEN);
ndev->dev_addr[5] ^= vif_idx;
memcpy(vif->wdev.address, ndev->dev_addr, ETH_ALEN);
#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;
//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;
memcpy(vif->wdev.address, ndev->dev_addr, ETH_ALEN);
#endif
}
AICWFDBG(LOGINFO, "interface add:%x %x %x %x %x %x\n", vif->wdev.address[0], vif->wdev.address[1], \
@@ -3278,6 +3350,7 @@ static int rwnx_cfg80211_change_iface(struct wiphy *wiphy,
/* Abort scan request on the vif */
if (vif->rwnx_hw->scan_request &&
vif->rwnx_hw->scan_request->wdev == &vif->wdev) {
#if 0
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
struct cfg80211_scan_info info = {
.aborted = true,
@@ -3293,6 +3366,12 @@ static int rwnx_cfg80211_change_iface(struct wiphy *wiphy,
return ret;
}
vif->rwnx_hw->scan_request = NULL;
#else
if ((ret = rwnx_send_scanu_cancel_req(vif->rwnx_hw, NULL))) {
AICWFDBG(LOGERROR, "scanu_cancel fail\n");
return ret;
}
#endif
}
ret = rwnx_send_remove_if(vif->rwnx_hw, vif->vif_index, false);
if (ret) {
@@ -3400,6 +3479,7 @@ static int rwnx_cfg80211_scan(struct wiphy *wiphy,
}
if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING){
AICWFDBG(LOGERROR, "%s wifi is connecting, return it\r\n", __func__);
return -EBUSY;
}
@@ -3414,6 +3494,13 @@ static int rwnx_cfg80211_scan(struct wiphy *wiphy,
return -EBUSY;
}
if ((RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION ||
RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) &&
rwnx_vif->sta.external_auth) {
AICWFDBG(LOGERROR, "scan about: external auth\r\n");
return -EBUSY;
}
rwnx_hw->scan_request = request;
error = rwnx_send_scanu_req(rwnx_hw, rwnx_vif, request);
if (error)
@@ -3427,12 +3514,13 @@ bool key_flag = false;
* @add_key: add a key with the given parameters. @mac_addr will be %NULL
* when adding a group key.
*/
static int rwnx_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
int link_id,
static int rwnx_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
int link_id,
#endif
u8 key_index, bool pairwise, const u8 *mac_addr,
struct key_params *params)
u8 key_index, bool pairwise, const u8 *mac_addr,
struct key_params *params)
{
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
struct rwnx_vif *vif = netdev_priv(netdev);
@@ -3524,7 +3612,7 @@ static int rwnx_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
*
*/
static int rwnx_cfg80211_get_key(struct wiphy *wiphy, struct net_device *netdev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
int link_id,
#endif
u8 key_index, bool pairwise, const u8 *mac_addr,
@@ -3542,7 +3630,7 @@ static int rwnx_cfg80211_get_key(struct wiphy *wiphy, struct net_device *netdev,
* and @key_index, return -ENOENT if the key doesn't exist.
*/
static int rwnx_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
int link_id,
#endif
u8 key_index, bool pairwise, const u8 *mac_addr)
@@ -3581,7 +3669,7 @@ static int rwnx_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
*/
static int rwnx_cfg80211_set_default_key(struct wiphy *wiphy,
struct net_device *netdev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
int link_id,
#endif
u8 key_index, bool unicast, bool multicast)
@@ -3596,7 +3684,7 @@ static int rwnx_cfg80211_set_default_key(struct wiphy *wiphy,
*/
static int rwnx_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
struct net_device *netdev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
int link_id,
#endif
u8 key_index)
@@ -3631,10 +3719,18 @@ static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return -EALREADY;
}
#endif
if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING){
AICWFDBG(LOGERROR, "%s driver is disconnecting return it \r\n", __func__);
return -EALREADY;
}
if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED) {
AICWFDBG(LOGDEBUG, "%s this connection is roam \r\n", __func__);
rwnx_vif->sta.is_roam = true;
}else{
rwnx_vif->sta.is_roam = false;
}
if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING||
(int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING) {
AICWFDBG(LOGERROR, "%s driver is disconnecting or connecting ,return it \r\n", __func__);
return -EALREADY;
}
#endif
atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTING);
@@ -3675,7 +3771,7 @@ static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
key_params.seq_len = 0;
key_params.cipher = sme->crypto.cipher_group;
rwnx_cfg80211_add_key(wiphy, dev,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
0,
#endif
sme->key_idx, false, NULL, &key_params);
@@ -3751,6 +3847,12 @@ static int rwnx_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
msleep(500);
}
if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_DISCONNECTING) {
AICWFDBG(LOGERROR, "%s wifi is disconnecting, return it:%d \r\n",
__func__, reason_code);
return -EBUSY;
}
if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTED){
atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING);
key_flag = true;
@@ -3759,6 +3861,7 @@ static int rwnx_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0,
reason_code?reason_code:WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC);
atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED);
rwnx_external_auth_disable(rwnx_vif);
return 0;
}
@@ -3935,7 +4038,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
sta->vif_idx = rwnx_vif->vif_index;
sta->vlan_idx = sta->vif_idx;
sta->qos = (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) != 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41)
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
sta->ht = params->link_sta_params.ht_capa ? 1 : 0;
sta->vht = params->link_sta_params.vht_capa ? 1 : 0;
#else
@@ -4341,7 +4444,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
sta->vif_idx = rwnx_vif->vif_index;
sta->vlan_idx = sta->vif_idx;
sta->qos = (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) != 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41)
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
sta->ht = params->link_sta_params.ht_capa ? 1 : 0;
sta->vht = params->link_sta_params.vht_capa ? 1 : 0;
#else
@@ -4588,7 +4691,7 @@ static int rwnx_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *d
/**
* * @stop_ap: Stop being an AP, including stopping beaconing.
*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION)
static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev, unsigned int link_id)
#else
static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
@@ -4990,6 +5093,11 @@ static int rwnx_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
return rwnx_send_cancel_roc(rwnx_hw);
}
#define IS_2P4GHZ(n) (n >= 2412 && n <= 2484)
#define IS_5GHZ(n) (n >= 4000 && n <= 5895)
#define DEFAULT_NOISE_FLOOR_2GHZ (-89)
#define DEFAULT_NOISE_FLOOR_5GHZ (-92)
/**
* @dump_survey: get site survey information.
*/
@@ -5034,7 +5142,9 @@ static int rwnx_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *net
if (rwnx_survey->filled != 0) {
SURVEY_TIME(info) = (u64)rwnx_survey->chan_time_ms;
SURVEY_TIME_BUSY(info) = (u64)rwnx_survey->chan_time_busy_ms;
info->noise = rwnx_survey->noise_dbm;
//info->noise = rwnx_survey->noise_dbm;
info->noise = ((IS_2P4GHZ(info->channel->center_freq)) ? DEFAULT_NOISE_FLOOR_2GHZ :
(IS_5GHZ(info->channel->center_freq)) ? DEFAULT_NOISE_FLOOR_5GHZ : DEFAULT_NOISE_FLOOR_5GHZ);
// Set the survey report as not used
if(info->noise == 0){
@@ -5055,7 +5165,7 @@ static int rwnx_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *net
*/
static int rwnx_cfg80211_get_channel(struct wiphy *wiphy,
struct wireless_dev *wdev,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
unsigned int link_id,
#endif
struct cfg80211_chan_def *chandef)
@@ -5260,7 +5370,7 @@ int rwnx_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
return rwnx_send_cfg_rssi_req(rwnx_hw, rwnx_vif->vif_index, rssi_thold, rssi_hyst);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
/**
*
* @channel_switch: initiate channel-switch procedure (with CSA). Driver is
@@ -5349,22 +5459,16 @@ int rwnx_cfg80211_channel_switch (struct wiphy *wiphy,
goto end;
} else {
INIT_WORK(&csa->work, rwnx_csa_finish);
rwnx_cfg80211_ch_switch_started_notify(dev
, &csa->chandef
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
, 0
#endif
, params->count
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
, false
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION4
cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false, 0);
#elif LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2
cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
, params->block_tx
cfg80211_ch_switch_started_notify(dev, &csa->chandef, params->count, params->block_tx);
#else
cfg80211_ch_switch_started_notify(dev, &csa->chandef, params->count);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 94)
, 0
#endif
);
}
end:
@@ -6353,7 +6457,7 @@ static struct cfg80211_ops rwnx_cfg80211_ops = {
.start_radar_detection = rwnx_cfg80211_start_radar_detection,
.update_ft_ies = rwnx_cfg80211_update_ft_ies,
.set_cqm_rssi_config = rwnx_cfg80211_set_cqm_rssi_config,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
.channel_switch = rwnx_cfg80211_channel_switch,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
@@ -6563,6 +6667,9 @@ extern int get_wifi_custom_mac_address(char *addr_str);
#ifdef CONFIG_PLATFORM_ROCKCHIP
#include <linux/rfkill-wlan.h>
#endif
#ifdef CONFIG_PLATFORM_ROCKCHIP2
#include <linux/rfkill-wlan.h>
#endif
#ifdef CONFIG_USE_CUSTOMER_MAC
int rwnx_get_custom_mac_addr(u8_l *mac_addr_efuse){
@@ -6585,6 +6692,9 @@ int rwnx_get_custom_mac_addr(u8_l *mac_addr_efuse){
#ifdef CONFIG_PLATFORM_ROCKCHIP
ret = rockchip_wifi_mac_addr(mac_addr_efuse);
#endif//CONFIG_PLATFORM_ROCKCHIP
#ifdef CONFIG_PLATFORM_ROCKCHIP2
ret = rockchip_wifi_mac_addr(mac_addr_efuse);
#endif//CONFIG_PLATFORM_ROCKCHIP
if(ret == 0){
AICWFDBG(LOGINFO, "%s %02x:%02x:%02x:%02x:%02x:%02x", __func__,
@@ -6612,6 +6722,9 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data)
u8_l mac_addr_efuse[ETH_ALEN];
struct aicbsp_feature_t feature;
struct mm_set_stack_start_cfm set_start_cfm;
#ifdef CONFIG_TEMP_COMP
struct mm_set_vendor_swconfig_cfm swconfig_cfm;
#endif
char fw_path[200];
(void)addr_str;
@@ -6665,6 +6778,10 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data)
goto err_cache;
}
#ifdef CONFIG_FILTER_TCP_ACK
tcp_ack_init(rwnx_hw);
#endif
#if 0
ret = rwnx_parse_configfile(rwnx_hw, RWNX_CONFIG_FW_NAME, &init_conf);
if (ret) {
@@ -6874,6 +6991,11 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data)
ret = rwnx_send_reset(rwnx_hw);
if (ret)
goto err_lmac_reqs;
#ifdef CONFIG_TEMP_COMP
rwnx_send_set_temp_comp_req(rwnx_hw, &swconfig_cfm);
#endif
ret = rwnx_send_version_req(rwnx_hw, &rwnx_hw->version_cfm);
if (ret)
goto err_lmac_reqs;
@@ -7038,6 +7160,9 @@ void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw)
rwnx_radar_detection_deinit(&rwnx_hw->radar);
rwnx_platform_off(rwnx_hw, NULL);
kmem_cache_destroy(rwnx_hw->sw_txhdr_cache);
#ifdef CONFIG_FILTER_TCP_ACK
tcp_ack_deinit(rwnx_hw);
#endif
aicwf_wakeup_lock_deinit(rwnx_hw);
wiphy_free(rwnx_hw->wiphy);
}

View File

@@ -1165,6 +1165,11 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
he_cap->ppe_thres[0] |= 0x10;
}
if (rwnx_hw->mod_params->use_80) {
he_cap->ppe_thres[0] |= 0x20;
he_cap->ppe_thres[2] |= 0xc0;
he_cap->ppe_thres[3] |= 0x07;
}
//if (rwnx_hw->mod_params->use_80)
{
he_cap->he_cap_elem.phy_cap_info[0] |=
@@ -1274,6 +1279,11 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
he_cap->ppe_thres[0] |= 0x10;
}
if (rwnx_hw->mod_params->use_80) {
he_cap->ppe_thres[0] |= 0x20;
he_cap->ppe_thres[2] |= 0xc0;
he_cap->ppe_thres[3] |= 0x07;
}
//if (rwnx_hw->mod_params->use_80)
{
he_cap->he_cap_elem.phy_cap_info[0] |=
@@ -1388,6 +1398,11 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
he_cap->ppe_thres[0] |= 0x10;
}
if (rwnx_hw->mod_params->use_80) {
he_cap->ppe_thres[0] |= 0x20;
he_cap->ppe_thres[2] |= 0xc0;
he_cap->ppe_thres[3] |= 0x07;
}
//if (rwnx_hw->mod_params->use_80)
{
he_cap->he_cap_elem.phy_cap_info[0] |=

View File

@@ -9,6 +9,7 @@
*
****************************************************************************************
*/
#include <linux/vmalloc.h>
#include "rwnx_defs.h"
#include "rwnx_prof.h"
#include "rwnx_tx.h"
@@ -24,6 +25,7 @@
#include "rwnx_compat.h"
#include "aicwf_txrxif.h"
#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)
{
@@ -712,8 +714,12 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
const u8 *extcap_ie;
const struct ieee_types_extcap *extcap;
struct ieee80211_channel *chan;
struct cfg80211_bss *bss = NULL;
struct wireless_dev *wdev = NULL;
int retry_counter = 10;
RWNX_DBG(RWNX_FN_ENTRY_STR);
wdev = dev->ieee80211_ptr;
/* Retrieve IE addresses and lengths */
req_ie = (const u8 *)ind->assoc_ie_buf;
@@ -811,7 +817,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
rwnx_chanctx_link(rwnx_mon_vif, ind->ch_idx, NULL);
}
#endif
atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
//atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
} else if (ind->status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
if (rwnx_vif->wep_enabled) {
rwnx_vif->wep_auth_err = true;
@@ -828,21 +834,100 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
ind->status_code,
(int)atomic_read(&rwnx_vif->drv_conn_state));
do {
bss = cfg80211_get_bss(wdev->wiphy, NULL, rwnx_vif->sta.bssid,
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
wdev->u.client.ssid, wdev->u.client.ssid_len,
#else
wdev->ssid, wdev->ssid_len,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
wdev->conn_bss_type,
IEEE80211_PRIVACY_ANY);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
IEEE80211_BSS_TYPE_ESS,
IEEE80211_PRIVACY_ANY);
#else
WLAN_CAPABILITY_ESS,
WLAN_CAPABILITY_PRIVACY);
#endif
if (!bss) {
printk("%s bss is NULL \r\n", __func__);
printk("%s bss ssid(%d):%s conn_bss_type:%d bss2 ssid(%d):%s conn_bss_type:%d\r\n",
__func__,
(int)rwnx_vif->sta.ssid_len,
rwnx_vif->sta.ssid,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
IEEE80211_BSS_TYPE_ESS,
#else
WLAN_CAPABILITY_ESS,
#endif
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
(int)wdev->u.client.ssid_len,
wdev->u.client.ssid,
#else
(int)wdev->ssid_len,
wdev->ssid,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
wdev->conn_bss_type
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
IEEE80211_BSS_TYPE_ESS
#else
WLAN_CAPABILITY_ESS
#endif
);
printk("%s rwnx_vif->sta.bssid %02x %02x %02x %02x %02x %02x \r\n", __func__,
rwnx_vif->sta.bssid[0], rwnx_vif->sta.bssid[1], rwnx_vif->sta.bssid[2],
rwnx_vif->sta.bssid[3], rwnx_vif->sta.bssid[4], rwnx_vif->sta.bssid[5]);
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
wdev->u.client.ssid_len = (int)rwnx_vif->sta.ssid_len;
memcpy(wdev->u.client.ssid, rwnx_vif->sta.ssid, wdev->u.client.ssid_len);
#else
wdev->ssid_len = (int)rwnx_vif->sta.ssid_len;
memcpy(wdev->ssid, rwnx_vif->sta.ssid, wdev->ssid_len);
#endif
msleep(100);
retry_counter--;
if(retry_counter == 0){
printk("%s bss recover fail \r\n", __func__);
break;
}
}
} while (!bss);
if (!ind->roamed){//not roaming
cfg80211_connect_result(dev, (const u8 *)ind->bssid.array, req_ie,
ind->assoc_req_ie_len, rsp_ie,
ind->assoc_rsp_ie_len, ind->status_code,
GFP_ATOMIC);
if (ind->status_code == 0) {
atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
} else {
atomic_set(&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));
}else {//roaming
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);
atomic_set(&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)
struct cfg80211_roam_info info;
memset(&info, 0, sizeof(info));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
if (rwnx_vif->ch_index < NX_CHAN_CTXT_CNT)
info.links[0].channel = rwnx_hw->chanctx_table[rwnx_vif->ch_index].chan_def.chan;
info.links[0].bssid = (const u8 *)ind->bssid.array;
@@ -856,6 +941,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
info.resp_ie = rsp_ie;
info.resp_ie_len = ind->assoc_rsp_ie_len;
cfg80211_roamed(dev, &info, GFP_ATOMIC);
atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
#else
chan = ieee80211_get_channel(rwnx_hw->wiphy, ind->center_freq);
cfg80211_roamed(dev
@@ -869,6 +955,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)*/
atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
}
}
netif_tx_start_all_queues(dev);
@@ -877,6 +964,36 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
return 0;
}
void rwnx_cfg80211_unlink_bss(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif){
struct wiphy *wiphy = rwnx_hw->wiphy;
struct cfg80211_bss *bss = NULL;
RWNX_DBG(RWNX_FN_ENTRY_STR);
bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
rwnx_vif->sta.bssid, rwnx_vif->sta.ssid,
rwnx_vif->sta.ssid_len,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
IEEE80211_BSS_TYPE_ESS,
IEEE80211_PRIVACY(true));//temp set true
#else
WLAN_CAPABILITY_ESS,
WLAN_CAPABILITY_ESS);
#endif
if (bss) {
cfg80211_unlink_bss(wiphy, bss);
AICWFDBG(LOGINFO, "%s(): cfg80211_unlink %s!!\n", __func__, rwnx_vif->sta.ssid);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
cfg80211_put_bss(wiphy, bss);
#else
cfg80211_put_bss(bss);
#endif
}else{
AICWFDBG(LOGINFO, "%s(): cfg80211_unlink error %s!!\n", __func__, rwnx_vif->sta.ssid);
}
}
extern u8 dhcped;
static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
struct rwnx_cmd *cmd,
@@ -892,12 +1009,23 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
#endif
RWNX_DBG(RWNX_FN_ENTRY_STR);
if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTED){
AICWFDBG(LOGINFO, "%s, is already disconnected, drop disconnect ind", __func__);
return 0;
}
dhcped = 0;
if(!rwnx_vif)
return 0;
dev = rwnx_vif->ndev;
if (rwnx_vif->sta.is_roam == false) {
rwnx_cfg80211_unlink_bss(rwnx_hw, rwnx_vif);
} else {
AICWFDBG(LOGINFO, "%s roaming no rwnx_cfg80211_unlink_bss \r\n", __func__);
}
#ifdef CONFIG_BR_SUPPORT
struct rwnx_vif *vif = netdev_priv(dev);
/* clear bridge database */
@@ -928,13 +1056,13 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
rx_priv = rwnx_hw->usbdev->rx_priv;
#endif
if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) {
macaddr = rwnx_vif->ndev->dev_addr;
macaddr = (u8*)rwnx_vif->ndev->dev_addr;
printk("deinit:macaddr:%x,%x,%x,%x,%x,%x\r\n", macaddr[0], macaddr[1], macaddr[2], \
macaddr[3], macaddr[4], macaddr[5]);
spin_lock_bh(&rx_priv->stas_reord_lock);
//spin_lock_bh(&rx_priv->stas_reord_lock);
list_for_each_entry_safe(reord_info, tmp, &rx_priv->stas_reord_list, list) {
macaddr = rwnx_vif->ndev->dev_addr;
macaddr = (u8*)rwnx_vif->ndev->dev_addr;
printk("reord_mac:%x,%x,%x,%x,%x,%x\r\n", reord_info->mac_addr[0], reord_info->mac_addr[1], reord_info->mac_addr[2], \
reord_info->mac_addr[3], reord_info->mac_addr[4], reord_info->mac_addr[5]);
if (!memcmp(reord_info->mac_addr, macaddr, 6)) {
@@ -942,7 +1070,7 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
break;
}
}
spin_unlock_bh(&rx_priv->stas_reord_lock);
//spin_unlock_bh(&rx_priv->stas_reord_lock);
} else if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
BUG();//should be not here: del_sta function
}
@@ -973,6 +1101,9 @@ static inline int rwnx_rx_sm_external_auth_required_ind(struct rwnx_hw *rwnx_hw,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL)
struct net_device *dev = rwnx_vif->ndev;
struct cfg80211_external_auth_params params;
int ret = 0;
struct wireless_dev *wdev = dev->ieee80211_ptr;
int retry_counter = 10;
RWNX_DBG(RWNX_FN_ENTRY_STR);
@@ -983,11 +1114,28 @@ static inline int rwnx_rx_sm_external_auth_required_ind(struct rwnx_hw *rwnx_hw,
min_t(size_t, ind->ssid.length, sizeof(params.ssid.ssid)));
params.key_mgmt_suite = ind->akm;
while (wdev->conn_owner_nlportid == 0) {
AICWFDBG(LOGINFO, "%s WARNING conn_owner_nlportid = 0, msleep 100ms.\r\n", __func__);
msleep(100);
retry_counter--;
if (retry_counter == 0) {
break;
}
}
AICWFDBG(LOGINFO, "%s wdev->conn_owner_nlportid:%d \r\n", __func__, (int)wdev->conn_owner_nlportid);
if (wdev->conn_owner_nlportid != 0) {
rwnx_vif->sta.conn_owner_nlportid = wdev->conn_owner_nlportid;
} else {
AICWFDBG(LOGINFO, "%s try to recover conn_owner_nlportid\r\n", __func__);
wdev->conn_owner_nlportid = rwnx_vif->sta.conn_owner_nlportid;
}
if ((ind->vif_idx > NX_VIRT_DEV_MAX) || !rwnx_vif->up ||
(RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_STATION) ||
cfg80211_external_auth_request(dev, &params, GFP_ATOMIC)) {
wiphy_err(rwnx_hw->wiphy, "Failed to start external auth on vif %d",
ind->vif_idx);
(ret = cfg80211_external_auth_request(dev, &params, GFP_ATOMIC))) {
wiphy_err(rwnx_hw->wiphy, "Failed to start external auth on vif %d, rwnx_vif->up %d, iftype:%d, ret %d",
ind->vif_idx, rwnx_vif->up, RWNX_VIF_TYPE(rwnx_vif), ret);
rwnx_send_sm_external_auth_required_rsp(rwnx_hw, rwnx_vif,
WLAN_STATUS_UNSPECIFIED_FAILURE);
return 0;

View File

@@ -1025,7 +1025,7 @@ int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *
rf_calib_req->cal_cfg_24g = 0x0f8f;
rf_calib_req->cal_cfg_5g = 0x0f0f;
}
rf_calib_req->param_alpha = 0x0c34c008;
rf_calib_req->bt_calib_en = 0;
rf_calib_req->bt_calib_param = 0x264203;
@@ -1116,33 +1116,33 @@ int rwnx_send_set_stack_start_req(struct rwnx_hw *rwnx_hw, u8_l on, u8_l efuse_v
return error;
}
#if 0
int rwnx_send_txop_req(struct rwnx_hw *rwnx_hw, uint16_t *txop, u8_l long_nav_en, u8_l cfe_en)
int rwnx_send_set_temp_comp_req(struct rwnx_hw *rwnx_hw, struct mm_set_vendor_swconfig_cfm *cfm)
{
struct mm_set_txop_req *req;
int error;
struct mm_set_vendor_swconfig_req *req;
int ret;
/* Build the MM_SET_TXOP_REQ message */
req = rwnx_msg_zalloc(MM_SET_TXOP_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_txop_req));
RWNX_DBG(RWNX_FN_ENTRY_STR);
/* Build the TEMP_COMP_SET_REQ message */
req = rwnx_msg_zalloc(MM_SET_VENDOR_SWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_vendor_swconfig_req));
if (!req) {
printk("%s msg_alloc fail\n", __func__);
return -ENOMEM;
}
req->swconfig_id = TEMP_COMP_SET_REQ;
req->temp_comp_set_req.enable = 1;
req->temp_comp_set_req.tmr_period_ms = 15 * 1000;
if (!req) {
return -ENOMEM;
}
req->txop_bk = txop[0];
req->txop_be = txop[1];
req->txop_vi = txop[2];
req->txop_vo = txop[3];
req->long_nav_en = long_nav_en;
req->cfe_en = cfe_en;
/* Send the MM_SET_TXOP_REQ message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_TXOP_CFM, NULL);
return error;
ret = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, cfm);
if (!ret)
printk("temp_comp status: %d\n", cfm->temp_comp_set_cfm.status);
else {
printk("%s msg_fail\n", __func__);
return ret;
}
return ret;
}
#endif
int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param)
int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param, int32_t *param_out)
{
struct mm_set_acs_txop_req *req0;
struct mm_set_channel_access_req *req1;
@@ -1150,7 +1150,7 @@ int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id,
struct mm_set_cca_threshold_req *req3;
struct mm_set_bwmode_req *req4;
int error;
int error = 0;
switch (hwconfig_id)
{
@@ -1188,8 +1188,9 @@ int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id,
req1->rc_retry_cnt[0] = param[9];
req1->rc_retry_cnt[1] = param[10];
req1->rc_retry_cnt[2] = param[11];
printk("set_channel_access_req:edca[]= %x %x %x %x\nvif_idx: %x, retry_cnt: %x, rts_en: %x, long_nav_en: %x, cfe_en: %x, rc_retry_cnt: %x:%x:%x\n",
req1->edca[0], req1->edca[1], req1->edca[2], req1->edca[3], req1->vif_idx, req1->retry_cnt, req1->rts_en, req1->long_nav_en, req1->cfe_en, req1->rc_retry_cnt[0],req1->rc_retry_cnt[1], req1->rc_retry_cnt[2]);
req1->ccademod_th = param[12];
printk("set_channel_access_req:edca[]= %x %x %x %x\nvif_idx: %x, retry_cnt: %x, rts_en: %x, long_nav_en: %x, cfe_en: %x, rc_retry_cnt: %x:%x:%x, ccademod_th = %d\n",
req1->edca[0], req1->edca[1], req1->edca[2], req1->edca[3], req1->vif_idx, req1->retry_cnt, req1->rts_en, req1->long_nav_en, req1->cfe_en, req1->rc_retry_cnt[0],req1->rc_retry_cnt[1], req1->rc_retry_cnt[2], req1->ccademod_th);
/* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, req1, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL);
break;
@@ -1239,12 +1240,95 @@ int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id,
/* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, req4, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL);
break;
case CHIP_TEMP_GET_REQ:
if ((rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC) ||
(rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW))
{
struct mm_get_chip_temp_req *req;
struct mm_set_vendor_hwconfig_cfm cfm = {0,};
/* Build the CHIP_TEMP_GET_REQ message */
req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_get_chip_temp_req));
if (!req)
return -ENOMEM;
req->hwconfig_id = hwconfig_id;
/* Send the MM_SET_VENDOR_HWCONFIG_REQ message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, &cfm);
if (!error) {
if (param_out) {
param_out[0] = (int32_t)cfm.chip_temp_cfm.degree;
}
printk("get_chip_temp degree=%d\n", cfm.chip_temp_cfm.degree);
} else {
printk("get_chip_temp err=%d\n", error);
}
}
break;
default:
return -ENOMEM;
}
return error;
}
int rwnx_send_vendor_swconfig_req(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, int32_t *param_in, int32_t *param_out)
{
struct mm_set_vendor_swconfig_req *req;
struct mm_set_vendor_swconfig_cfm cfm = {0,};
int error;
req = rwnx_msg_zalloc(MM_SET_VENDOR_SWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_vendor_swconfig_req));
if (!req) {
return -ENOMEM;
}
req->swconfig_id = swconfig_id;
switch (swconfig_id)
{
case BCN_CFG_REQ:
/* Build the BCN_CFG_REQ message */
req->bcn_cfg_req.tim_bcmc_ignored_enable = (bool_l)param_in[0];
printk("bcn_cfg_req: tim_bcmc_ignd=%d\n", req->bcn_cfg_req.tim_bcmc_ignored_enable);
/* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm);
if (!error) {
param_out[0] = (int32_t)cfm.bcn_cfg_cfm.tim_bcmc_ignored_status;
printk("status=%d\n", cfm.bcn_cfg_cfm.tim_bcmc_ignored_status);
}
break;
case TEMP_COMP_SET_REQ:
/* Build the TEMP_COMP_SET_REQ message */
req->temp_comp_set_req.enable = (u8_l)param_in[0];
req->temp_comp_set_req.tmr_period_ms = (u32_l)param_in[1];
printk("temp_comp_set_req: en=%d, tmr=%x\n",
req->temp_comp_set_req.enable, req->temp_comp_set_req.tmr_period_ms);
/* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm);
if (!error) {
param_out[0] = (int32_t)cfm.temp_comp_set_cfm.status;
printk("status=%d\n", cfm.temp_comp_set_cfm.status);
}
break;
case TEMP_COMP_GET_REQ:
printk("temp_comp_get_req\n");
/* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */
error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm);
if (!error) {
param_out[0] = (int32_t)cfm.temp_comp_get_cfm.status;
param_out[1] = (int32_t)cfm.temp_comp_get_cfm.degree;
printk("status=%d, degree=%d\n",
cfm.temp_comp_get_cfm.status, cfm.temp_comp_get_cfm.degree);
}
break;
default:
error = -ENOMEM;
break;
}
return error;
}
int rwnx_send_get_fw_version_req(struct rwnx_hw *rwnx_hw, struct mm_get_fw_version_cfm *cfm)
{
@@ -1831,8 +1915,8 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par
const u8 *mac, u8 inst_nbr, struct me_sta_add_cfm *cfm)
{
struct me_sta_add_req *req;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41)
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
struct link_station_parameters *link_sta_params = &params->link_sta_params;
#else
struct station_parameters *link_sta_params = params;
@@ -1862,7 +1946,7 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par
/* Set parameters for the MM_STA_ADD_REQ message */
memcpy(&(req->mac_addr.array[0]), mac, ETH_ALEN);
req->rate_set.length = link_sta_params->supported_rates_len;;
req->rate_set.length = link_sta_params->supported_rates_len;
for (i = 0; i < link_sta_params->supported_rates_len; i++)
req->rate_set.array[i] = link_sta_params->supported_rates[i];
@@ -2205,15 +2289,19 @@ int rwnx_send_sm_connect_req(struct rwnx_hw *rwnx_hw,
rwnx_vif->last_auth_type = sme->auth_type;
}
rwnx_vif->sta.ssid_len = (int)sme->ssid_len;
memset(rwnx_vif->sta.ssid, 0, rwnx_vif->sta.ssid_len + 1);
memcpy(rwnx_vif->sta.ssid, sme->ssid, rwnx_vif->sta.ssid_len);
memcpy(rwnx_vif->sta.bssid, sme->bssid, ETH_ALEN);
printk("%s drv_vif_index:%d connect to %s(%d) channel:%d auth_type:%d\r\n",
__func__,
rwnx_vif->drv_vif_index,
sme->ssid,
(int)sme->ssid_len,
rwnx_vif->sta.ssid,
rwnx_vif->sta.ssid_len,
req->chan.freq,
req->auth_type);
/* Send the SM_CONNECT_REQ message to LMAC FW */
return rwnx_send_msg(rwnx_hw, req, 1, SM_CONNECT_CFM, cfm);
@@ -2493,7 +2581,7 @@ int rwnx_send_scanu_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
if (rwnx_vif->is_p2p_vif && !rwnx_hw->is_p2p_alive) {
#else
if (rwnx_vif == rwnx_hw->p2p_dev_vif && !rwnx_vif->up) {
#endif
#endif
err = rwnx_send_add_if (rwnx_hw, rwnx_vif->wdev.address,
RWNX_VIF_TYPE(rwnx_vif), false, &add_if_cfm);
if (err)

View File

@@ -166,7 +166,9 @@ int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_
int rwnx_send_set_stack_start_req(struct rwnx_hw *rwnx_hw, u8_l on, u8_l efuse_valid, u8_l set_vendor_info,
u8_l fwtrace_redir_en, struct mm_set_stack_start_cfm *cfm);
int rwnx_send_txop_req(struct rwnx_hw *rwnx_hw, uint16_t *txop, u8_l long_nav_en, u8_l cfe_en);
int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param);
int rwnx_send_set_temp_comp_req(struct rwnx_hw *rwnx_hw, struct mm_set_vendor_swconfig_cfm *cfm);
int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param, int32_t *param_out);
int rwnx_send_vendor_swconfig_req(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, int32_t *param_in, int32_t *param_out);
int rwnx_send_get_fw_version_req(struct rwnx_hw *rwnx_hw, struct mm_get_fw_version_cfm *cfm);
int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw);
int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw);

View File

@@ -33,6 +33,9 @@
#endif
#define RWNX_FCU_FW_NAME "fcuram.bin"
#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
#define FW_DPDRESULT_NAME_8800DC "aic_dpdresult_lite_8800dc.bin"
#endif
/**
* Type of memory to access (cf rwnx_plat.get_address)

View File

@@ -410,6 +410,11 @@ static void rwnx_rx_data_skb_forward(struct rwnx_hw *rwnx_hw, struct rwnx_vif *r
rx_skb->protocol = eth_type_trans(rx_skb, rwnx_vif->ndev);
memset(rx_skb->cb, 0, sizeof(rx_skb->cb));
REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_IEEE80211RX);
#ifdef CONFIG_FILTER_TCP_ACK
filter_rx_tcp_ack(rwnx_hw,rx_skb->data, cpu_to_le16(rx_skb->len));
#endif
#ifdef CONFIG_RX_NETIF_RECV_SKB //modify by aic
local_bh_disable();
netif_receive_skb(rx_skb);
@@ -445,6 +450,7 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
struct sk_buff_head list;
struct sk_buff *rx_skb;
bool amsdu = rxhdr->flags_is_amsdu;
u8 flags_dst_idx = rxhdr->flags_dst_idx;
bool resend = false, forward = true;
skb->dev = rwnx_vif->ndev;
@@ -452,6 +458,9 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
__skb_queue_head_init(&list);
if (amsdu) {
#if 1
rwnx_rxdata_process_amsdu(rwnx_hw, skb, rxhdr->flags_vif_idx, &list); //rxhdr not used below since skb free!
#else
int count;
ieee80211_amsdu_to_8023s(skb, &list, rwnx_vif->ndev->dev_addr,
RWNX_VIF_TYPE(rwnx_vif), 0, NULL, NULL);
@@ -460,6 +469,7 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
if (count > ARRAY_SIZE(rwnx_hw->stats.amsdus_rx))
count = ARRAY_SIZE(rwnx_hw->stats.amsdus_rx);
rwnx_hw->stats.amsdus_rx[count - 1]++;
#endif
} else {
rwnx_hw->stats.amsdus_rx[0]++;
__skb_queue_head(&list, skb);
@@ -481,8 +491,8 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
} else {
/* unicast pkt for STA inside the BSS, no need to forward to upper
layer simply resend on wireless interface */
if (rxhdr->flags_dst_idx != RWNX_INVALID_STA) {
struct rwnx_sta *sta = &rwnx_hw->sta_table[rxhdr->flags_dst_idx];
if (flags_dst_idx != RWNX_INVALID_STA) {
struct rwnx_sta *sta = &rwnx_hw->sta_table[flags_dst_idx];
if (sta->valid && (sta->vlan_idx == rwnx_vif->vif_index)) {
forward = false;
resend = true;
@@ -498,7 +508,7 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
if (!is_multicast_ether_addr(eth->h_dest)) {
/* unicast pkt for STA inside the BSS, no need to forward to upper
layer simply resend on wireless interface */
if (rxhdr->flags_dst_idx != RWNX_INVALID_STA) {
if (flags_dst_idx != RWNX_INVALID_STA) {
forward = false;
resend = true;
}
@@ -577,6 +587,11 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
#endif
memset(rx_skb->cb, 0, sizeof(rx_skb->cb));
REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_IEEE80211RX);
#ifdef CONFIG_FILTER_TCP_ACK
filter_rx_tcp_ack(rwnx_hw,rx_skb->data, cpu_to_le16(rx_skb->len));
#endif
#ifdef CONFIG_RX_NETIF_RECV_SKB //modify by aic
local_bh_disable();
netif_receive_skb(rx_skb);
@@ -707,23 +722,48 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
if ((RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_MESH_POINT) &&
hw_rxhdr->flags_new_peer) {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0))
#ifdef CONFIG_GKI
rwnx_cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa,
mgmt->u.beacon.variable,
skb->len - offsetof(struct ieee80211_mgmt,
u.beacon.variable),
GFP_ATOMIC);
#else
cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa,
mgmt->u.beacon.variable,
skb->len - offsetof(struct ieee80211_mgmt,
u.beacon.variable),
GFP_ATOMIC);
#endif
#else
#ifdef CONFIG_GKI
/* TODO: the value of parameter sig_dbm need to be confirmed */
rwnx_cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa,
mgmt->u.beacon.variable,
skb->len - offsetof(struct ieee80211_mgmt,
u.beacon.variable),
rxvect->rssi1, GFP_ATOMIC);
#else
/* TODO: the value of parameter sig_dbm need to be confirmed */
cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa,
mgmt->u.beacon.variable,
skb->len - offsetof(struct ieee80211_mgmt,
u.beacon.variable),
rxvect->rssi1, GFP_ATOMIC);
#endif
#endif
} else {
#ifdef CONFIG_GKI
rwnx_cfg80211_report_obss_beacon(rwnx_hw->wiphy, skb->data, skb->len,
hw_rxhdr->phy_info.phy_prim20_freq,
rxvect->rssi1);
#else
cfg80211_report_obss_beacon(rwnx_hw->wiphy, skb->data, skb->len,
hw_rxhdr->phy_info.phy_prim20_freq,
rxvect->rssi1);
#endif
}
} else if ((ieee80211_is_deauth(mgmt->frame_control) ||
ieee80211_is_disassoc(mgmt->frame_control)) &&
@@ -1212,7 +1252,11 @@ static int rwnx_rx_monitor(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
skb->ip_summed = CHECKSUM_UNNECESSARY;
skb->pkt_type = PACKET_OTHERHOST;
skb->protocol = htons(ETH_P_802_2);
#ifdef CONFIG_FILTER_TCP_ACK
filter_rx_tcp_ack(rwnx_hw,skb->data, cpu_to_le16(skb->len));
#endif
local_bh_disable();
netif_receive_skb(skb);
local_bh_enable();
@@ -1426,6 +1470,8 @@ int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prfr
struct list_head *rxframes_freequeue = NULL;
struct sk_buff *skb = NULL;
struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif;
struct sk_buff_head list;
struct sk_buff *rx_skb;
rxframes_freequeue = &rx_priv->rxframes_freequeue;
skb = prframe->pkt;
@@ -1468,49 +1514,64 @@ int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prfr
return 0;
}
skb->data = prframe->rx_data;
skb_set_tail_pointer(skb, prframe->len);
skb->len = prframe->len;
//skb->data = prframe->rx_data;
//skb_set_tail_pointer(skb, prframe->len);
//skb->len = prframe->len;
__skb_queue_head_init(&list);
//printk("sg:%d\n", prframe->is_amsdu);
if(prframe->is_amsdu) {
rwnx_rxdata_process_amsdu(rwnx_vif->rwnx_hw, skb, rwnx_vif->vif_index, &list); //rxhdr not used below since skb free!
} else {
__skb_queue_head(&list, skb);
}
rwnx_vif->net_stats.rx_packets++;
rwnx_vif->net_stats.rx_bytes += skb->len;
//printk("netif sn=%d, len=%d\n", precv_frame->attrib.seq_num, skb->len);
skb->dev = rwnx_vif->ndev;
skb->protocol = eth_type_trans(skb, rwnx_vif->ndev);
while (!skb_queue_empty(&list)) {
rx_skb = __skb_dequeue(&list);
rwnx_vif->net_stats.rx_packets++;
rwnx_vif->net_stats.rx_bytes += rx_skb->len;
//printk("netif sn=%d, len=%d\n", precv_frame->attrib.seq_num, skb->len);
rx_skb->dev = rwnx_vif->ndev;
rx_skb->protocol = eth_type_trans(rx_skb, rwnx_vif->ndev);
#ifdef AICWF_ARP_OFFLOAD
if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) {
arpoffload_proc(skb, rwnx_vif);
}
if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) {
arpoffload_proc(rx_skb, rwnx_vif);
}
#endif
memset(rx_skb->cb, 0, sizeof(rx_skb->cb));
#ifdef CONFIG_FILTER_TCP_ACK
filter_rx_tcp_ack(rwnx_vif->rwnx_hw,rx_skb->data, cpu_to_le16(skb->len));
#endif
memset(skb->cb, 0, sizeof(skb->cb));
#ifdef CONFIG_RX_NETIF_RECV_SKB//AIDEN test
local_bh_disable();
netif_receive_skb(skb);
local_bh_enable();
local_bh_disable();
netif_receive_skb(rx_skb);
local_bh_enable();
#else
if (in_interrupt()) {
netif_rx(skb);
} else {
/*
* If the receive is not processed inside an ISR, the softirqd must be woken explicitly to service the NET_RX_SOFTIRQ.
* * In 2.6 kernels, this is handledby netif_rx_ni(), but in earlier kernels, we need to do it manually.
*/
if (in_interrupt()) {
netif_rx(rx_skb);
} else {
/*
* If the receive is not processed inside an ISR, the softirqd must be woken explicitly to service the NET_RX_SOFTIRQ.
* * In 2.6 kernels, this is handledby netif_rx_ni(), but in earlier kernels, we need to do it manually.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
netif_rx_ni(skb);
netif_rx_ni(rx_skb);
#else
ulong flags;
netif_rx(skb);
local_irq_save(flags);
RAISE_RX_SOFTIRQ();
local_irq_restore(flags);
ulong flags;
netif_rx(rx_skb);
local_irq_save(flags);
RAISE_RX_SOFTIRQ();
local_irq_restore(flags);
#endif
}
#endif /* CONFIG_RX_NETIF_RECV_SKB */
}
#endif//CONFIG_RX_NETIF_RECV_SKB
//rwnx_vif->net_stats.rx_packets++;
//rwnx_vif->net_stats.rx_bytes += skb->len;
prframe->pkt = NULL;
reord_rxframe_free(&rx_priv->freeq_lock, rxframes_freequeue, &prframe->rxframe_list);
@@ -1627,7 +1688,7 @@ void reord_timeout_worker(struct work_struct *work)
return ;
}
int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 seq_num, u8 tid, u8 forward)
int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 seq_num, u8 tid, u8 forward, u8 is_amsdu)
{
int ret = 0;
u8 *mac;
@@ -1654,10 +1715,11 @@ int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 s
pframe->seq_num = seq_num;
pframe->tid = tid;
pframe->rx_data = skb->data;
pframe->len = skb->len;
//pframe->len = skb->len;
pframe->pkt = skb;
pframe->forward = forward;
preorder_ctrl = pframe->preorder_ctrl;
pframe->is_amsdu = is_amsdu;
if ((ntohs(eh->h_proto) == ETH_P_PAE) || is_mcast)
return reord_single_frame_ind(rx_priv, pframe);
@@ -1709,23 +1771,26 @@ int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 s
spin_lock_bh(&preorder_ctrl->reord_list_lock);
if (reord_need_check(preorder_ctrl, pframe->seq_num)) {
if(pframe->rx_data[42] == 0x80){//this is rtp package
if(pframe->seq_num == preorder_ctrl->ind_sn){
//printk("%s pframe->seq_num1:%d \r\n", __func__, pframe->seq_num);
reord_single_frame_ind(rx_priv, pframe);//not need to reorder
}else{
printk("%s free pframe->seq_num:%d \r\n", __func__, pframe->seq_num);
if (pframe->pkt){
dev_kfree_skb(pframe->pkt);
pframe->pkt = NULL;
}
reord_rxframe_free(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue, &pframe->rxframe_list);
}
}else{
//printk("%s pframe->seq_num2:%d \r\n", __func__, pframe->seq_num);
reord_single_frame_ind(rx_priv, pframe);//not need to reorder
}
#if 0
if(pframe->rx_data[42] == 0x80){//this is rtp package
if(pframe->seq_num == preorder_ctrl->ind_sn){
printk("%s pframe->seq_num1:%d \r\n", __func__, pframe->seq_num);
reord_single_frame_ind(rx_priv, pframe);//not need to reorder
}else{
printk("%s free pframe->seq_num:%d \r\n", __func__, pframe->seq_num);
if (pframe->pkt){
dev_kfree_skb(pframe->pkt);
pframe->pkt = NULL;
}
reord_rxframe_free(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue, &pframe->rxframe_list);
}
}else{
//printk("%s pframe->seq_num2:%d \r\n", __func__, pframe->seq_num);
reord_single_frame_ind(rx_priv, pframe);//not need to reorder
}
#else
reord_single_frame_ind(rx_priv, pframe);//not need to reor
#endif
spin_unlock_bh(&preorder_ctrl->reord_list_lock);
return 0;
}
@@ -1851,6 +1916,65 @@ void defrag_timeout_cb(struct timer_list *t)
spin_unlock_bh(&defrag_ctrl->rwnx_hw->defrag_lock);
}
void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx,
struct sk_buff_head *list)
{
u16 len_alligned = 0;
u16 sublen = 0;
struct sk_buff *sub_skb = NULL;
struct rwnx_vif *rwnx_vif;
//if (is_amsdu)
{
//skb_pull(skb, pull_len-8);
/* |amsdu sub1 | amsdu sub2 | ... */
len_alligned = 0;
sublen = 0;
sub_skb = NULL;
while (skb->len > 16) {
sublen = (skb->data[12]<<8)|(skb->data[13]);
if (skb->len > (sublen+14))
len_alligned = roundup(sublen + 14, 4);
else if (skb->len == (sublen+14))
len_alligned = sublen+14;
else {
printk("accroding to amsdu: this will not happen\n");
break;
}
//printk("sublen = %d, %x, %x, %x, %x\r\n", sublen,skb->data[0], skb->data[1], skb->data[12], skb->data[13]);
#if 1
sub_skb = __dev_alloc_skb(sublen - 6 + 12, GFP_KERNEL);
if(!sub_skb){
printk("sub_skb alloc fail:%d\n", sublen);
break;
}
skb_put(sub_skb, sublen - 6 + 12);
memcpy(sub_skb->data, skb->data, MAC_ADDR_LEN);
memcpy(&sub_skb->data[6], &skb->data[6], MAC_ADDR_LEN);
memcpy(&sub_skb->data[12], &skb->data[14 + 6], sublen - 6);
rwnx_vif = rwnx_rx_get_vif(rwnx_hw, vif_idx);
if (!rwnx_vif) {
printk("Frame received but no active vif (%d)", vif_idx);
//dev_kfree_skb(sub_skb);
break;
}
__skb_queue_tail(list, sub_skb);
//printk("a:%p\n", sub_skb);
//if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, sub_skb, hw_rxhdr))
// dev_kfree_skb(sub_skb);
#endif
skb_pull(skb, len_alligned);
}
//printk("af:%p\n", skb);
dev_kfree_skb(skb);
//return 0;
}
}
u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
{
struct hw_rxhdr *hw_rxhdr;
@@ -1877,9 +2001,6 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
u8 sta_idx = 0;
u16_l frame_ctrl;
u8 is_amsdu = 0;
u16 len_alligned = 0;
u16 sublen = 0;
struct sk_buff *sub_skb = NULL;
bool resend = false, forward = true;
const struct ethhdr *eth;
@@ -2000,7 +2121,11 @@ check_len_update:
hdr = (struct ieee80211_hdr *)(skb->data + msdu_offset);
rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx);
if (rwnx_vif) {
#ifdef CONFIG_GKI
rwnx_cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC);
#else
cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC);
#endif
}
goto end;
}
@@ -2063,8 +2188,15 @@ check_len_update:
memcpy(ether_type, &skb->data[hdr_len + 6], 2);
break;
}
if(is_amsdu)
hw_rxhdr->flags_is_amsdu = 1;
else
hw_rxhdr->flags_is_amsdu = 0;
if (is_amsdu) {
#if 1
skb_pull(skb, pull_len-8);
#else
skb_pull(skb, pull_len-8);
/* |amsdu sub1 | amsdu sub2 | ... */
len_alligned = 0;
@@ -2103,6 +2235,7 @@ check_len_update:
}
dev_kfree_skb(skb);
return 0;
#endif
}
if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA)
@@ -2241,7 +2374,7 @@ check_len_update:
}
}
if (!is_frag) {
if (!is_frag && !is_amsdu) {
skb_pull(skb, pull_len);
skb_push(skb, 14);
memcpy(skb->data, ra, MAC_ADDR_LEN);
@@ -2278,8 +2411,13 @@ check_len_update:
}
if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) {
#ifdef CONFIG_GKI
rwnx_cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
sta->mac_addr, GFP_ATOMIC);
#else
cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
sta->mac_addr, GFP_ATOMIC);
#endif
}
}
@@ -2291,13 +2429,13 @@ check_len_update:
if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) {
if (is_qos && hw_rxhdr->flags_need_reord)
reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1);
reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1, hw_rxhdr->flags_is_amsdu);
else if (is_qos && !hw_rxhdr->flags_need_reord) {
reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid);
if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr))
if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr) && !hw_rxhdr->flags_is_amsdu)
dev_kfree_skb(skb);
} else {
if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr))
if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr) && !hw_rxhdr->flags_is_amsdu)
dev_kfree_skb(skb);
}
} else if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
@@ -2327,7 +2465,7 @@ check_len_update:
if (forward) {
if (is_qos && hw_rxhdr->flags_need_reord)
reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1);
reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1, hw_rxhdr->flags_is_amsdu);
else if (is_qos && !hw_rxhdr->flags_need_reord) {
reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid);
rwnx_rx_data_skb_forward(rwnx_hw, rwnx_vif, skb, hw_rxhdr);
@@ -2335,7 +2473,7 @@ check_len_update:
rwnx_rx_data_skb_forward(rwnx_hw, rwnx_vif, skb, hw_rxhdr);
} else if(resend) {
if (is_qos && hw_rxhdr->flags_need_reord)
reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 0);
reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 0, hw_rxhdr->flags_is_amsdu);
else if (is_qos && !hw_rxhdr->flags_need_reord) {
reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid);
dev_kfree_skb(skb);

View File

@@ -364,6 +364,8 @@ void reord_timeout_handler (struct timer_list *t);
#endif
#endif
void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx,
struct sk_buff_head *list);
#ifdef CONFIG_HE_FOR_OLD_KERNEL
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 197)

View File

@@ -320,8 +320,11 @@ rwnx_tdls_add_oper_classes(struct rwnx_vif *rwnx_vif, struct sk_buff *skb)
chan_def.width = rwnx_vif->sta.ap->width;
chan_def.center_freq1 = rwnx_vif->sta.ap->center_freq1;
chan_def.center_freq2 = rwnx_vif->sta.ap->center_freq2;
#ifdef CONFIG_GKI
if (!rwnx_ieee80211_chandef_to_operating_class(&chan_def, &op_class))
#else
if (!ieee80211_chandef_to_operating_class(&chan_def, &op_class))
#endif
return;
pos = skb_put(skb, 4);

View File

@@ -1195,6 +1195,175 @@ int aic_br_client_tx(struct rwnx_vif *vif, struct sk_buff **pskb)
#endif /* CONFIG_BR_SUPPORT */
#ifdef CONFIG_FILTER_TCP_ACK
/* return:
* 0, msg buf freed by the real driver
* others, skb need free by the caller,remember not use msg->skb!
*/
int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg)
{
struct rwnx_vif *rwnx_vif = msg->rwnx_vif;
struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw;
struct rwnx_txhdr *txhdr;
struct rwnx_sw_txhdr *sw_txhdr;
struct txdesc_api *desc;
struct rwnx_sta *sta;
struct rwnx_txq *txq;
int headroom;
//int max_headroom;
int hdr_pads;
u16 frame_len;
u16 frame_oft;
u8 tid;
struct sk_buff *skb=msg->skb;
struct ethhdr eth_t;
move_tcpack_msg(rwnx_hw,msg);
kfree(msg);
memcpy(&eth_t, skb->data, sizeof(struct ethhdr));
/* Get the STA id and TID information */
sta = rwnx_get_tx_priv(rwnx_vif, skb, &tid);
if (!sta)
goto free;
txq = rwnx_txq_sta_get(sta, tid, rwnx_hw);
if (txq->idx == TXQ_INACTIVE)
goto free;
#ifdef CONFIG_RWNX_AMSDUS_TX
if (rwnx_amsdu_add_subframe(rwnx_hw, skb, sta, txq))
return NETDEV_TX_OK;
#endif
#ifdef CONFIG_BR_SUPPORT
if (1) {//(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) {
void *br_port = NULL;
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
br_port = rwnx_vif->ndev->br_port;
#else
rcu_read_lock();
br_port = rcu_dereference(rwnx_vif->ndev->rx_handler_data);
rcu_read_unlock();
#endif
if (br_port) {
s32 res = aic_br_client_tx(rwnx_vif, &skb);
if (res == -1) {
goto free;
}
}
}
#endif /* CONFIG_BR_SUPPORT */
/* Retrieve the pointer to the Ethernet data */
// eth = (struct ethhdr *)skb->data;
skb_pull(skb, 14);
//hdr_pads = RWNX_SWTXHDR_ALIGN_PADS((long)eth);
hdr_pads = RWNX_SWTXHDR_ALIGN_PADS((long)skb->data);
headroom = sizeof(struct rwnx_txhdr) + hdr_pads;
skb_push(skb, headroom);
txhdr = (struct rwnx_txhdr *)skb->data;
sw_txhdr = kmem_cache_alloc(rwnx_hw->sw_txhdr_cache, GFP_ATOMIC);
if (unlikely(sw_txhdr == NULL))
goto free;
txhdr->sw_hdr = sw_txhdr;
desc = &sw_txhdr->desc;
frame_len = (u16)skb->len - headroom;// - sizeof(*eth);
sw_txhdr->txq = txq;
sw_txhdr->frame_len = frame_len;
sw_txhdr->rwnx_sta = sta;
sw_txhdr->rwnx_vif = rwnx_vif;
sw_txhdr->skb = skb;
sw_txhdr->headroom = headroom;
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
#ifdef CONFIG_RWNX_AMSDUS_TX
sw_txhdr->amsdu.len = 0;
sw_txhdr->amsdu.nb = 0;
#endif
// Fill-in the descriptor
memcpy(&desc->host.eth_dest_addr, eth_t.h_dest, ETH_ALEN);
memcpy(&desc->host.eth_src_addr, eth_t.h_source, ETH_ALEN);
desc->host.ethertype = eth_t.h_proto;
desc->host.staid = sta->sta_idx;
desc->host.tid = tid;
if (unlikely(rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP_VLAN))
desc->host.vif_idx = rwnx_vif->ap_vlan.master->vif_index;
else
desc->host.vif_idx = rwnx_vif->vif_index;
if (rwnx_vif->use_4addr && (sta->sta_idx < NX_REMOTE_STA_MAX))
desc->host.flags = TXU_CNTRL_USE_4ADDR;
else
desc->host.flags = 0;
if ((rwnx_vif->tdls_status == TDLS_LINK_ACTIVE) &&
rwnx_vif->sta.tdls_sta &&
(memcmp(desc->host.eth_dest_addr.array, rwnx_vif->sta.tdls_sta->mac_addr, ETH_ALEN) == 0)) {
desc->host.flags |= TXU_CNTRL_TDLS;
rwnx_vif->sta.tdls_sta->tdls.last_tid = desc->host.tid;
//rwnx_vif->sta.tdls_sta->tdls.last_sn = desc->host.sn;
}
if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_MESH_POINT) {
if (rwnx_vif->is_resending) {
desc->host.flags |= TXU_CNTRL_MESH_FWD;
}
}
#ifdef CONFIG_RWNX_SPLIT_TX_BUF
desc->host.packet_len[0] = frame_len;
#else
desc->host.packet_len = frame_len;
#endif
txhdr->hw_hdr.cfm.status.value = 0;
if (unlikely(rwnx_prep_tx(rwnx_hw, txhdr))) {
kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr);
skb_pull(skb, headroom);
dev_kfree_skb_any(skb);
return NETDEV_TX_BUSY;
}
/* Fill-in TX descriptor */
frame_oft = sizeof(struct rwnx_txhdr) - offsetof(struct rwnx_txhdr, hw_hdr)
+ hdr_pads;// + sizeof(*eth);
#if 0
#ifdef CONFIG_RWNX_SPLIT_TX_BUF
desc->host.packet_addr[0] = sw_txhdr->dma_addr + frame_oft;
desc->host.packet_cnt = 1;
#else
desc->host.packet_addr = sw_txhdr->dma_addr + frame_oft;
#endif
#endif
desc->host.hostid = sw_txhdr->dma_addr;
spin_lock_bh(&rwnx_hw->tx_lock);
if (rwnx_txq_queue_skb(skb, txq, rwnx_hw, false))
rwnx_hwq_process(rwnx_hw, txq->hwq);
spin_unlock_bh(&rwnx_hw->tx_lock);
return 0;//NETDEV_TX_OK
free:
dev_kfree_skb_any(skb);
return 0;//NETDEV_TX_OK
}
#endif
/**
* netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb,
* struct net_device *dev);
@@ -1225,13 +1394,14 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev)
u8 tid;
struct ethhdr eth_t;
#ifdef CONFIG_FILTER_TCP_ACK
struct msg_buf *msgbuf;
#endif
#ifdef CONFIG_ONE_TXQ
skb->queue_mapping = rwnx_select_txq(rwnx_vif, skb);
#endif
memcpy(&eth_t, skb->data, sizeof(struct ethhdr));
sk_pacing_shift_update(skb->sk, rwnx_hw->tcp_pacing_shift);
max_headroom = sizeof(struct rwnx_txhdr);
@@ -1248,6 +1418,20 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb = newskb;
}
#ifdef CONFIG_FILTER_TCP_ACK
msgbuf=intf_tcp_alloc_msg(msgbuf);
msgbuf->rwnx_vif=rwnx_vif;
msgbuf->skb=skb;
if(filter_send_tcp_ack(rwnx_hw,msgbuf,skb->data,cpu_to_le16(skb->len))){
return NETDEV_TX_OK;
}else{
move_tcpack_msg(rwnx_hw,msgbuf);
kfree(msgbuf);
}
#endif
memcpy(&eth_t, skb->data, sizeof(struct ethhdr));
/* Get the STA id and TID information */
sta = rwnx_get_tx_priv(rwnx_vif, skb, &tid);
if (!sta)
@@ -1493,7 +1677,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
robust = ieee80211_is_robust_mgmt_frame((void *)skb->data);
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
/* Update CSA counter if present */
if (unlikely(params->n_csa_offsets) &&
vif->wdev.iftype == NL80211_IFTYPE_AP &&

View File

@@ -836,7 +836,11 @@ int rwnx_txq_queue_skb(struct sk_buff *skb, struct rwnx_txq *txq,
skb_queue_tail(&txq->sk_list, skb);
} else {
if (txq->last_retry_skb)
#ifdef CONFIG_GKI
rwnx_skb_append(txq->last_retry_skb, skb, &txq->sk_list);
#else
skb_append(txq->last_retry_skb, skb, &txq->sk_list);
#endif
else
skb_queue_head(&txq->sk_list, skb);
@@ -1240,6 +1244,8 @@ void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq)
BUG_ON(!(txq->status & RWNX_TXQ_IN_HWQ_LIST));
if(txq->idx == TXQ_INACTIVE){
printk("%s txq->idx == TXQ_INACTIVE \r\n", __func__);
rwnx_txq_del_from_hw_list(txq);
rwnx_txq_flush(rwnx_hw, txq);
continue;
}
BUG_ON(txq->idx == TXQ_INACTIVE);

View File

@@ -129,7 +129,7 @@ int rwnx_v7_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_plat)
pci_read_config_word(pci_dev, PCI_COMMAND, &pci_cmd);
pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
pci_write_config_word(pci_dev, PCI_COMMAND, pci_cmd);
pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2);
//pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2);
ret = pci_enable_device(pci_dev);
if (ret) {
@@ -139,12 +139,13 @@ int rwnx_v7_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_plat)
pci_set_master(pci_dev);
#if 0
ret = pci_request_regions(pci_dev, KBUILD_MODNAME);
if (ret) {
dev_err(&(pci_dev->dev), "pci_request_regions failed\n");
goto out_request;
}
#endif
#ifdef CONFIG_PCI
if (pci_enable_msi(pci_dev)) {
dev_err(&(pci_dev->dev), "pci_enable_msi failed\n");
@@ -183,7 +184,7 @@ out_bar0:
out_msi:
#endif
pci_release_regions(pci_dev);
out_request:
//out_request:
#ifdef CONFIG_PCI
pci_clear_master(pci_dev);
#endif

View File

@@ -1,4 +1,4 @@
#define RWNX_VERS_REV "241c091M (master)"
#define RWNX_VERS_MOD "6.4.3.0"
#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - - 241c091M (master)"
#define RELEASE_DATE "2023_0904_1725"
#define RELEASE_DATE "2023_1212_15dcf017"

View File

@@ -27,19 +27,23 @@ void rwnx_wakeup_deinit(struct wakeup_source *ws)
struct wakeup_source *rwnx_wakeup_register(struct device *dev, const char *name)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
return wakeup_source_register(dev, name);
#else
#ifdef CONFIG_PLATFORM_ROCKCHIP
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
#if defined(CONFIG_PLATFORM_ROCKCHIP2) || defined(CONFIG_PLATFORM_ROCKCHIP)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
return wakeup_source_register(dev, name);
#else
return wakeup_source_register(name);
#endif
#else
return wakeup_source_register(name);
#endif//CONFIG_PLATFORM_ROCKCHIP
#endif
#endif//#if defined(CONFIG_PLATFORM_ROCKCHIP2) || defined(CONFIG_PLATFORM_ROCKCHIP)
#endif//LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
}
void rwnx_wakeup_unregister(struct wakeup_source *ws)