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
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
--- /dev/null
+*.o
+*.ko
+*.order
+*.symvers
+*.o.d
+*.o.cmd
+*.ko.cmd
+*.mod
+*.mod.c
+*.mod.cmd
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
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
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 := \
# Platform support list
CONFIG_PLATFORM_ROCKCHIP ?= n
+CONFIG_PLATFORM_ROCKCHIP2 ?= n
CONFIG_PLATFORM_ALLWINNER ?=n
CONFIG_PLATFORM_INGENIC_T20 ?= n
CONFIG_PLATFORM_AMLOGIC ?= n
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/
#else
{0x00b4, 0xf3010000},
#endif
+#if defined(CONFIG_AMSDU_RX)
+ {0x170, 0x0100000a}
+#endif
+#if AIC_IRQ_WAKE_FLAG
+ {0x00000170, 0x0000010a}, //irqf
+#endif
};
#ifdef CONFIG_OOB
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;
}
0x00ffcc85,
0x00ffcd70,
0x00ffcd80,
- 0x00ffce70,
+ 0x00ffcd90,
0x00ffce80,
0x00ffce93,
0x00ffcf90,
#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] =
{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)
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);
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;
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 {
}
#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
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) {
}
#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);
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) {
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");
return 0;
}
+#endif /* !CONFIG_FORCE_DPD_CALIB */
#endif
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);
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
#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;
}
extern char aic_fw_path[200];
-extern int testmode;
int aicwf_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev)
{
int ret = 0;
} 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);
}
}
#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;
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;
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)
{
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);
#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) {
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
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) {
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;
}
-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)
{
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;
}
{
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;
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;
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);
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){
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);
}
}
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},
};
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,
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
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);
#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"
#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"
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
#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°
uint32_t cpmode;
uint32_t chip_rev;
bool fwlog_en;
+ uint8_t irqf;
};
extern struct aicbsp_info_t aicbsp_info;
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[];
#ifndef __AIC_BSP_EXPORT_H
#define __AIC_BSP_EXPORT_H
-#define AICBSP_RESV_MEM_SUPPORT 0
-
enum aicbsp_subsys {
AIC_BLUETOOTH,
AIC_WIFI,
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);
},
};
+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)",
.hwinfo = AICBSP_HWINFO_DEFAULT,
.cpmode = AICBSP_CPMODE_DEFAULT,
.fwlog_en = AICBSP_FWLOG_EN_DEFAULT,
+ .irqf = AIC_IRQ_WAKE_FLAG,
};
struct mutex aicbsp_power_lock;
#ifdef CONFIG_PLATFORM_ROCKCHIP
#include <linux/rfkill-wlan.h>
#endif /* CONFIG_PLATFORM_ROCKCHIP */
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+#include <linux/rfkill-wlan.h>
+#endif /* CONFIG_PLATFORM_ROCKCHIP */
#ifdef CONFIG_PLATFORM_ALLWINNER
//#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;
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 &&
#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;
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
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);
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 &&
return -ENOMEM;
}
-
+
sdiodev = kzalloc(sizeof(struct aic_sdio_dev), GFP_KERNEL);
if (!sdiodev) {
sdio_err("alloc sdiodev fail\n");
}
bus_if = aicbsp_get_drvdata(&func->dev);
-
+
if (!bus_if) {
AICWFDBG(LOGERROR, "%s bus_if is NULL \r\n", __func__);
return;
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);
#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;
}
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);
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);
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){
}
return 0;
}
-
+
aicbsp_unreg_sdio_notify();
#ifdef CONFIG_PLATFORM_ALLWINNER
sunxi_wlan_set_power(0);
#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;
}
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);
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 ||
{
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;
}else{
memcpy(fw_path, aic_default_fw_path, strlen(aic_default_fw_path));
}
-}
+}
int get_testmode(void){
return testmode;
};
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)
{
#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"
--- /dev/null
+*.o
+*.ko
+*.order
+*.symvers
+*.o.d
+*.o.cmd
+*.ko.cmd
+*.mod
+*.mod.c
+*.mod.cmd
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
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/
#include <linux/wakelock.h>
#endif
+#include "aic_bsp_export.h"
+
/*
* #define BT_SLEEP_DBG
*/
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,
.release = single_release,
.write = bluesleep_write_proc_btwrite,
};
+#endif
+
#else
/**
* Handles HCI device events.
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);
}
/* 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) {
#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");
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);
#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,
},
};
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/platform_device.h>
-//#include "lpm.h"
+#include "lpm.h"
#include "rfkill.h"
#define DRV_CONFIG_FW_NAME "fw.bin"
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");
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);
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);
bool band_5g_support;
uint32_t sdio_clock;
uint8_t sdio_phase;
+ uint8_t irqf;
};
int aicbsp_set_subsys(int, int);
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);
* 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)
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
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);
--- /dev/null
+*.o
+*.ko
+*.order
+*.symvers
+*.o.d
+*.o.cmd
+*.ko.cmd
+*.mod
+*.mod.c
+*.mod.cmd
+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
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
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)
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 \
$(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)\"
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)
# Platform support list
CONFIG_PLATFORM_ROCKCHIP ?= n
+CONFIG_PLATFORM_ROCKCHIP2 ?= n
CONFIG_PLATFORM_ALLWINNER ?= n
CONFIG_PLATFORM_INGENIC_T20 ?= n
CONFIG_PLATFORM_AMLOGIC ?= n
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
#ifndef __AIC_BSP_EXPORT_H
#define __AIC_BSP_EXPORT_H
-#define AICBSP_RESV_MEM_SUPPORT 0
-
enum aicbsp_subsys {
AIC_BLUETOOTH,
AIC_WIFI,
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);
[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,
{
return 0;
}
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
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
},
.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
},
.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
},
.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
},
.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
},
.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
},
.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
},
.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
},
.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
},
.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
},
.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
},
.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
},
.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
},
.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,
},
.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,
#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);
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;
}
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);
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){
#include <linux/types.h>
+#include "aic_bsp_export.h"
#ifdef CONFIG_DPD
-int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw);
+int aicwf_fdrv_dpd_result_apply_8800dc(struct rwnx_hw * rwnx_hw, rf_misc_ram_lite_t * dpd_res);
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res);
+#endif
#endif
int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw);
int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
#ifdef CONFIG_PLATFORM_ROCKCHIP
#include <linux/rfkill-wlan.h>
#endif
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+#include <linux/rfkill-wlan.h>
+#endif
+
#include "aic_bsp_export.h"
extern uint8_t scanning;
#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
{
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);
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
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);
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;
#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
#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();
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
// 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();
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 ||
#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"
cpumask_set_cpu(3, &cpumask);
sched_setaffinity(0, &cpumask);
#endif
-
+#if 0
#ifdef CONFIG_THREAD_INFO_IN_TASK
int set_cpu_ret = 0;
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))
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);
}
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);
}
}
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);
--- /dev/null
+#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);
+ }
+}
+
--- /dev/null
+#ifndef _AICWF_TCP_ACK_H_
+#define _AICWF_TCP_ACK_H_
+
+#include <uapi/linux/if_ether.h>
+#include <uapi/linux/tcp.h>
+#include <uapi/linux/ip.h>
+#include <uapi/linux/in.h>
+#include <linux/moduleparam.h>
+#include <net/tcp.h>
+#include <linux/timer.h>
+
+
+#define TCP_ACK_NUM 32
+#define TCP_ACK_EXIT_VAL 0x800
+#define TCP_ACK_DROP_CNT 10
+
+#define ACK_OLD_TIME 4000
+#define U32_BEFORE(a, b) ((__s32)((__u32)a - (__u32)b) <= 0)
+
+#define MAX_TCP_ACK 200
+/*min window size in KB, it's 256KB*/
+#define MIN_WIN 256
+#define SIZE_KB 1024
+
+
+struct msg_buf {
+ //struct list_head list;
+ struct sk_buff *skb;
+ struct rwnx_vif *rwnx_vif;
+
+ /* data just tx cmd use,not include the head */
+ /*void *data;
+ void *tran_data;
+ unsigned long pcie_addr;
+ u8 type;
+ u8 mode;
+ u16 len;
+ unsigned long timeout;*/
+ /* marlin 2 */
+ /*unsigned int fifo_id;
+ struct sprdwl_msg_list *msglist;*/
+ /* marlin 3 */
+ /*unsigned char buffer_type;
+ struct sprdwl_xmit_msg_list *xmit_msg_list;
+ unsigned char msg_type;
+
+ unsigned long last_time;
+ u8 ctxt_id;*/
+
+};
+
+struct tcp_ack_msg {
+ u16 source;
+ u16 dest;
+ s32 saddr;
+ s32 daddr;
+ u32 seq;
+ u16 win;
+};
+
+
+struct tcp_ack_info {
+ int ack_info_num;
+ int busy;
+ int drop_cnt;
+ int psh_flag;
+ u32 psh_seq;
+ u16 win_scale;
+ /* seqlock for ack info */
+ seqlock_t seqlock;
+ unsigned long last_time;
+ unsigned long timeout;
+ struct timer_list timer;
+ struct msg_buf *msgbuf;
+ struct msg_buf *in_send_msg;
+ struct tcp_ack_msg ack_msg;
+};
+
+struct tcp_ack_manage {
+ /* 1 filter */
+ atomic_t enable;
+ int max_num;
+ int free_index;
+ unsigned long last_time;
+ unsigned long timeout;
+ atomic_t max_drop_cnt;
+ /* lock for tcp ack alloc and free */
+ spinlock_t lock;
+ struct rwnx_hw *priv;
+ struct tcp_ack_info ack_info[TCP_ACK_NUM];
+ /*size in KB*/
+ unsigned int ack_winsize;
+};
+
+struct msg_buf *intf_tcp_alloc_msg(struct msg_buf *msg);
+
+void tcp_ack_init(struct rwnx_hw *priv);
+
+void tcp_ack_deinit(struct rwnx_hw *priv);
+
+
+int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len, unsigned short *win_scale);
+
+int is_tcp_ack(struct sk_buff *skb, unsigned short *win_scale);
+
+int filter_send_tcp_ack(struct rwnx_hw *priv, struct msg_buf *msgbuf,unsigned char *buf, unsigned int plen);
+
+void filter_rx_tcp_ack(struct rwnx_hw *priv,unsigned char *buf, unsigned plen);
+
+void move_tcpack_msg(struct rwnx_hw *priv, struct msg_buf * msg);
+#endif
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
#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);
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);
for (i = 0; i < qsize; i++) {
INIT_LIST_HEAD(&req->rxframe_list);
list_add(&req->rxframe_list, q);
- req->len = 0;
req++;
}
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
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;
MM_CFG_RSSI_CFM,
+ MM_SET_VENDOR_SWCONFIG_REQ,
+ MM_SET_VENDOR_SWCONFIG_CFM,
+
/// MAX number of messages
MM_MAX,
};
MAC_TIMESCALE_REQ,
CCA_THRESHOLD_REQ,
BWMODE_REQ,
+ CHIP_TEMP_GET_REQ,
};
enum {
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
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
{
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
#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)
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) {
{
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;
}
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)
{
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;
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;
}
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
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,
#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
{
#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"
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 */
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 */
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;
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;
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) {
}
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);
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);
#ifdef ANDROID_PLATFORM
#include "net/wireless/core.h"
#endif
-
+#include <include/linux/types.h>
#undef NL80211_MCGRP_MLME
#define NL80211_MCGRP_MLME 3
-#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
-
+//#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
static struct genl_family rwnx_nl80211_fam;
#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,
#include <linux/if_arp.h>
#include <linux/ctype.h>
#include <linux/random.h>
+#include <linux/vmalloc.h>
#include "rwnx_defs.h"
#include "rwnx_dini.h"
#include "rwnx_msg_tx.h"
} 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);
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);
#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
}
#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
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;
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
}
}
#endif
- clear_bit(RWNX_DEV_STARTED, &rwnx_hw->drv_flags);
+ clear_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags);
}
#ifdef CONFIG_COEX
else {
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 {
}
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], \
/* 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,
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) {
}
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;
}
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)
* @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);
*
*/
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,
* 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)
*/
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)
*/
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)
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);
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);
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;
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;
}
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
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
/**
* * @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)
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.
*/
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){
*/
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)
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
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:
.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)
#ifdef CONFIG_PLATFORM_ROCKCHIP
#include <linux/rfkill-wlan.h>
#endif
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+#include <linux/rfkill-wlan.h>
+#endif
#ifdef CONFIG_USE_CUSTOMER_MAC
int rwnx_get_custom_mac_addr(u8_l *mac_addr_efuse){
#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__,
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;
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) {
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;
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);
}
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] |=
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] |=
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] |=
*
****************************************************************************************
*/
+#include <linux/vmalloc.h>
#include "rwnx_defs.h"
#include "rwnx_prof.h"
#include "rwnx_tx.h"
#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)
{
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;
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;
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;
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
, 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);
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,
#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 */
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)) {
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
}
#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);
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;
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;
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;
struct mm_set_cca_threshold_req *req3;
struct mm_set_bwmode_req *req4;
- int error;
+ int error = 0;
switch (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;
/* 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)
{
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;
/* 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];
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);
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)
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);
#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)
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);
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;
__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);
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);
} 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;
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;
}
#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);
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)) &&
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();
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;
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);
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;
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);
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;
}
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;
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;
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;
}
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;
}
dev_kfree_skb(skb);
return 0;
+ #endif
}
if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA)
}
}
- if (!is_frag) {
+ if (!is_frag && !is_amsdu) {
skb_pull(skb, pull_len);
skb_push(skb, 14);
memcpy(skb->data, ra, MAC_ADDR_LEN);
}
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
}
}
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)) {
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);
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);
#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)
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);
#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);
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);
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)
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 &&
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);
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);
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) {
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");
out_msi:
#endif
pci_release_regions(pci_dev);
-out_request:
+//out_request:
#ifdef CONFIG_PCI
pci_clear_master(pci_dev);
#endif
#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"
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)