From: Lu Hui Date: Mon, 25 Dec 2023 03:07:25 +0000 (+0800) Subject: drivers: aic8800: upgrade to 20231212 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c7445d78a38dae6120bc3fc78630a5b068983e27;p=platform%2Fkernel%2Flinux-thead.git drivers: aic8800: upgrade to 20231212 (cherry picked from commit 1fd93bc1a9b6fa6ffa509f20b9d0f85389cedf54) Signed-off-by: Jaehoon Chung --- diff --git a/drivers/net/wireless/aic8800/Makefile b/drivers/net/wireless/aic8800/Makefile index 090095862cc0..e410cafee48d 100644 --- a/drivers/net/wireless/aic8800/Makefile +++ b/drivers/net/wireless/aic8800/Makefile @@ -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 diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/.gitignore b/drivers/net/wireless/aic8800/aic8800_bsp/.gitignore new file mode 100644 index 000000000000..c3c2d151e157 --- /dev/null +++ b/drivers/net/wireless/aic8800/aic8800_bsp/.gitignore @@ -0,0 +1,10 @@ +*.o +*.ko +*.order +*.symvers +*.o.d +*.o.cmd +*.ko.cmd +*.mod +*.mod.c +*.mod.cmd diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/Makefile b/drivers/net/wireless/aic8800/aic8800_bsp/Makefile index b311153cba8e..632435a6b566 100644 --- a/drivers/net/wireless/aic8800/aic8800_bsp/Makefile +++ b/drivers/net/wireless/aic8800/aic8800_bsp/Makefile @@ -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/ diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/aic8800d80_compat.c b/drivers/net/wireless/aic8800/aic8800_bsp/aic8800d80_compat.c index bf34109dbd13..edc85f2b62d5 100644 --- a/drivers/net/wireless/aic8800/aic8800_bsp/aic8800d80_compat.c +++ b/drivers/net/wireless/aic8800/aic8800_bsp/aic8800d80_compat.c @@ -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; } diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/aic8800dc_compat.c b/drivers/net/wireless/aic8800/aic8800_bsp/aic8800dc_compat.c index 4ef066ddeca0..2bbb087ba3da 100644 --- a/drivers/net/wireless/aic8800/aic8800_bsp/aic8800dc_compat.c +++ b/drivers/net/wireless/aic8800/aic8800_bsp/aic8800dc_compat.c @@ -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, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); + return ret; + } + 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, "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->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 diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/aic8800dc_compat.h b/drivers/net/wireless/aic8800/aic8800_bsp/aic8800dc_compat.h index 09f303bc0602..67074cecfc5f 100644 --- a/drivers/net/wireless/aic8800/aic8800_bsp/aic8800dc_compat.h +++ b/drivers/net/wireless/aic8800/aic8800_bsp/aic8800dc_compat.h @@ -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 diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_driver.c b/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_driver.c index 4b02d68ce26e..5d7e6bbb3968 100644 --- a/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_driver.c +++ b/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_driver.c @@ -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; - - 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); - } - if (AICBT_PT_VER == p->type) { - printk("aicbsp: bt patch version: %s\n", (char *)p->data); - continue; - } + 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; + + *(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; + + 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); + } + + 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); + } - 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; - - *(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; - - 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}, }; diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_driver.h b/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_driver.h index 6f010b1d3a3f..810ed8e4dbef 100644 --- a/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_driver.h +++ b/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_driver.h @@ -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[]; diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_export.h b/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_export.h index 535f7bf0e1cd..249d6ec082ea 100644 --- a/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_export.h +++ b/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_export.h @@ -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); diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_main.c b/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_main.c index cf2c3a7d9fa6..5e144c8c1169 100644 --- a/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_main.c +++ b/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_main.c @@ -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; diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/aicsdio.c b/drivers/net/wireless/aic8800/aic8800_bsp/aicsdio.c index 2e50ac995947..c27e61a8717a 100644 --- a/drivers/net/wireless/aic8800/aic8800_bsp/aicsdio.c +++ b/drivers/net/wireless/aic8800/aic8800_bsp/aicsdio.c @@ -23,6 +23,9 @@ #ifdef CONFIG_PLATFORM_ROCKCHIP #include #endif /* CONFIG_PLATFORM_ROCKCHIP */ +#ifdef CONFIG_PLATFORM_ROCKCHIP2 +#include +#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; diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/aicwf_txq_prealloc.c b/drivers/net/wireless/aic8800/aic8800_bsp/aicwf_txq_prealloc.c index fc098af5baef..9514c416b5d6 100644 --- a/drivers/net/wireless/aic8800/aic8800_bsp/aicwf_txq_prealloc.c +++ b/drivers/net/wireless/aic8800/aic8800_bsp/aicwf_txq_prealloc.c @@ -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) { diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/rwnx_version_gen.h b/drivers/net/wireless/aic8800/aic8800_bsp/rwnx_version_gen.h index 668212830fca..e2d038e8802e 100644 --- a/drivers/net/wireless/aic8800/aic8800_bsp/rwnx_version_gen.h +++ b/drivers/net/wireless/aic8800/aic8800_bsp/rwnx_version_gen.h @@ -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" diff --git a/drivers/net/wireless/aic8800/aic8800_btlpm/.gitignore b/drivers/net/wireless/aic8800/aic8800_btlpm/.gitignore new file mode 100644 index 000000000000..c3c2d151e157 --- /dev/null +++ b/drivers/net/wireless/aic8800/aic8800_btlpm/.gitignore @@ -0,0 +1,10 @@ +*.o +*.ko +*.order +*.symvers +*.o.d +*.o.cmd +*.ko.cmd +*.mod +*.mod.c +*.mod.cmd diff --git a/drivers/net/wireless/aic8800/aic8800_btlpm/Makefile b/drivers/net/wireless/aic8800/aic8800_btlpm/Makefile index 028d2dc8abd3..cd63d62b98d2 100644 --- a/drivers/net/wireless/aic8800/aic8800_btlpm/Makefile +++ b/drivers/net/wireless/aic8800/aic8800_btlpm/Makefile @@ -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/ diff --git a/drivers/net/wireless/aic8800/aic8800_btlpm/aic8800_btlpm.c b/drivers/net/wireless/aic8800/aic8800_btlpm/aic8800_btlpm.c index f69937c8e16e..52d768d83da8 100644 --- a/drivers/net/wireless/aic8800/aic8800_btlpm/aic8800_btlpm.c +++ b/drivers/net/wireless/aic8800/aic8800_btlpm/aic8800_btlpm.c @@ -44,6 +44,8 @@ #include #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, }, }; diff --git a/drivers/net/wireless/aic8800/aic8800_btlpm/aic_bluetooth_main.c b/drivers/net/wireless/aic8800/aic8800_btlpm/aic_bluetooth_main.c index 603f67e9a815..122d867f0ed6 100644 --- a/drivers/net/wireless/aic8800/aic8800_btlpm/aic_bluetooth_main.c +++ b/drivers/net/wireless/aic8800/aic8800_btlpm/aic_bluetooth_main.c @@ -5,7 +5,7 @@ #include #include #include -//#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); diff --git a/drivers/net/wireless/aic8800/aic8800_btlpm/aic_bsp_export.h b/drivers/net/wireless/aic8800/aic8800_btlpm/aic_bsp_export.h index 0c4b588d85c6..88f6b565cd5f 100644 --- a/drivers/net/wireless/aic8800/aic8800_btlpm/aic_bsp_export.h +++ b/drivers/net/wireless/aic8800/aic8800_btlpm/aic_bsp_export.h @@ -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); diff --git a/drivers/net/wireless/aic8800/aic8800_btlpm/lpm.c b/drivers/net/wireless/aic8800/aic8800_btlpm/lpm.c index 26195f472c69..6e9b71564f19 100644 --- a/drivers/net/wireless/aic8800/aic8800_btlpm/lpm.c +++ b/drivers/net/wireless/aic8800/aic8800_btlpm/lpm.c @@ -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); diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/.gitignore b/drivers/net/wireless/aic8800/aic8800_fdrv/.gitignore new file mode 100644 index 000000000000..c3c2d151e157 --- /dev/null +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/.gitignore @@ -0,0 +1,10 @@ +*.o +*.ko +*.order +*.symvers +*.o.d +*.o.cmd +*.ko.cmd +*.mod +*.mod.c +*.mod.cmd diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/Makefile b/drivers/net/wireless/aic8800/aic8800_fdrv/Makefile index 623643e64198..74957daef8d0 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/Makefile +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/Makefile @@ -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 diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/aic_bsp_export.h b/drivers/net/wireless/aic8800/aic8800_fdrv/aic_bsp_export.h index adf8f55ec187..bd806fad5935 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/aic_bsp_export.h +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/aic_bsp_export.h @@ -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); diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/aic_vendor.c b/drivers/net/wireless/aic8800/aic8800_fdrv/aic_vendor.c index 6e8469d64542..0cc6d5a392b5 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/aic_vendor.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/aic_vendor.c @@ -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, diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c index 337fe6266409..f817fc0428df 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c @@ -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){ diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h index 7b591dbf54b8..249703b68389 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h @@ -1,7 +1,11 @@ #include +#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); diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_sdio.c b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_sdio.c index 66fc7e528130..53c9710dd690 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_sdio.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_sdio.c @@ -34,6 +34,10 @@ #ifdef CONFIG_PLATFORM_ROCKCHIP #include #endif +#ifdef CONFIG_PLATFORM_ROCKCHIP2 +#include +#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); diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.c b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.c new file mode 100644 index 000000000000..6d766bc75c10 --- /dev/null +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.c @@ -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); + } +} + diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.h b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.h new file mode 100644 index 000000000000..ff7f11d9103d --- /dev/null +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.h @@ -0,0 +1,111 @@ +#ifndef _AICWF_TCP_ACK_H_ +#define _AICWF_TCP_ACK_H_ + +#include +#include +#include +#include +#include +#include +#include + + +#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 diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.c b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.c index 7f8c7d924b93..47613d7c6cca 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.c @@ -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 diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.h b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.h index 393fb5dcc844..2a06442799b2 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.h +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.h @@ -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; diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/lmac_msg.h b/drivers/net/wireless/aic8800/aic8800_fdrv/lmac_msg.h index 81740182e3f8..061248c1015d 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/lmac_msg.h +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/lmac_msg.h @@ -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 diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_compat.h b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_compat.h index 000874b67825..9287eca607f8 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_compat.h +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_compat.h @@ -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, 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(5, 15, 0) -#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE + +#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) diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_debugfs.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_debugfs.c index e04bbbb1076f..f4594f4bcc1d 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_debugfs.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_debugfs.c @@ -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 { diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_defs.h b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_defs.h index 7c49f3aeee92..4e966dee2fad 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_defs.h +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_defs.h @@ -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; diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_dini.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_dini.c index 6e5bdea0269a..17d55da1156f 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_dini.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_dini.c @@ -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); diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_gki.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_gki.c index ad6c52d46f3e..7f6333d91e59 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_gki.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_gki.c @@ -2,12 +2,12 @@ #ifdef ANDROID_PLATFORM #include "net/wireless/core.h" #endif - +#include #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; diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_gki.h b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_gki.h index 6a8fb3ef7335..a41f57832279 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_gki.h +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_gki.h @@ -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, diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_main.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_main.c index ca33d79c0990..e364ba595495 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_main.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_main.c @@ -22,6 +22,7 @@ #include #include #include +#include #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 -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 94) - , 0 + 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 - ); - + } 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 #endif +#ifdef CONFIG_PLATFORM_ROCKCHIP2 +#include +#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); } diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_mod_params.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_mod_params.c index 30f369f0c5ec..4aa6eba9c51b 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_mod_params.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_mod_params.c @@ -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] |= diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_rx.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_rx.c index eb07e7cced56..662fb9378dff 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_rx.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_rx.c @@ -9,6 +9,7 @@ * **************************************************************************************** */ +#include #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, ¶ms, GFP_ATOMIC)) { - wiphy_err(rwnx_hw->wiphy, "Failed to start external auth on vif %d", - ind->vif_idx); + (ret = cfg80211_external_auth_request(dev, ¶ms, 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; diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_tx.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_tx.c index 71f25884147b..054afeb7a5c3 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_tx.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_tx.c @@ -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; - - /* 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)); - - if (!req) { - return -ENOMEM; - } + struct mm_set_vendor_swconfig_req *req; + int ret; - 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); + 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; - 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 = ¶ms->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) diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_tx.h b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_tx.h index 99f1017ca756..a3890fe2b26d 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_tx.h +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_tx.h @@ -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); diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_platform.h b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_platform.h index e5e8475eb0b0..9250612349d3 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_platform.h +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_platform.h @@ -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) diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_rx.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_rx.c index 5f650bc8fb48..02641e41bd32 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_rx.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_rx.c @@ -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); diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_rx.h b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_rx.h index a068083afc8a..36635350314b 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_rx.h +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_rx.h @@ -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) diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_tdls.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_tdls.c index 90cfdfd41cb1..34196edac508 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_tdls.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_tdls.c @@ -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); diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_tx.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_tx.c index 096d7ffe4022..7be91e061cf3 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_tx.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_tx.c @@ -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(ð_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(ð_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(ð_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 && diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_txq.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_txq.c index a0fd7a0f3173..a776e31e9a09 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_txq.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_txq.c @@ -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); diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_v7.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_v7.c index 21e907ccf902..72e3c850b48e 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_v7.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_v7.c @@ -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 diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_version_gen.h b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_version_gen.h index 6983ac8d5de5..e2d038e8802e 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_version_gen.h +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_version_gen.h @@ -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" diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_wakelock.c b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_wakelock.c index 4f9b7ca23fd8..69bcf3f5d784 100644 --- a/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_wakelock.c +++ b/drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_wakelock.c @@ -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)