drivers: aic8800: upgrade to 20231212
authorLu Hui <luhui@sipeed.com>
Mon, 25 Dec 2023 03:07:25 +0000 (11:07 +0800)
committerJaehoon Chung <jh80.chung@samsung.com>
Wed, 13 Mar 2024 06:58:58 +0000 (15:58 +0900)
(cherry picked from commit 1fd93bc1a9b6fa6ffa509f20b9d0f85389cedf54)
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
51 files changed:
drivers/net/wireless/aic8800/Makefile
drivers/net/wireless/aic8800/aic8800_bsp/.gitignore [new file with mode: 0644]
drivers/net/wireless/aic8800/aic8800_bsp/Makefile
drivers/net/wireless/aic8800/aic8800_bsp/aic8800d80_compat.c
drivers/net/wireless/aic8800/aic8800_bsp/aic8800dc_compat.c
drivers/net/wireless/aic8800/aic8800_bsp/aic8800dc_compat.h
drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_driver.c
drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_driver.h
drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_export.h
drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_main.c
drivers/net/wireless/aic8800/aic8800_bsp/aicsdio.c
drivers/net/wireless/aic8800/aic8800_bsp/aicwf_txq_prealloc.c
drivers/net/wireless/aic8800/aic8800_bsp/rwnx_version_gen.h
drivers/net/wireless/aic8800/aic8800_btlpm/.gitignore [new file with mode: 0644]
drivers/net/wireless/aic8800/aic8800_btlpm/Makefile
drivers/net/wireless/aic8800/aic8800_btlpm/aic8800_btlpm.c
drivers/net/wireless/aic8800/aic8800_btlpm/aic_bluetooth_main.c
drivers/net/wireless/aic8800/aic8800_btlpm/aic_bsp_export.h
drivers/net/wireless/aic8800/aic8800_btlpm/lpm.c
drivers/net/wireless/aic8800/aic8800_fdrv/.gitignore [new file with mode: 0644]
drivers/net/wireless/aic8800/aic8800_fdrv/Makefile
drivers/net/wireless/aic8800/aic8800_fdrv/aic_bsp_export.h
drivers/net/wireless/aic8800/aic8800_fdrv/aic_vendor.c
drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c
drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h
drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_sdio.c
drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.c [new file with mode: 0644]
drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.h [new file with mode: 0644]
drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.c
drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_txrxif.h
drivers/net/wireless/aic8800/aic8800_fdrv/lmac_msg.h
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_compat.h
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_debugfs.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_defs.h
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_dini.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_gki.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_gki.h
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_main.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_mod_params.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_rx.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_tx.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_msg_tx.h
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_platform.h
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_rx.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_rx.h
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_tdls.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_tx.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_txq.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_v7.c
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_version_gen.h
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_wakelock.c

index 090095862cc01ef106fe6037824e022e0ee05df3..e410cafee48d69374304dc37dcc73315d816e2db 100644 (file)
@@ -2,11 +2,13 @@ obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) += aic8800_btlpm/
 obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/
 obj-$(CONFIG_AIC_WLAN_SUPPORT) += aic8800_bsp/
 
+
 # Platform support list
-CONFIG_PLATFORM_ROCKCHIP ?= n
-CONFIG_PLATFORM_ALLWINNER ?= n
-CONFIG_PLATFORM_AMLOGIC ?= n
-CONFIG_PLATFORM_UBUNTU ?= y
+CONFIG_PLATFORM_ROCKCHIP = n
+CONFIG_PLATFORM_ROCKCHIP2 = n
+CONFIG_PLATFORM_ALLWINNER = n
+CONFIG_PLATFORM_AMLOGIC = n
+CONFIG_PLATFORM_UBUNTU = y
 
 ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
 #KDIR = /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/kernel
@@ -22,6 +24,15 @@ ccflags-y += -DANDROID_PLATFORM
 ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP
 endif
 
+ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
+ARCH = arm64
+KDIR = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
+CROSS_COMPILE = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
+ccflags-y += -DANDROID_PLATFORM
+ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP2
+endif
+
+
 ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
 KDIR  = /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/kernel/linux-4.9
 ARCH = arm64
diff --git a/drivers/net/wireless/aic8800/aic8800_bsp/.gitignore b/drivers/net/wireless/aic8800/aic8800_bsp/.gitignore
new file mode 100644 (file)
index 0000000..c3c2d15
--- /dev/null
@@ -0,0 +1,10 @@
+*.o
+*.ko
+*.order
+*.symvers
+*.o.d
+*.o.cmd
+*.ko.cmd
+*.mod
+*.mod.c
+*.mod.cmd
index b311153cba8ee4cbe9159dfb42bd9a6fc6ba921b..632435a6b566c7341d8df30fd9bc429b25349809 100644 (file)
@@ -12,6 +12,8 @@ ccflags-$(CONFIG_SDIO_PWRCTRL) += -DCONFIG_SDIO_PWRCTRL
 endif
 
 CONFIG_GPIO_WAKEUP = n
+CONFIG_M2D_OTA_AUTO_SUPPORT = n
+CONFIG_M2D_OTA_LZMA_SUPPORT = n
 CONFIG_LINK_DET_5G = y
 CONFIG_MCU_MESSAGE = n
 CONFIG_FIRMWARE_ARRAY = n
@@ -22,10 +24,14 @@ CONFIG_VRF_DCDC_MODE = y
 CONFIG_OOB = n
 CONFIG_PREALLOC_TXQ = y
 CONFIG_ONE_TXQ = n
-CONFIG_DPD = n
-CONFIG_FORCE_DPD_CALIB = n
+CONFIG_DPD = y
+CONFIG_FORCE_DPD_CALIB = y
+CONFIG_RESV_MEM_SUPPORT = y
+CONFIG_AMSDU_RX ?=n
 
 ccflags-$(CONFIG_GPIO_WAKEUP) += -DCONFIG_GPIO_WAKEUP
+ccflags-$(CONFIG_M2D_OTA_AUTO_SUPPORT) += -DCONFIG_M2D_OTA_AUTO_SUPPORT
+ccflags-$(CONFIG_M2D_OTA_LZMA_SUPPORT) += -DCONFIG_M2D_OTA_LZMA_SUPPORT
 ccflags-$(CONFIG_LINK_DET_5G) += -DCONFIG_LINK_DET_5G
 ccflags-$(CONFIG_MCU_MESSAGE) += -DCONFIG_MCU_MESSAGE
 ccflags-$(CONFIG_FIRMWARE_ARRAY) += -DCONFIG_FIRMWARE_ARRAY
@@ -37,6 +43,8 @@ ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ
 ccflags-$(CONFIG_ONE_TXQ)  += -DCONFIG_ONE_TXQ
 ccflags-$(CONFIG_DPD)  += -DCONFIG_DPD
 ccflags-$(CONFIG_FORCE_DPD_CALIB) += -DCONFIG_FORCE_DPD_CALIB -DCONFIG_DPD
+ccflags-$(CONFIG_RESV_MEM_SUPPORT) += -DCONFIG_RESV_MEM_SUPPORT
+ccflags-$(CONFIG_AMSDU_RX) += -DCONFIG_AMSDU_RX
 
 obj-m := $(MODULE_NAME).o
 $(MODULE_NAME)-y := \
@@ -56,6 +64,7 @@ endif
 
 # Platform support list
 CONFIG_PLATFORM_ROCKCHIP ?= n
+CONFIG_PLATFORM_ROCKCHIP2 ?= n
 CONFIG_PLATFORM_ALLWINNER ?=n
 CONFIG_PLATFORM_INGENIC_T20 ?= n
 CONFIG_PLATFORM_AMLOGIC ?= n
@@ -88,6 +97,13 @@ ARCH ?= arm64
 CROSS_COMPILE ?= /home/yaya/E/Rockchip/3566/Android11/rk3566_rk3568_android11_oranth/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
 endif
 
+ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
+ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2
+ARCH ?= arm64
+KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
+CROSS_COMPILE ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
+endif
+
 ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
 ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
 #KDIR  ?= /home/yaya/E/Allwinner/A133/a133-sdk/android/longan/out/kernel/build/
index bf34109dbd1313012e2df903877177f1e85484e5..edc85f2b62d5386069818042e339aba948e6d6f6 100644 (file)
@@ -53,6 +53,12 @@ u32 patch_tbl_8800d80[][2] = {
        #else
        {0x00b4, 0xf3010000},
        #endif
+#if defined(CONFIG_AMSDU_RX)
+        {0x170, 0x0100000a}
+#endif
+#if AIC_IRQ_WAKE_FLAG
+       {0x00000170, 0x0000010a}, //irqf
+#endif
 };
 
 #ifdef CONFIG_OOB
@@ -99,6 +105,7 @@ int aicwifi_patch_config_8800d80(struct aic_sdio_dev *sdiodev)
        int adap_patch_cnt = 0;
 
        if (adap_test) {
+        printk("%s for adaptivity test \r\n", __func__);
                adap_patch_cnt = sizeof(adaptivity_patch_tbl_8800d80)/sizeof(u32)/2;
        }
 
index 4ef066ddeca038c359398d6d3c8e5b5f8dd84d13..2bbb087ba3da5774f34d9ef86599e1681e534b6f 100644 (file)
@@ -1500,7 +1500,7 @@ uint32_t txgain_map[96] =  {
     0x00ffcc85,
     0x00ffcd70,
     0x00ffcd80,
-    0x00ffce70,
+    0x00ffcd90,
     0x00ffce80,
     0x00ffce93,
     0x00ffcf90,
@@ -1523,6 +1523,108 @@ uint32_t txgain_map[96] =  {
 #endif
 };
 
+const uint32_t txgain_map_h[96] =
+{
+    //11b
+    0xffd888, //11
+    0xffd979, //12
+    0xffd988, //13
+    0xffda79, //14
+    0xffda88, //15
+    0xffdb79, //16
+    0xffdb88, //17
+    0xffdc72, //18
+    0xffdc80, //19
+    0xffdd80, //20
+    0xffde66, //21
+    0xffde72, //22
+    0xffde80, //23
+    0xffdf79, //24
+    0xffdf88, //25
+    0xffdf98, //26
+    0xffd079, //-5
+    0xffd088, //-4
+    0xffd179, //-3
+    0xffd188, //-2
+    0xffd288, //-1
+    0xffd36c, //0
+    0xffd379, //1
+    0xffd388, //2
+    0xffd479, //3
+    0xffd488, //4
+    0xffd579, //5
+    0xffd588, //6
+    0xffd679, //7
+    0xffd688, //8
+    0xffd779, //9
+    0xffd879, //10
+    //high
+    0xffc879, //8
+    0xffc96b, //9
+    0xffc979, //10
+    0xffca6b, //11
+    0xffca79, //12
+    0xffcc56, //13
+    0xffcc60, //14
+    0xffcc6b, //15
+    0xffcc79, //16
+    0xffcd72, //17
+    0xffce60, //18
+    0xffce72, //19
+    0xffcf72, //20
+    0xffcf80, //21
+    0xffcf90, //22
+    0xffcf90, //23
+    0xffc079, //-8
+    0xffc16b, //-7
+    0xffc179, //-6
+    0xffc26b, //-5
+    0xffc279, //-4
+    0xffc36b, //-3
+    0xffc379, //-2
+    0xffc46b, //-1
+    0xffc479, //0
+    0xffc56b, //1
+    0xffc579, //2
+    0xffc66b, //3
+    0xffc679, //4
+    0xffc76b, //5
+    0xffc779, //6
+    0xffc86b, //7
+    //low
+    0xffc879, //8
+    0xffc96b, //9
+    0xffc979, //10
+    0xffca6b, //11
+    0xffca79, //12
+    0xffcc56, //13
+    0xffcc60, //14
+    0xffcc6b, //15
+    0xffcc79, //16
+    0xffcd72, //17
+    0xffce60, //18
+    0xffce72, //19
+    0xffcf72, //20
+    0xffcf80, //21
+    0xffcf90, //22
+    0xffcf90, //23
+    0xffc079, //-8
+    0xffc16b, //-7
+    0xffc179, //-6
+    0xffc26b, //-5
+    0xffc279, //-4
+    0xffc36b, //-3
+    0xffc379, //-2
+    0xffc46b, //-1
+    0xffc479, //0
+    0xffc56b, //1
+    0xffc579, //2
+    0xffc66b, //3
+    0xffc679, //4
+    0xffc76b, //5
+    0xffc779, //6
+    0xffc86b, //7
+};
 
 
 u32 jump_tbl[][2] =
@@ -1585,6 +1687,7 @@ u32 patch_tbl_rf_func[][2] =
     {0x00110bf0, 0x00180001},
 };
 
+static u8 chip_id = 0;
 #define CHIP_ID_H_MASK  0xC0
 #define IS_CHIP_ID_H()  ((chip_id & CHIP_ID_H_MASK) == CHIP_ID_H_MASK)
 
@@ -1594,7 +1697,6 @@ void system_config_8800dc(struct aic_sdio_dev *rwnx_hw)
     array3_tbl_t p_syscfg_msk_tbl;
     int ret, cnt;
     const u32 mem_addr = 0x40500000;
-       u8 chip_id = 0;
     struct dbg_mem_read_cfm rd_mem_addr_cfm;
 
     ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm);
@@ -1716,7 +1818,7 @@ void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw)
         u32 patch_tbl_wifisetting_num;// = sizeof(patch_tbl_wifisetting_8800dc_u02)/sizeof(u32)/2;
         u32 ldpc_cfg_size = sizeof(ldpc_cfg_ram);
         u32 agc_cfg_size = sizeof(agc_cfg_ram);
-        u32 txgain_cfg_size = sizeof(txgain_map);
+        u32 txgain_cfg_size, *txgain_cfg_array;
         u32 jump_tbl_size = 0;
         u32 patch_tbl_func_num = 0;
 
@@ -1731,7 +1833,7 @@ void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw)
             patch_tbl_func_num = sizeof(patch_tbl_func)/sizeof(u32)/2;
                        patch_tbl_wifisetting_num = sizeof(patch_tbl_wifisetting_8800dc_u01)/sizeof(u32)/2;
                        patch_tbl_wifisetting_8800dc_base = patch_tbl_wifisetting_8800dc_u01;
-        } else if (chip_sub_id == 1) {
+        } else if ((chip_sub_id == 1) || (chip_sub_id == 2)) {
                        patch_tbl_wifisetting_num = sizeof(patch_tbl_wifisetting_8800dc_u02)/sizeof(u32)/2;
                        patch_tbl_wifisetting_8800dc_base = patch_tbl_wifisetting_8800dc_u02;
         } else {
@@ -1812,29 +1914,42 @@ void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw)
         }
 
         #if !defined(CONFIG_FPGA_VERIFICATION)
-        ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, txgain_cfg_addr, txgain_cfg_size, txgain_map);
+        if ((IS_CHIP_ID_H())) {
+            txgain_cfg_size = sizeof(txgain_map_h);
+            txgain_cfg_array = (u32 *)txgain_map_h;
+        } else {
+            txgain_cfg_size = sizeof(txgain_map);
+            txgain_cfg_array = (u32 *)txgain_map;
+        }
+        ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, txgain_cfg_addr, txgain_cfg_size, txgain_cfg_array);
         if (ret) {
             AICWFDBG(LOGERROR, "txgain upload fail: %x, err:%d\r\n", txgain_cfg_addr, ret);
         }
 
-               if(chip_sub_id == 0){
-               for (cnt = 0; cnt < jump_tbl_size/4; cnt+=1) {
-                   AICWFDBG(LOGDEBUG, "%x = %x\n", jump_tbl_base[cnt][0]*4+jump_tbl_addr, jump_tbl_base[cnt][1]);
-                   if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, jump_tbl_base[cnt][0]*4+jump_tbl_addr, jump_tbl_base[cnt][1]))) {
-                       AICWFDBG(LOGERROR, "%x write fail\n", jump_tbl_addr+8*cnt);
-                   }
-               }
-               for (cnt = 0; cnt < patch_tbl_func_num; cnt++) {
-                   if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_func_base[cnt][0], patch_tbl_func_base[cnt][1]))) {
-                       AICWFDBG(LOGERROR, "patch_tbl_func %x write fail\n", patch_tbl_func_base[cnt][0]);
-                   }
-               }
-               }
-               else{
+               if (chip_sub_id == 0) {
+                       for (cnt = 0; cnt < jump_tbl_size/4; cnt+=1) {
+                               AICWFDBG(LOGDEBUG, "%x = %x\n", jump_tbl_base[cnt][0]*4+jump_tbl_addr, jump_tbl_base[cnt][1]);
+                               if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, jump_tbl_base[cnt][0]*4+jump_tbl_addr, jump_tbl_base[cnt][1]))) {
+                                       AICWFDBG(LOGERROR, "%x write fail\n", jump_tbl_addr+8*cnt);
+                               }
+                       }
+                       for (cnt = 0; cnt < patch_tbl_func_num; cnt++) {
+                               if ((ret = rwnx_send_dbg_mem_write_req(rwnx_hw, patch_tbl_func_base[cnt][0], patch_tbl_func_base[cnt][1]))) {
+                                       AICWFDBG(LOGERROR, "patch_tbl_func %x write fail\n", patch_tbl_func_base[cnt][0]);
+                               }
+                       }
+               } else if (chip_sub_id == 1) {
                        ret = aicwf_patch_table_load(rwnx_hw, RWNX_MAC_PATCH_TABLE_8800DC_U02);
                        if(ret){
-                              printk("patch_tbl upload fail: err:%d\r\n", ret);
+                               printk("patch_tbl upload fail: err:%d\r\n", ret);
+                       }
+               } else if (chip_sub_id == 2) {
+                       ret = aicwf_patch_table_load(rwnx_hw, RWNX_MAC_PATCH_TABLE_8800DC_H_U02);
+                       if(ret){
+                               printk("patch_tbl upload fail: err:%d\r\n", ret);
                        }
+               } else {
+                       printk("unsupported id: %d\n", chip_sub_id);
                }
 
         #endif
@@ -1853,11 +1968,15 @@ void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw)
 int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev)
 {
     int ret = 0;
-    const uint32_t cfg_base = 0x10164;
+    uint32_t cfg_base = 0x10164;
     struct dbg_mem_read_cfm cfm;
     uint32_t misc_ram_addr;
     uint32_t misc_ram_size = 12;
     int i;
+
+    if (testmode == FW_RFTEST_MODE) {
+        cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
+    }
     // init misc ram
     ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x14, &cfm);
     if (ret) {
@@ -1877,13 +1996,23 @@ int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev)
 }
 
 #ifdef CONFIG_DPD
-int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, uint32_t *dpd_res)
+int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res)
 {
     int ret = 0;
     uint32_t fw_addr, boot_type;
+    int valid_flag;
 
        printk("%s\n", __func__);
 
+    ret = aicwf_misc_ram_valid_check_8800dc(sdiodev, &valid_flag);
+    if (ret) {
+        AICWFDBG(LOGINFO, "misc ram check fail: %d\n", ret);
+        return ret;
+    }
+    if (valid_flag) {
+        AICWFDBG(LOGINFO, "misc ram valid, skip calib process\n");
+        return ret;
+    }
     ret = aicwf_plat_calib_load_8800dc(sdiodev);
     if (ret) {
         AICWFDBG(LOGINFO, "load calib bin fail: %d\n", ret);
@@ -1902,7 +2031,7 @@ int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, uint32_t *dpd_res)
         const uint32_t cfg_base = 0x10164;
         struct dbg_mem_read_cfm cfm;
         uint32_t misc_ram_addr;
-        uint32_t misc_ram_size = DPD_RESULT_SIZE_8800DC;
+        uint32_t ram_base_addr, ram_word_cnt;
         int i;
         ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x14, &cfm);
         if (ret) {
@@ -1910,50 +2039,137 @@ int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, uint32_t *dpd_res)
             return ret;
         }
         misc_ram_addr = cfm.memdata;
-        for (i = 0; i < (misc_ram_size / 4); i++) {
-            ret = rwnx_send_dbg_mem_read_req(sdiodev, misc_ram_addr + i * 4, &cfm);
+        // bit_mask
+        ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask);
+        ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4;
+        for (i = 0; i < ram_word_cnt; i++) {
+            ret = rwnx_send_dbg_mem_read_req(sdiodev, ram_base_addr + i * 4, &cfm);
+            if (ret) {
+                AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n",  ram_base_addr + i * 4, ret);
+                return ret;
+            }
+            dpd_res->bit_mask[i] = cfm.memdata;
+        }
+        // dpd_high
+        ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high);
+        ram_word_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high) / 4;
+        for (i = 0; i < ram_word_cnt; i++) {
+            ret = rwnx_send_dbg_mem_read_req(sdiodev, ram_base_addr + i * 4, &cfm);
             if (ret) {
-                AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n",  misc_ram_addr + i * 4, ret);
+                AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n",  ram_base_addr + i * 4, ret);
                 return ret;
             }
-            dpd_res[i] = cfm.memdata;
+            dpd_res->dpd_high[i] = cfm.memdata;
+        }
+        // loft_res
+        ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res);
+        ram_word_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res) / 4;
+        for (i = 0; i < ram_word_cnt; i++) {
+            ret = rwnx_send_dbg_mem_read_req(sdiodev, ram_base_addr + i * 4, &cfm);
+            if (ret) {
+                AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n",  ram_base_addr + i * 4, ret);
+                return ret;
+            }
+            dpd_res->loft_res[i] = cfm.memdata;
         }
     }
     return ret;
 }
 
-int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev)
+int aicwf_dpd_result_apply_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res)
 {
-       printk("%s\n", __func__);
     int ret = 0;
     uint32_t cfg_base = 0x10164;
     struct dbg_mem_read_cfm cfm;
     uint32_t misc_ram_addr;
-       if (testmode == 1) {
-               cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
-       }
+    uint32_t ram_base_addr, ram_byte_cnt;
+    AICWFDBG(LOGINFO, "bit_mask[1]=%x\n", dpd_res->bit_mask[1]);
+    if (dpd_res->bit_mask[1] == 0) {
+        AICWFDBG(LOGERROR, "void dpd_res, bypass it.\n");
+        return 0;
+    }
+    if (testmode == FW_RFTEST_MODE) {
+        cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
+    }
     if ((ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x14, &cfm))) {
         AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
         return ret;
     }
     misc_ram_addr = cfm.memdata;
-    ret = rwnx_plat_bin_fw_upload_android(sdiodev, misc_ram_addr, FW_DPDRESULT_NAME_8800DC);
+    AICWFDBG(LOGINFO, "misc_ram_addr: %x\n", misc_ram_addr);
+    /* Copy dpd_res on the Embedded side */
+    // bit_mask
+    AICWFDBG(LOGINFO, "bit_mask[0]=%x\n", dpd_res->bit_mask[0]);
+    ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask);
+    ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved);
+    ret = rwnx_send_dbg_mem_block_write_req(sdiodev, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->bit_mask[0]);
     if (ret) {
-        AICWFDBG(LOGINFO, "load calib bin fail: %d\n", ret);
+        AICWFDBG(LOGERROR, "bit_mask wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
+        return ret;
+    }
+    // dpd_high
+    AICWFDBG(LOGINFO, "dpd_high[0]=%x\n", dpd_res->dpd_high[0]);
+    ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high);
+    ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high);
+    ret = rwnx_send_dbg_mem_block_write_req(sdiodev, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->dpd_high[0]);
+    if (ret) {
+        AICWFDBG(LOGERROR, "dpd_high wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
+        return ret;
+    }
+    // loft_res
+    AICWFDBG(LOGINFO, "loft_res[0]=%x\n", dpd_res->loft_res[0]);
+    ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res);
+    ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res);
+    ret = rwnx_send_dbg_mem_block_write_req(sdiodev, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->loft_res[0]);
+    if (ret) {
+        AICWFDBG(LOGERROR, "loft_res wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
         return ret;
     }
     return ret;
 }
 
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res)
+{
+    int ret = 0;
+    int size;
+    u32 *dst=NULL;
+    char *filename = FW_DPDRESULT_NAME_8800DC;
+    struct device *dev = sdiodev->dev;
+    AICWFDBG(LOGINFO, "%s: dpd_res file path:%s \r\n", __func__, filename);
+    /* load file */
+    size = rwnx_load_firmware(&dst, filename, dev);
+    if (size <= 0) {
+        AICWFDBG(LOGERROR, "wrong size of dpd_res file\n");
+        if (dst) {
+            #ifndef CONFIG_FIRMWARE_ARRAY
+            vfree(dst);
+            #endif
+            dst = NULL;
+        }
+        return -1;
+    }
+    AICWFDBG(LOGINFO, "### Load file done: %s, size=%d, dst[0]=%x\n", filename, size, dst[0]);
+    memcpy((u8 *)dpd_res, (u8 *)dst, sizeof(rf_misc_ram_lite_t));
+    if (dst) {
+        #ifndef CONFIG_FIRMWARE_ARRAY
+        vfree(dst);
+        #endif
+        dst = NULL;
+    }
+    return ret;
+}
+
 int aicwf_dpd_result_write_8800dc(void *buf, int buf_len)
 {
-       printk("%s\n", __func__);
     int sum = 0, len = 0;
     char *path = NULL;
     struct file *fp = NULL;
     loff_t pos = 0;
     mm_segment_t fs;
 
+    AICWFDBG(LOGINFO, "%s\n", __func__);
+
     path = __getname();
     if (!path) {
         AICWFDBG(LOGINFO, "get path fail\n");
@@ -1988,6 +2204,7 @@ int aicwf_dpd_result_write_8800dc(void *buf, int buf_len)
 
     return 0;
 }
+#endif /* !CONFIG_FORCE_DPD_CALIB */
 #endif
 
 
index 09f303bc06029fc4f333a6494d04a10eafabc5b0..67074cecfc5fbdeb7abbbbea1af5cde36df92971 100644 (file)
@@ -16,7 +16,6 @@ typedef uint64_t u64_l;
 
 extern u8 chip_sub_id;
 extern u8 chip_mcu_id;
-#define DPD_RESULT_SIZE_8800DC 1880
 #define FW_PATH_MAX_LEN 200
 
 void aicwf_patch_config_8800dc(struct          aic_sdio_dev *rwnx_hw);
@@ -24,9 +23,12 @@ void system_config_8800dc(struct aic_sdio_dev *rwnx_hw);
 int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev);
 
 #ifdef CONFIG_DPD
-int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, uint32_t *dpd_res);
-int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev);
+int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res);
+int aicwf_dpd_result_apply_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res);
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res);
 int aicwf_dpd_result_write_8800dc(void *buf, int buf_len);
+#endif/* !CONFIG_FORCE_DPD_CALIB */
 #endif
 
 #endif
index 4b02d68ce26e2853678de7ed62ead0f6c43d68eb..5d7e6bbb3968d3f0115b48ec9103dbaba8e50017 100644 (file)
@@ -655,6 +655,239 @@ int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *device)
 #endif
 }
 
+extern int testmode;
+
+#ifdef CONFIG_M2D_OTA_AUTO_SUPPORT
+extern char saved_sdk_ver[64];
+
+int rwnx_plat_m2d_flash_ota_android(struct aic_sdio_dev *sdiodev, char *filename)
+{
+       struct device *dev = sdiodev->dev;
+       unsigned int i=0;
+       int size;
+       u32 *dst=NULL;
+       int err=0;
+       int ret;
+       u8 bond_id;
+       const u32 mem_addr = 0x40500000;
+       struct dbg_mem_read_cfm rd_mem_addr_cfm;
+
+       ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm);
+       if (ret) {
+               printk("m2d %x rd fail: %d\n", mem_addr, ret);
+               return ret;
+       }
+       bond_id = (u8)(rd_mem_addr_cfm.memdata >> 24);
+       printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
+       if (bond_id & (1<<1)) {
+               //flash is invalid
+               printk("m2d flash is invalid\n");
+               return -1;
+       }
+
+       /* load aic firmware */
+       size = rwnx_load_firmware(&dst, filename, dev);
+       if(size<=0){
+                       printk("wrong size of m2d file\n");
+                       vfree(dst);
+                       dst = NULL;
+                       return -1;
+       }
+
+       /* Copy the file on the Embedded side */
+       printk("### Upload m2d %s flash, size=%d\n", filename, size);
+
+       /*send info first*/
+       err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_INFO_ADDR, 4, (u32 *)&size);
+
+       /*send data first*/
+       if (size > 1024) {// > 1KB data
+               for (i = 0; i < (size - 1024); i += 1024) {//each time write 1KB
+                       err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, 1024, dst + i / 4);
+                               if (err) {
+                               printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err);
+                               break;
+                       }
+               }
+       }
+
+       if (!err && (i < size)) {// <1KB data
+               err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, size - i, dst + i / 4);
+               if (err) {
+                       printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err);
+               }
+       }
+
+       if (dst) {
+               vfree(dst);
+               dst = NULL;
+       }
+       testmode = FW_NORMAL_MODE;
+       aicbsp_info.cpmode = testmode;
+
+       printk("m2d flash update complete\n\n");
+
+       return err;
+}
+
+int rwnx_plat_m2d_flash_ota_check(struct aic_sdio_dev *sdiodev, char *filename)
+{
+       struct device *dev = sdiodev->dev;
+       unsigned int i=0,j=0;
+       int size;
+       u32 *dst=NULL;
+       int err=0;
+       int ret=0;
+       u8 bond_id;
+       const u32 mem_addr = 0x40500000;
+       const u32 mem_addr_code_start = AIC_M2D_OTA_CODE_START_ADDR;
+       const u32 mem_addr_sdk_ver = AIC_M2D_OTA_VER_ADDR;
+       const u32 driver_code_start_idx = (AIC_M2D_OTA_CODE_START_ADDR-AIC_M2D_OTA_FLASH_ADDR)/4;
+       const u32 driver_sdk_ver_idx = (AIC_M2D_OTA_VER_ADDR-AIC_M2D_OTA_FLASH_ADDR)/4;
+       u32 driver_sdk_ver_addr_idx = 0;
+       u32 code_start_addr = 0xffffffff;
+       u32 sdk_ver_addr = 0xffffffff;
+       u32 drv_code_start_addr = 0xffffffff;
+       u32 drv_sdk_ver_addr = 0xffffffff;
+       struct dbg_mem_read_cfm rd_mem_addr_cfm;
+       char m2d_sdk_ver[64];
+       char flash_sdk_ver[64];
+       u32 flash_ver[16];
+       u32 ota_ver[16];
+
+       ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm);
+       if (ret) {
+               printk("m2d %x rd fail: %d\n", mem_addr, ret);
+               return ret;
+       }
+       bond_id = (u8)(rd_mem_addr_cfm.memdata >> 24);
+       printk("%x=%x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
+       if (bond_id & (1<<1)) {
+               //flash is invalid
+               printk("m2d flash is invalid\n");
+               return -1;
+       }
+       ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr_code_start, &rd_mem_addr_cfm);
+       if (ret){
+               printk("mem_addr_code_start %x rd fail: %d\n", mem_addr_code_start, ret);
+               return ret;
+       }
+       code_start_addr = rd_mem_addr_cfm.memdata;
+
+       #if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT)
+       ret = rwnx_send_dbg_mem_read_req(sdiodev, mem_addr_sdk_ver, &rd_mem_addr_cfm);
+       if (ret){
+               printk("mem_addr_sdk_ver %x rd fail: %d\n", mem_addr_code_start, ret);
+               return ret;
+       }
+       sdk_ver_addr = rd_mem_addr_cfm.memdata;
+       #else
+       sdk_ver_addr = mem_addr_sdk_ver;
+       #endif
+       printk("code_start_addr: 0x%x,  sdk_ver_addr: 0x%x\n", code_start_addr,sdk_ver_addr);
+
+       /* load aic firmware */
+       size = rwnx_load_firmware(&dst, filename, dev);
+       if(size<=0){
+                       printk("wrong size of m2d file\n");
+                       vfree(dst);
+                       dst = NULL;
+                       return -1;
+       }
+       if(code_start_addr == 0xffffffff && sdk_ver_addr == 0xffffffff) {
+               printk("########m2d flash old version , must be upgrade\n");
+               drv_code_start_addr = dst[driver_code_start_idx];
+               drv_sdk_ver_addr = dst[driver_sdk_ver_idx];
+
+               printk("drv_code_start_addr: 0x%x,      drv_sdk_ver_addr: 0x%x\n", drv_code_start_addr,drv_sdk_ver_addr);
+
+               if(drv_sdk_ver_addr == 0xffffffff){
+                       printk("########driver m2d_ota.bin is old ,not need upgrade\n");
+                       return -1;
+               }
+
+       } else {
+               for(i=0;i<16;i++){
+                       ret = rwnx_send_dbg_mem_read_req(sdiodev, (sdk_ver_addr+i*4), &rd_mem_addr_cfm);
+                       if (ret){
+                               printk("mem_addr_sdk_ver %x rd fail: %d\n", mem_addr_code_start, ret);
+                               return ret;
+                       }
+                       flash_ver[i] = rd_mem_addr_cfm.memdata;
+               }
+               memcpy((u8 *)flash_sdk_ver,(u8 *)flash_ver,64);
+               memcpy((u8 *)saved_sdk_ver,(u8 *)flash_sdk_ver,64);
+               printk("flash SDK Version: %s\r\n\r\n", flash_sdk_ver);
+
+               drv_code_start_addr = dst[driver_code_start_idx];
+               drv_sdk_ver_addr = dst[driver_sdk_ver_idx];
+
+               printk("drv_code_start_addr: 0x%x,      drv_sdk_ver_addr: 0x%x\n", drv_code_start_addr,drv_sdk_ver_addr);
+
+               if(drv_sdk_ver_addr == 0xffffffff){
+                       printk("########driver m2d_ota.bin is old ,not need upgrade\n");
+                       return -1;
+               }
+
+               #if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT)
+               driver_sdk_ver_addr_idx = (drv_sdk_ver_addr-drv_code_start_addr)/4;
+               #else
+               driver_sdk_ver_addr_idx = driver_sdk_ver_idx;
+               #endif
+               printk("driver_sdk_ver_addr_idx %d\n",driver_sdk_ver_addr_idx);
+
+               if (driver_sdk_ver_addr_idx){
+                       for(j = 0; j < 16; j++){
+                               ota_ver[j] = dst[driver_sdk_ver_addr_idx+j];
+                       }
+                       memcpy((u8 *)m2d_sdk_ver,(u8 *)ota_ver,64);
+                       printk("m2d_ota SDK Version: %s\r\n\r\n", m2d_sdk_ver);
+               } else {
+                       return -1;
+               }
+
+               if(!strcmp(m2d_sdk_ver,flash_sdk_ver)){
+                       printk("######## m2d %s flash is not need upgrade\r\n", filename);
+                       return -1;
+               }
+       }
+
+       /* Copy the file on the Embedded side */
+       printk("### Upload m2d %s flash, size=%d\n", filename, size);
+
+       /*send info first*/
+       err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_INFO_ADDR, 4, (u32 *)&size);
+
+       /*send data first*/
+       if (size > 1024) {// > 1KB data
+               for (i = 0; i < (size - 1024); i += 1024) {//each time write 1KB
+                       err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, 1024, dst + i / 4);
+                               if (err) {
+                               printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err);
+                               break;
+                       }
+               }
+       }
+
+       if (!err && (i < size)) {// <1KB data
+               err = rwnx_send_dbg_mem_block_write_req(sdiodev, AIC_M2D_OTA_DATA_ADDR, size - i, dst + i / 4);
+               if (err) {
+                       printk("m2d upload fail: %x, err:%d\r\n", AIC_M2D_OTA_DATA_ADDR, err);
+               }
+       }
+
+       if (dst) {
+               vfree(dst);
+               dst = NULL;
+       }
+       testmode = FW_NORMAL_MODE;
+
+       printk("m2d flash update complete\n\n");
+
+       return err;
+}
+#endif//CONFIG_M2D_OTA_AUTO_SUPPORT
+
 int aicwf_patch_table_load(struct aic_sdio_dev *rwnx_hw, char *filename)
 {
        struct device *dev = rwnx_hw->dev;
@@ -720,7 +953,6 @@ int aicwf_patch_table_load(struct aic_sdio_dev *rwnx_hw, char *filename)
 }
 
 extern char aic_fw_path[200];
-extern int testmode;
 int aicwf_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev)
 {
     int ret = 0;
@@ -731,6 +963,9 @@ int aicwf_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev)
     } else if (chip_sub_id == 1) {
         printk("u02 is loaing ###############\n");
         ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_8800DC_U02);
+    } else if (chip_sub_id == 2) {
+        printk("h_u02 is loaing ###############\n");
+        ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_8800DC_H_U02);
     } else {
         printk("unsupported id: %d\n", chip_sub_id);
     }
@@ -750,6 +985,76 @@ int aicwf_plat_rftest_load_8800dc(struct aic_sdio_dev *sdiodev)
 }
 
 #ifdef CONFIG_DPD
+int aicwf_misc_ram_valid_check_8800dc(struct aic_sdio_dev *sdiodev, int *valid_out)
+{
+    int ret = 0;
+    uint32_t cfg_base = 0x10164;
+    struct dbg_mem_read_cfm cfm;
+    uint32_t misc_ram_addr;
+    uint32_t ram_base_addr, ram_word_cnt;
+    uint32_t bit_mask[4];
+    int i;
+    if (valid_out) {
+        *valid_out = 0;
+    }
+    if (testmode == FW_RFTEST_MODE) {
+               
+           uint32_t vect1 = 0;
+           uint32_t vect2 = 0;
+           cfg_base = RAM_LMAC_FW_ADDR + 0x0004;
+           ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base, &cfm);
+           if (ret) {
+                   AICWFDBG(LOGERROR, "cfg_base:%x vcet1 rd fail: %d\n", cfg_base, ret);
+                   return ret;
+           }
+           vect1 = cfm.memdata;
+           if ((vect1 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) {
+                   AICWFDBG(LOGERROR, "vect1 invalid: %x\n", vect1);
+                   return ret;
+           }
+           cfg_base = RAM_LMAC_FW_ADDR + 0x0008;
+           ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base, &cfm);
+           if (ret) {
+                   AICWFDBG(LOGERROR, "cfg_base:%x vcet2 rd fail: %d\n", cfg_base, ret);
+                   return ret;
+           }
+           vect2 = cfm.memdata;
+           if ((vect2 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) {
+                   AICWFDBG(LOGERROR, "vect2 invalid: %x\n", vect2);
+                   return ret;
+           }
+
+        cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
+    }
+    // init misc ram
+    ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x14, &cfm);
+    if (ret) {
+        AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
+        return ret;
+    }
+    misc_ram_addr = cfm.memdata;
+    AICWFDBG(LOGERROR, "misc_ram_addr=%x\n", misc_ram_addr);
+    // bit_mask
+    ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask);
+    ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4;
+    for (i = 0; i < ram_word_cnt; i++) {
+        ret = rwnx_send_dbg_mem_read_req(sdiodev, ram_base_addr + i * 4, &cfm);
+        if (ret) {
+            AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n",  ram_base_addr + i * 4, ret);
+            return ret;
+        }
+        bit_mask[i] = cfm.memdata;
+    }
+    AICWFDBG(LOGTRACE, "bit_mask:%x,%x,%x,%x\n",bit_mask[0],bit_mask[1],bit_mask[2],bit_mask[3]);
+    if ((bit_mask[0] == 0) && ((bit_mask[1] & 0xFFF00000) == 0x80000000) &&
+        (bit_mask[2] == 0) && ((bit_mask[3] & 0xFFFFFF00) == 0x00000000)) {
+        if (valid_out) {
+            *valid_out = 1;
+        }
+    }
+    return ret;
+}
+
 int aicwf_plat_calib_load_8800dc(struct aic_sdio_dev *sdiodev)
 {
     int ret = 0;
@@ -759,10 +1064,17 @@ int aicwf_plat_calib_load_8800dc(struct aic_sdio_dev *sdiodev)
             AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret);
             return ret;
         }
+    } else if (chip_sub_id == 2) {
+        ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_CALIB_ADDR, RWNX_MAC_CALIB_NAME_8800DC_H_U02);
+        if (ret) {
+            AICWFDBG(LOGINFO, "load rftest bin fail: %d\n", ret);
+            return ret;
+        }
     }
     return ret;
 }
 
+#ifndef CONFIG_FORCE_DPD_CALIB
 int is_file_exist(char* name)
 {
     char *path = NULL;
@@ -792,6 +1104,12 @@ int is_file_exist(char* name)
 
 EXPORT_SYMBOL(is_file_exist);
 #endif
+#endif
+
+#ifdef CONFIG_DPD
+rf_misc_ram_lite_t dpd_res = {{0},};
+EXPORT_SYMBOL(dpd_res);
+#endif
 
 static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
 {
@@ -816,7 +1134,7 @@ static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
                     return ret;
                 }
             }
-        } else if (chip_sub_id == 1) {
+        } else if (chip_sub_id >= 1) {
             if (testmode == FW_NORMAL_MODE) {
                 AICWFDBG(LOGINFO, "rwnx_plat_patch_loading\n");
                 ret = aicwf_plat_patch_load_8800dc(sdiodev);
@@ -827,39 +1145,41 @@ static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
                 #ifdef CONFIG_DPD
                 #ifdef CONFIG_FORCE_DPD_CALIB
                 if (1) {
-                    uint32_t dpd_res[DPD_RESULT_SIZE_8800DC / 4] = {0,};
                     AICWFDBG(LOGINFO, "dpd calib & write\n");
-                    ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res[0]);
+                    ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res);
                     if (ret) {
                         AICWFDBG(LOGINFO, "dpd calib fail: %d\n", ret);
                         return ret;
                     }
-                    ret = aicwf_dpd_result_write_8800dc((void *)dpd_res, DPD_RESULT_SIZE_8800DC);
-                    if (ret) {
-                        AICWFDBG(LOGINFO, "file write fail: %d\n", ret);
-                        return ret;
-                    }
                 }
                 #else
                 if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) {
                     AICWFDBG(LOGINFO, "dpd bin load\n");
-                    ret = aicwf_dpd_result_load_8800dc(sdiodev);
+                    ret = aicwf_dpd_result_load_8800dc(sdiodev, &dpd_res);
                     if (ret) {
                         AICWFDBG(LOGINFO, "load dpd bin fail: %d\n", ret);
                         return ret;
                     }
+                                       ret = aicwf_dpd_result_apply_8800dc(sdiodev, &dpd_res);
+                                       if (ret) {
+                                               AICWFDBG(LOGINFO, "apply dpd bin fail: %d\n", ret);
+                                               return ret;
+                                       }
                 }
                 #endif
                 else
                 #endif
                 {
-                    aicwf_misc_ram_init_8800dc(sdiodev);
+                    ret = aicwf_misc_ram_init_8800dc(sdiodev);
+                    if (ret) {
+                        AICWFDBG(LOGINFO, "misc ram init fail: %d\n", ret);
+                        return ret;
+                    }
                 }
             } else if (testmode == FW_RFTEST_MODE) {
                 #ifdef CONFIG_DPD
                 #ifdef CONFIG_FORCE_DPD_CALIB
                 if (1) {
-                    uint32_t dpd_res[DPD_RESULT_SIZE_8800DC / 4] = {0,};
                     AICWFDBG(LOGINFO, "patch load\n");
                     ret = aicwf_plat_patch_load_8800dc(sdiodev);
                     if (ret) {
@@ -867,16 +1187,11 @@ static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
                         return ret;
                     }
                     AICWFDBG(LOGINFO, "dpd calib & write\n");
-                    ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res[0]);
+                    ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res);
                     if (ret) {
                         AICWFDBG(LOGINFO, "dpd calib fail: %d\n", ret);
                         return ret;
                     }
-                    ret = aicwf_dpd_result_write_8800dc((void *)dpd_res, DPD_RESULT_SIZE_8800DC);
-                    if (ret) {
-                        AICWFDBG(LOGINFO, "file write fail: %d\n", ret);
-                        return ret;
-                    }
                 }
                 #endif
                 #endif
@@ -886,9 +1201,8 @@ static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
                     return ret;
                 }
             } else if (testmode == FW_DPDCALIB_MODE) {
-                #ifdef CONFIG_DPD
+                #if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
                 if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 0) {
-                    uint32_t dpd_res[DPD_RESULT_SIZE_8800DC / 4] = {0,};
                     AICWFDBG(LOGINFO, "patch load\n");
                     ret = aicwf_plat_patch_load_8800dc(sdiodev);
                     if (ret) {
@@ -896,12 +1210,12 @@ static int rwnx_plat_patch_load(struct aic_sdio_dev *sdiodev)
                         return ret;
                     }
                     AICWFDBG(LOGINFO, "dpd calib & write\n");
-                    ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res[0]);
+                    ret = aicwf_dpd_calib_8800dc(sdiodev, &dpd_res);
                     if (ret) {
                         AICWFDBG(LOGINFO, "dpd calib fail: %d\n", ret);
                         return ret;
                     }
-                    ret = aicwf_dpd_result_write_8800dc((void *)dpd_res, DPD_RESULT_SIZE_8800DC);
+                    ret = aicwf_dpd_result_write_8800dc((void *)&dpd_res, DPD_RESULT_SIZE_8800DC);
                     if (ret) {
                         AICWFDBG(LOGINFO, "file write fail: %d\n", ret);
                         return ret;
@@ -1116,23 +1430,41 @@ int aicbt_patch_trap_data_load(struct aic_sdio_dev *sdiodev, struct aicbt_patch_
 
 }
 
-static struct aicbt_info_t aicbt_info = {
-       .btmode        = AICBT_BTMODE_DEFAULT,
-       .btport        = AICBT_BTPORT_DEFAULT,
-       .uart_baud     = AICBT_UART_BAUD_DEFAULT,
-       .uart_flowctrl = AICBT_UART_FC_DEFAULT,
-       .lpm_enable = AICBT_LPM_ENABLE_DEFAULT,
-       .txpwr_lvl     = AICBT_TXPWR_LVL_DEFAULT,
+static struct aicbt_info_t aicbt_info[]={
+    {
+        .btmode        = AICBT_BTMODE_DEFAULT,
+        .btport        = AICBT_BTPORT_DEFAULT,
+        .uart_baud     = AICBT_UART_BAUD_DEFAULT,
+        .uart_flowctrl = AICBT_UART_FC_DEFAULT,
+        .lpm_enable    = AICBT_LPM_ENABLE_DEFAULT,
+        .txpwr_lvl     = AICBT_TXPWR_LVL_DEFAULT,
+    },//PRODUCT_ID_AIC8801
+    {
+        .btmode        = AICBT_BTMODE_BT_WIFI_COMBO,
+        .btport        = AICBT_BTPORT_DEFAULT,
+        .uart_baud     = AICBT_UART_BAUD_DEFAULT,
+        .uart_flowctrl = AICBT_UART_FC_DEFAULT,
+        .lpm_enable    = AICBT_LPM_ENABLE_DEFAULT,
+        .txpwr_lvl     = AICBT_TXPWR_LVL_DEFAULT_8800dc,
+    },//PRODUCT_ID_AIC8800DC
+    {
+        .btmode        = AICBT_BTMODE_BT_WIFI_COMBO,
+        .btport        = AICBT_BTPORT_DEFAULT,
+        .uart_baud     = AICBT_UART_BAUD_DEFAULT,
+        .uart_flowctrl = AICBT_UART_FC_DEFAULT,
+        .lpm_enable    = AICBT_LPM_ENABLE_DEFAULT,
+        .txpwr_lvl     = AICBT_TXPWR_LVL_DEFAULT_8800dc,
+    },//PRODUCT_ID_AIC8800DW
+    {
+        .btmode        = AICBT_BTMODE_DEFAULT_8800d80,
+        .btport        = AICBT_BTPORT_DEFAULT,
+        .uart_baud     = AICBT_UART_BAUD_DEFAULT,
+        .uart_flowctrl = AICBT_UART_FC_DEFAULT,
+        .lpm_enable    = AICBT_LPM_ENABLE_DEFAULT,
+        .txpwr_lvl     = AICBT_TXPWR_LVL_DEFAULT_8800d80,
+    }//PRODUCT_ID_AIC8800D80
 };
 
-struct aicbt_info_t aicbt_info_8800dc = {
-       .btmode            = AICBT_BTMODE_BT_WIFI_COMBO,
-       .btport            = AICBT_BTPORT_DEFAULT,
-       .uart_baud         = AICBT_UART_BAUD_DEFAULT,
-       .uart_flowctrl = AICBT_UART_FC_DEFAULT,
-       .lpm_enable    = AICBT_LPM_ENABLE_DEFAULT,
-       .txpwr_lvl         = AICBT_TXPWR_LVL_8800dc,
-};
 
 int aicbt_patch_table_load(struct aic_sdio_dev *sdiodev, struct aicbt_patch_table *head)
 {
@@ -1142,87 +1474,44 @@ int aicbt_patch_table_load(struct aic_sdio_dev *sdiodev, struct aicbt_patch_tabl
     if(head == NULL){
         return -1;
     }
-       if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800D80){
-        if (sdiodev->chipid == PRODUCT_ID_AIC8800D80) {
-            //aicbt_info.btmode = AICBT_BTMODE_BT_ONLY_COANT;
-            aicbt_info.txpwr_lvl = AICBT_TXPWR_LVL_8800d80;
-        }
-               for (p = head; p != NULL; p = p->next) {
-                       data = p->data;
-                       if (AICBT_PT_BTMODE == p->type) {
-                               *(data + 1)  = aicbsp_info.hwinfo < 0;
-                               *(data + 3)  = aicbsp_info.hwinfo;
-                               *(data + 5)  = 0;//aicbsp_info.cpmode;
-
-                               *(data + 7)  = aicbt_info.btmode;
-                               *(data + 9)  = aicbt_info.btport;
-                               *(data + 11) = aicbt_info.uart_baud;
-                               *(data + 13) = aicbt_info.uart_flowctrl;
-                               *(data + 15) = aicbt_info.lpm_enable;
-                               *(data + 17) = aicbt_info.txpwr_lvl;
-
-                               printk("%s bt btmode:%d \r\n", __func__, aicbt_info.btmode);
-                               printk("%s bt uart_baud:%d \r\n", __func__, aicbt_info.uart_baud);
-                               printk("%s bt uart_flowctrl:%d \r\n", __func__, aicbt_info.uart_flowctrl);
-                               printk("%s bt lpm_enable:%d \r\n", __func__, aicbt_info.lpm_enable);
-                               printk("%s bt tx_pwr:%d \r\n", __func__, aicbt_info.txpwr_lvl);
-                       }
 
-                       if (AICBT_PT_VER == p->type) {
-                               printk("aicbsp: bt patch version: %s\n", (char *)p->data);
-                               continue;
-                       }
+    for (p = head; p != NULL; p = p->next) {
+       data = p->data;
+       if (AICBT_PT_BTMODE == p->type) {
+               *(data + 1)  = aicbsp_info.hwinfo < 0;
+               *(data + 3)  = aicbsp_info.hwinfo;
+               *(data + 5)  = (sdiodev->chipid == PRODUCT_ID_AIC8800DC?aicbsp_info.cpmode:0);//0;//aicbsp_info.cpmode;
+
+               *(data + 7)  = aicbt_info[sdiodev->chipid].btmode;
+               *(data + 9)  = aicbt_info[sdiodev->chipid].btport;
+               *(data + 11) = aicbt_info[sdiodev->chipid].uart_baud;
+               *(data + 13) = aicbt_info[sdiodev->chipid].uart_flowctrl;
+               *(data + 15) = aicbt_info[sdiodev->chipid].lpm_enable;
+               *(data + 17) = aicbt_info[sdiodev->chipid].txpwr_lvl;
+
+            printk("%s bt btmode[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].btmode);
+               printk("%s bt uart_baud[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].uart_baud);
+               printk("%s bt uart_flowctrl[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].uart_flowctrl);
+               printk("%s bt lpm_enable[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].lpm_enable);
+               printk("%s bt tx_pwr[%d]:%d \r\n", __func__, sdiodev->chipid, aicbt_info[sdiodev->chipid].txpwr_lvl);
+       }
+
+       if (AICBT_PT_VER == p->type) {
+               printk("aicbsp: bt patch version: %s\n", (char *)p->data);
+               continue;
+       }
+
+       for (i = 0; i < p->len; i++) {
+               ret = rwnx_send_dbg_mem_write_req(sdiodev, *data, *(data + 1));
+               if (ret != 0)
+                       return ret;
+               data += 2;
+       }
+       if (p->type == AICBT_PT_PWRON)
+               udelay(500);
+    }
 
-                       for (i = 0; i < p->len; i++) {
-                               ret = rwnx_send_dbg_mem_write_req(sdiodev, *data, *(data + 1));
-                               if (ret != 0)
-                                       return ret;
-                               data += 2;
-                       }
-                       if (p->type == AICBT_PT_PWRON)
-                               udelay(500);
-               }
-       }
-       else if(sdiodev->chipid == PRODUCT_ID_AIC8800DC){
-               for (p = head; p != NULL; p = p->next) {
-                       data = p->data;
-                       if (AICBT_PT_BTMODE == p->type) {
-                               *(data + 1)  = aicbsp_info.hwinfo < 0;
-                               *(data + 3)  = aicbsp_info.hwinfo;
-                               *(data + 5)  = aicbsp_info.cpmode;
-
-                               *(data + 7)  = aicbt_info_8800dc.btmode;
-                               *(data + 9)  = aicbt_info_8800dc.btport;
-                               *(data + 11) = aicbt_info_8800dc.uart_baud;
-                               *(data + 13) = aicbt_info_8800dc.uart_flowctrl;
-                               *(data + 15) = aicbt_info_8800dc.lpm_enable;
-                               *(data + 17) = aicbt_info_8800dc.txpwr_lvl;
-
-                               printk("%s bt uart_baud:%d \r\n", __func__, aicbt_info_8800dc.uart_baud);
-                               printk("%s bt uart_flowctrl:%d \r\n", __func__, aicbt_info_8800dc.uart_flowctrl);
-                               printk("%s bt lpm_enable:%d \r\n", __func__, aicbt_info_8800dc.lpm_enable);
-                               printk("%s bt tx_pwr:%d \r\n", __func__, aicbt_info_8800dc.txpwr_lvl);
-                       }
-                       if (AICBT_PT_INF == p->type) {
-                               continue;
-                       }
-                       printk("########## p->type = %d \n",p->type);
-                       printk("AICBT_PT_VER = %d \n",AICBT_PT_VER);
-                       if (AICBT_PT_VER == p->type) {
-                               printk("aicbsp: bt patch version: %s\n", (char *)p->data);
-                               continue;
-                       }
 
-                       for (i = 0; i < p->len; i++) {
-                               ret = rwnx_send_dbg_mem_write_req(sdiodev, *data, *(data + 1));
-                               if (ret != 0)
-                                       return ret;
-                               data += 2;
-                       }
-                       if (p->type == AICBT_PT_PWRON)
-                               udelay(500);
-               }
-       }
        ///aicbt_patch_table_free(&head);
        return 0;
 }
@@ -1438,6 +1727,13 @@ int aicwifi_init(struct aic_sdio_dev *sdiodev)
 {
        int ret = 0;
        if(sdiodev->chipid == PRODUCT_ID_AIC8801){
+               #ifdef CONFIG_M2D_OTA_AUTO_SUPPORT
+               if (testmode == FW_M2D_OTA_MODE) {
+                       rwnx_plat_m2d_flash_ota_android(sdiodev, FW_M2D_OTA_NAME);
+               } else if (testmode == FW_NORMAL_MODE) {
+                       rwnx_plat_m2d_flash_ota_check(sdiodev, FW_M2D_OTA_NAME);
+               }
+               #endif
                if (rwnx_plat_bin_fw_upload_android(sdiodev, RAM_FMAC_FW_ADDR, aicbsp_firmware_list[aicbsp_info.cpmode].wl_fw)) {
                        printk("download wifi fw fail\n");
                        return -1;
@@ -1558,6 +1854,7 @@ int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev)
        u32 mem_addr;
        struct dbg_mem_read_cfm rd_mem_addr_cfm;
        u32 btenable = 0;
+       u8 is_chip_id_h = 0;
        int ret = 0;
 
        mem_addr = 0x40500000;
@@ -1589,7 +1886,8 @@ int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev)
                if (rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm))
                        return -1;
 
-               aicbsp_info.chip_rev = (u8)(rd_mem_addr_cfm.memdata >> 16);
+               aicbsp_info.chip_rev = (u8)((rd_mem_addr_cfm.memdata >> 16) & 0x3F);
+               is_chip_id_h = (u8)(((rd_mem_addr_cfm.memdata >> 16) & 0xC0) == 0xC0);
 
                btenable = ((rd_mem_addr_cfm.memdata >> 26) & 0x1);
                AICWFDBG(LOGINFO, "btenable = %d \n",btenable);
@@ -1606,10 +1904,15 @@ int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev)
                        pr_err("aicbsp: %s, unsupport chip rev: %d\n", __func__, aicbsp_info.chip_rev);
                        return -1;
                }
-               if(aicbsp_info.chip_rev == CHIP_REV_U01){
-                       aicbsp_firmware_list = fw_8800dc_u01;
-               }else{
-                       aicbsp_firmware_list = fw_8800dc_u02;
+               if (is_chip_id_h) {
+                       AICWFDBG(LOGINFO, "IS_CHIP_ID_H \n");
+                       aicbsp_firmware_list = fw_8800dc_h_u02;
+               } else {
+                       if(aicbsp_info.chip_rev == CHIP_REV_U01){
+                               aicbsp_firmware_list = fw_8800dc_u01;
+                       }else{
+                               aicbsp_firmware_list = fw_8800dc_u02;
+                       }
                }
        }
     else if(sdiodev->chipid == PRODUCT_ID_AIC8800D80){
@@ -1658,6 +1961,7 @@ int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path)
        feature->sdio_phase = FEATURE_SDIO_PHASE;
        feature->hwinfo     = aicbsp_info.hwinfo;
        feature->fwlog_en   = aicbsp_info.fwlog_en;
+       feature->irqf       = aicbsp_info.irqf;
        if(fw_path != NULL){
                sprintf(fw_path,"%s", AICBSP_FW_PATH);
        }
@@ -1666,7 +1970,7 @@ int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path)
 }
 EXPORT_SYMBOL_GPL(aicbsp_get_feature);
 
-#if AICBSP_RESV_MEM_SUPPORT
+#ifdef CONFIG_RESV_MEM_SUPPORT
 static struct skb_buff_pool resv_skb[] = {
        {AIC_RESV_MEM_TXDATA, 1536*64, "resv_mem_txdata", 0, NULL},
 };
index 6f010b1d3a3ff5d43f20860b7f17df19a5a04db1..810ed8e4dbef69f50c4cf110039c76501c71f080 100644 (file)
@@ -236,6 +236,12 @@ enum dbg_msg_tag {
        DBG_MAX,
 };
 
+#if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT)
+#define FW_M2D_OTA_NAME                 "m2d_ota.bin"
+#else
+#define FW_M2D_OTA_NAME                 "m2d_ota_lzma.bin"
+#endif
+
 enum {
        HOST_START_APP_AUTO = 1,
        HOST_START_APP_CUSTOM,
@@ -305,6 +311,7 @@ struct dbg_start_app_cfm {
 int aicwf_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev);
 int aicwf_plat_rftest_load_8800dc(struct aic_sdio_dev *sdiodev);
 #ifdef CONFIG_DPD
+int aicwf_misc_ram_valid_check_8800dc(struct aic_sdio_dev *sdiodev, int *valid_out);
 int aicwf_plat_calib_load_8800dc(struct aic_sdio_dev *sdiodev);
 #endif
 
@@ -326,7 +333,7 @@ void rwnx_rx_handle_msg(struct aic_sdio_dev *sdiodev, struct ipc_e2a_msg *msg);
 int aicbsp_platform_init(struct aic_sdio_dev *sdiodev);
 void aicbsp_platform_deinit(struct aic_sdio_dev *sdiodev);
 int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev);
-#ifdef CONFIG_DPD
+#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
 int is_file_exist(char* name);
 #endif
 int aicbsp_resv_mem_init(void);
@@ -364,10 +371,13 @@ int aicbsp_resv_mem_deinit(void);
 
 #define RWNX_MAC_CALIB_BASE_NAME_8800DC        "fmacfw_calib_8800dc"
 #define RWNX_MAC_CALIB_NAME_8800DC_U02          RWNX_MAC_CALIB_BASE_NAME_8800DC"_u02.bin"
+#define RWNX_MAC_CALIB_NAME_8800DC_H_U02        RWNX_MAC_CALIB_BASE_NAME_8800DC"_h_u02.bin"
 
 #ifdef CONFIG_DPD
 #define ROM_FMAC_CALIB_ADDR            0x00130000
-#define FW_DPDRESULT_NAME_8800DC        "aic_dpdresult_8800dc.bin"
+#ifndef CONFIG_FORCE_DPD_CALIB
+#define FW_DPDRESULT_NAME_8800DC        "aic_dpdresult_lite_8800dc.bin"
+#endif
 #endif
 
 #define RWNX_MAC_FW_RF_BASE_NAME_8800DC   "lmacfw_rf_8800dc.bin"
@@ -379,11 +389,13 @@ int aicbsp_resv_mem_deinit(void);
 #define RWNX_MAC_PATCH_BASE_NAME_8800DC        "fmacfw_patch_8800dc"
 #define RWNX_MAC_PATCH_NAME2_8800DC RWNX_MAC_PATCH_BASE_NAME_8800DC".bin"
 #define RWNX_MAC_PATCH_NAME2_8800DC_U02 RWNX_MAC_PATCH_BASE_NAME_8800DC"_u02.bin"
+#define RWNX_MAC_PATCH_NAME2_8800DC_H_U02 RWNX_MAC_PATCH_BASE_NAME_8800DC"_h_u02.bin"
 #endif
 
 #define RWNX_MAC_PATCH_TABLE_NAME_8800DC "fmacfw_patch_tbl_8800dc"
 #define RWNX_MAC_PATCH_TABLE_8800DC RWNX_MAC_PATCH_TABLE_NAME_8800DC ".bin"
 #define RWNX_MAC_PATCH_TABLE_8800DC_U02 RWNX_MAC_PATCH_TABLE_NAME_8800DC "_u02.bin"
+#define RWNX_MAC_PATCH_TABLE_8800DC_H_U02 RWNX_MAC_PATCH_TABLE_NAME_8800DC "_h_u02.bin"
 
 #define RWNX_MAC_RF_PATCH_BASE_NAME_8800DC     "fmacfw_rf_patch_8800dc"
 #define RWNX_MAC_RF_PATCH_NAME_8800DC RWNX_MAC_RF_PATCH_BASE_NAME_8800DC".bin"
@@ -456,6 +468,18 @@ enum chip_rev {
        CHIP_REV_U03 = 7,
        CHIP_REV_U04 = 7,
 };
+
+#define AIC_M2D_OTA_INFO_ADDR       0x88000020
+#define AIC_M2D_OTA_DATA_ADDR       0x88000040
+#if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT)
+#define AIC_M2D_OTA_FLASH_ADDR      0x08004000
+#define AIC_M2D_OTA_CODE_START_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x0188)
+#define AIC_M2D_OTA_VER_ADDR        (AIC_M2D_OTA_FLASH_ADDR + 0x018C)
+#else
+#define AIC_M2D_OTA_FLASH_ADDR      0x08005000
+#define AIC_M2D_OTA_CODE_START_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x1188)
+#define AIC_M2D_OTA_VER_ADDR        (AIC_M2D_OTA_FLASH_ADDR + 0x0010)
+#endif
 ///aic bt tx pwr lvl :lsb->msb: first byte, min pwr lvl; second byte, max pwr lvl;
 ///pwr lvl:20(min), 30 , 40 , 50 , 60(max)
 #define AICBT_TXPWR_LVL            0x00006020
@@ -466,13 +490,18 @@ enum chip_rev {
 #define AICBSP_CPMODE_DEFAULT       AICBSP_CPMODE_WORK
 #define AICBSP_FWLOG_EN_DEFAULT     0
 
-#define AICBT_BTMODE_DEFAULT        AICBT_BTMODE_BT_ONLY_SW
-#define AICBT_BTPORT_DEFAULT        AICBT_BTPORT_UART
-#define AICBT_UART_BAUD_DEFAULT     AICBT_UART_BAUD_1_5M
-#define AICBT_UART_FC_DEFAULT       AICBT_UART_FLOWCTRL_ENABLE
-#define AICBT_LPM_ENABLE_DEFAULT       0
-#define AICBT_TXPWR_LVL_DEFAULT    AICBT_TXPWR_LVL
+#define AICBT_BTMODE_DEFAULT_8800d80    AICBT_BTMODE_BT_ONLY_COANT
+#define AICBT_BTMODE_DEFAULT            AICBT_BTMODE_BT_ONLY_SW
+#define AICBT_BTPORT_DEFAULT            AICBT_BTPORT_UART
+#define AICBT_UART_BAUD_DEFAULT         AICBT_UART_BAUD_1_5M
+#define AICBT_UART_FC_DEFAULT           AICBT_UART_FLOWCTRL_ENABLE
+#define AICBT_LPM_ENABLE_DEFAULT           0
+#define AICBT_TXPWR_LVL_DEFAULT         AICBT_TXPWR_LVL
+#define AICBT_TXPWR_LVL_DEFAULT_8800dc  AICBT_TXPWR_LVL_8800dc
+#define AICBT_TXPWR_LVL_DEFAULT_8800d80 AICBT_TXPWR_LVL_8800d80
+
 
+#define AIC_IRQ_WAKE_FLAG           0          // 0: rising edge, 1: falling edge
 #define FEATURE_SDIO_CLOCK          50000000 // 0: default, other: target clock rate
 #define FEATURE_SDIO_CLOCK_V3       150000000 // 0: default, other: target clock rate
 #define FEATURE_SDIO_PHASE          2        // 0: default, 2: 180°
@@ -520,6 +549,7 @@ struct aicbsp_info_t {
        uint32_t cpmode;
        uint32_t chip_rev;
        bool fwlog_en;
+       uint8_t irqf;
 };
 
 extern struct aicbsp_info_t aicbsp_info;
@@ -529,6 +559,7 @@ extern const struct aicbsp_firmware fw_u02[];
 extern const struct aicbsp_firmware fw_u03[];
 extern const struct aicbsp_firmware fw_8800dc_u01[];
 extern const struct aicbsp_firmware fw_8800dc_u02[];
+extern const struct aicbsp_firmware fw_8800dc_h_u02[];
 extern const struct aicbsp_firmware fw_8800d80_u01[];
 extern const struct aicbsp_firmware fw_8800d80_u02[];
 
index 535f7bf0e1cd6a1886e6115e00ed9cc96e6c5d12..249d6ec082ea5398e39fc4db53dec2fd19b99397 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef __AIC_BSP_EXPORT_H
 #define __AIC_BSP_EXPORT_H
 
-#define AICBSP_RESV_MEM_SUPPORT 0
-
 enum aicbsp_subsys {
        AIC_BLUETOOTH,
        AIC_WIFI,
@@ -30,8 +28,35 @@ struct aicbsp_feature_t {
        uint32_t sdio_clock;
        uint8_t  sdio_phase;
        bool     fwlog_en;
+       uint8_t  irqf;
 };
 
+#ifdef CONFIG_DPD
+typedef struct {
+    uint32_t bit_mask[3];
+    uint32_t reserved;
+    uint32_t dpd_high[96];
+    uint32_t dpd_11b[96];
+    uint32_t dpd_low[96];
+    uint32_t idac_11b[48];
+    uint32_t idac_high[48];
+    uint32_t idac_low[48];
+    uint32_t loft_res[18];
+    uint32_t rx_iqim_res[16];
+} rf_misc_ram_t;
+
+typedef struct {
+    uint32_t bit_mask[4];
+    uint32_t dpd_high[96];
+    uint32_t loft_res[18];
+} rf_misc_ram_lite_t;
+
+#define MEMBER_SIZE(type, member)   sizeof(((type *)0)->member)
+#define DPD_RESULT_SIZE_8800DC      sizeof(rf_misc_ram_lite_t)
+
+extern rf_misc_ram_lite_t dpd_res;
+#endif
+
 int aicbsp_set_subsys(int, int);
 int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path);
 struct sk_buff *aicbsp_resv_mem_alloc_skb(unsigned int length, uint32_t id);
index cf2c3a7d9fa6b8828df453ab9f809d2fc5b2c144..5e144c8c116979af4934509bbea595f5c59c71ed 100644 (file)
@@ -99,6 +99,25 @@ const struct aicbsp_firmware fw_8800dc_u02[] = {
        },
 };
 
+const struct aicbsp_firmware fw_8800dc_h_u02[] = {
+       [AICBSP_CPMODE_WORK] = {
+               .desc          = "normal work mode(8800dc_h sdio u02)",
+               .bt_adid       = "fw_adid_8800dc_u02h.bin",
+               .bt_patch      = "fw_patch_8800dc_u02h.bin",
+               .bt_table      = "fw_patch_table_8800dc_u02h.bin",
+               .wl_fw         = "fmacfw_patch_8800dc_h_u02.bin"
+       },
+
+       [AICBSP_CPMODE_TEST] = {
+               .desc          = "rf test mode(8800dc_h sdio u02)",
+               .bt_adid       = "fw_adid_8800dc_u02h.bin",
+               .bt_patch      = "fw_patch_8800dc_u02h.bin",
+               .bt_table      = "fw_patch_table_8800dc_u02h.bin",
+               .wl_fw         = "lmacfw_rf_8800dc.bin" //u01,u02 lmacfw load same bin
+       },
+};
+
+
 const struct aicbsp_firmware fw_8800d80_u01[] = {
        [AICBSP_CPMODE_WORK] = {
                .desc          = "normal work mode(8800d80 sdio u01)",
@@ -140,6 +159,7 @@ struct aicbsp_info_t aicbsp_info = {
        .hwinfo   = AICBSP_HWINFO_DEFAULT,
        .cpmode   = AICBSP_CPMODE_DEFAULT,
        .fwlog_en = AICBSP_FWLOG_EN_DEFAULT,
+       .irqf     = AIC_IRQ_WAKE_FLAG,
 };
 
 struct mutex aicbsp_power_lock;
index 2e50ac995947407c9616d0c1e2c24ee1f137742f..c27e61a8717a6177b31dea84968ca72ff31017b9 100644 (file)
@@ -23,6 +23,9 @@
 #ifdef CONFIG_PLATFORM_ROCKCHIP
 #include <linux/rfkill-wlan.h>
 #endif /* CONFIG_PLATFORM_ROCKCHIP */
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+#include <linux/rfkill-wlan.h>
+#endif /* CONFIG_PLATFORM_ROCKCHIP */
 
 
 #ifdef CONFIG_PLATFORM_ALLWINNER
@@ -57,6 +60,10 @@ static const char* aic_default_fw_path = CONFIG_AIC_FW_PATH;
 //#endif
 char aic_fw_path[FW_PATH_MAX];
 module_param_string(aic_fw_path, aic_fw_path, FW_PATH_MAX, 0660);
+#ifdef CONFIG_M2D_OTA_AUTO_SUPPORT
+char saved_sdk_ver[64];
+module_param_string(saved_sdk_ver, saved_sdk_ver,64, 0660);
+#endif
 
 extern int testmode;
 
@@ -79,8 +86,8 @@ static int aicbsp_dummy_probe(struct sdio_func *func, const struct sdio_device_i
        if (func && (func->num != 2))
                return 0;
 
-       if(func->vendor != SDIO_VENDOR_ID_AIC8801 && 
-               func->device != SDIO_DEVICE_ID_AIC8801 && 
+       if(func->vendor != SDIO_VENDOR_ID_AIC8801 &&
+               func->device != SDIO_DEVICE_ID_AIC8801 &&
                func->device != SDIO_DEVICE_ID_AIC8801_FUNC2 &&
                func->vendor != SDIO_VENDOR_ID_AIC8800DC &&
                func->device != SDIO_DEVICE_ID_AIC8800DC &&
@@ -137,6 +144,12 @@ void rfkill_rk_sleep_bt(bool sleep);
 #endif
 #endif
 
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+#if 1//FOR RK SUSPEND
+void rfkill_rk_sleep_bt(bool sleep);
+#endif
+#endif
+
 int aicbsp_set_subsys(int subsys, int state)
 {
        static int pre_power_map;
@@ -177,7 +190,15 @@ int aicbsp_set_subsys(int subsys, int state)
                        printk("%s BT wake default to SLEEP\r\n", __func__);
 #endif
 #endif
-                       
+
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+#ifdef CONFIG_GPIO_WAKEUP
+                       //BT_SLEEP:true,BT_WAKEUP:false
+                       rfkill_rk_sleep_bt(true);
+                       printk("%s BT wake default to SLEEP\r\n", __func__);
+#endif
+#endif
+
 //#ifndef CONFIG_PLATFORM_ROCKCHIP
 //                     aicbsp_sdio_exit();
 //#endif
@@ -210,7 +231,7 @@ err0:
 EXPORT_SYMBOL_GPL(aicbsp_set_subsys);
 
 bool aicbsp_get_load_fw_in_fdrv(void){
-       return aicbsp_load_fw_in_fdrv; 
+       return aicbsp_load_fw_in_fdrv;
 }
 
 EXPORT_SYMBOL_GPL(aicbsp_get_load_fw_in_fdrv);
@@ -254,8 +275,8 @@ static int aicbsp_sdio_probe(struct sdio_func *func,
        sdio_dbg("%s:%d vid:0x%04X  did:0x%04X\n", __func__, func->num,
                func->vendor, func->device);
 
-       if(func->vendor != SDIO_VENDOR_ID_AIC8801 && 
-               func->device != SDIO_DEVICE_ID_AIC8801 && 
+       if(func->vendor != SDIO_VENDOR_ID_AIC8801 &&
+               func->device != SDIO_DEVICE_ID_AIC8801 &&
                func->device != SDIO_DEVICE_ID_AIC8801_FUNC2 &&
                func->vendor != SDIO_VENDOR_ID_AIC8800DC &&
                func->device != SDIO_DEVICE_ID_AIC8800DC &&
@@ -280,7 +301,7 @@ static int aicbsp_sdio_probe(struct sdio_func *func,
                return -ENOMEM;
        }
 
-    
+
        sdiodev = kzalloc(sizeof(struct aic_sdio_dev), GFP_KERNEL);
        if (!sdiodev) {
                sdio_err("alloc sdiodev fail\n");
@@ -343,7 +364,7 @@ static void aicbsp_sdio_remove(struct sdio_func *func)
        }
 
     bus_if = aicbsp_get_drvdata(&func->dev);
-       
+
        if (!bus_if) {
         AICWFDBG(LOGERROR, "%s bus_if is NULL \r\n", __func__);
                return;
@@ -374,12 +395,19 @@ static int aicbsp_sdio_suspend(struct device *dev)
        struct sdio_func *func = dev_to_sdio_func(dev);
        int err;
        mmc_pm_flag_t sdio_flags;
-    
+
 #ifdef CONFIG_PLATFORM_ROCKCHIP
 #ifdef CONFIG_GPIO_WAKEUP
     //BT_SLEEP:true,BT_WAKEUP:false
     rfkill_rk_sleep_bt(false);
 #endif
+#endif
+
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+#ifdef CONFIG_GPIO_WAKEUP
+        //BT_SLEEP:true,BT_WAKEUP:false
+        rfkill_rk_sleep_bt(false);
+#endif
 #endif
 
        sdio_dbg("%s, func->num = %d\n", __func__, func->num);
@@ -407,6 +435,14 @@ static int aicbsp_sdio_suspend(struct device *dev)
 #endif
 #endif
 
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+#ifdef CONFIG_GPIO_WAKEUP
+            //BT_SLEEP:true,BT_WAKEUP:false
+            rfkill_rk_sleep_bt(true);
+            printk("%s BT wake to SLEEP\r\n", __func__);
+#endif
+#endif
+
 
        return 0;
 }
@@ -461,6 +497,13 @@ static int aicbsp_platform_power_on(void)
                set_power_control_lock(1);
 #endif
 
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+            rockchip_wifi_power(0);
+            mdelay(50);
+            rockchip_wifi_power(1);
+            mdelay(50);
+            rockchip_wifi_set_carddetect(1);
+#endif /*CONFIG_PLATFORM_ROCKCHIP2*/
 
        sema_init(&aic_chipup_sem, 0);
        ret = aicbsp_reg_sdio_notify(&aic_chipup_sem);
@@ -468,7 +511,7 @@ static int aicbsp_platform_power_on(void)
                sdio_dbg("%s aicbsp_reg_sdio_notify fail(%d)\n", __func__, ret);
                        return ret;
        }
-       
+
 #ifdef CONFIG_PLATFORM_ALLWINNER
        sunxi_wlan_set_power(0);
        mdelay(50);
@@ -477,12 +520,6 @@ static int aicbsp_platform_power_on(void)
        sunxi_mmc_rescan_card(aicbsp_bus_index);
 #endif //CONFIG_PLATFORM_ALLWINNER
 
-#ifdef CONFIG_PLATFORM_ROCKCHIP
-//             rockchip_wifi_power(1);
-//             mdelay(200);
-//             rockchip_wifi_set_carddetect(1);
-#endif /*CONFIG_PLATFORM_ROCKCHIP*/
-
        if (down_timeout(&aic_chipup_sem, msecs_to_jiffies(2000)) == 0) {
                aicbsp_unreg_sdio_notify();
                if(aicbsp_load_fw_in_fdrv){
@@ -491,7 +528,7 @@ static int aicbsp_platform_power_on(void)
                }
                return 0;
        }
-       
+
        aicbsp_unreg_sdio_notify();
 #ifdef CONFIG_PLATFORM_ALLWINNER
        sunxi_wlan_set_power(0);
@@ -502,9 +539,9 @@ static int aicbsp_platform_power_on(void)
 #endif
 
 
-#ifdef CONFIG_PLATFORM_ROCKCHIP
-//     rockchip_wifi_power(0);
-#endif /*CONFIG_PLATFORM_ROCKCHIP*/
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+       rockchip_wifi_power(0);
+#endif /*CONFIG_PLATFORM_ROCKCHIP2*/
 
        return -1;
 }
@@ -524,11 +561,11 @@ static void aicbsp_platform_power_off(void)
        sunxi_mmc_rescan_card(aicbsp_bus_index);
 #endif //CONFIG_PLATFORM_ALLWINNER
 
-#ifdef CONFIG_PLATFORM_ROCKCHIP
-//     rockchip_wifi_set_carddetect(0);
-//     mdelay(200);
-//     rockchip_wifi_power(0);
-//     mdelay(200);            
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+       rockchip_wifi_set_carddetect(0);
+       mdelay(200);
+       rockchip_wifi_power(0);
+       mdelay(200);
 #endif /*CONFIG_PLATFORM_ROCKCHIP*/
 #ifdef CONFIG_PLATFORM_AMLOGIC
        extern_wifi_set_enable(0);
@@ -698,7 +735,7 @@ int aicwf_sdio_wakeup(struct aic_sdio_dev *sdiodev)
        int ret = 0;
        int read_retry;
        int write_retry = 20;
-    int wakeup_reg_val;
+    int wakeup_reg_val = 0;
 
     if (sdiodev->chipid == PRODUCT_ID_AIC8801 ||
         sdiodev->chipid == PRODUCT_ID_AIC8800DC ||
@@ -1608,7 +1645,7 @@ void aicwf_sdio_reg_init(struct aic_sdio_dev *sdiodev)
 {
     sdio_dbg("%s\n", __func__);
 
-    if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC || 
+    if(sdiodev->chipid == PRODUCT_ID_AIC8801 || sdiodev->chipid == PRODUCT_ID_AIC8800DC ||
        sdiodev->chipid == PRODUCT_ID_AIC8800DW){
         sdiodev->sdio_reg.bytemode_len_reg =       SDIOWIFI_BYTEMODE_LEN_REG;
         sdiodev->sdio_reg.intr_config_reg =        SDIOWIFI_INTR_CONFIG_REG;
@@ -1900,7 +1937,7 @@ void get_fw_path(char* fw_path){
        }else{
                memcpy(fw_path, aic_default_fw_path, strlen(aic_default_fw_path));
        }
-} 
+}
 
 int get_testmode(void){
        return testmode;
index fc098af5baef98f94eaa0224dfd23379994d268f..9514c416b5d6013cf7c479ea189d46670f6995ce 100644 (file)
@@ -9,7 +9,7 @@ struct prealloc_txq{
 };
 
 struct prealloc_txq prealloc_txq;
-#define MAX_TXQ_SIZE 30 * 1024
+#define MAX_TXQ_SIZE 100 * 1024
 
 void *aicwf_prealloc_txq_alloc(size_t size)
 {
index 668212830fca13c65ee99faf10c0b60b3e4dab28..e2d038e8802eed7b61937755996c731b5583ff32 100644 (file)
@@ -1,4 +1,4 @@
 #define RWNX_VERS_REV "241c091M (master)"
 #define RWNX_VERS_MOD "6.4.3.0"
 #define RWNX_VERS_BANNER "rwnx v6.4.3.0 - - 241c091M (master)"
-#define RELEASE_DATE "2023_0904_1726"
+#define RELEASE_DATE "2023_1212_15dcf017"
diff --git a/drivers/net/wireless/aic8800/aic8800_btlpm/.gitignore b/drivers/net/wireless/aic8800/aic8800_btlpm/.gitignore
new file mode 100644 (file)
index 0000000..c3c2d15
--- /dev/null
@@ -0,0 +1,10 @@
+*.o
+*.ko
+*.order
+*.symvers
+*.o.d
+*.o.cmd
+*.ko.cmd
+*.mod
+*.mod.c
+*.mod.cmd
index 028d2dc8abd3de5f1ab0186b844f1cbd427ee824..cd63d62b98d23dae6741e23aae9df9ad9a948948 100644 (file)
@@ -4,19 +4,29 @@ obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) := aic8800_btlpm.o
 
 ccflags-y += -I$(srctree)/$(src)/../aic8800_bsp
 
-aic8800_btlpm-y := \
-       aic_bluetooth_main.o \
-       rfkill.o \
-       lpm.o
-
 # Platform support list
 CONFIG_PLATFORM_ROCKCHIP ?= n
+CONFIG_PLATFORM_ROCKCHIP2 ?= n
 CONFIG_PLATFORM_ALLWINNER ?= n
 CONFIG_PLATFORM_AMLOGIC ?= n
 CONFIG_PLATFORM_UBUNTU ?= y
 
+
+CONFIG_SUPPORT_LPM = y
+CONFIG_AUTO_PM ?= n
+
+aic8800_btlpm-y := \
+       aic_bluetooth_main.o \
+       rfkill.o \
+
+ifeq ($(CONFIG_PLATFORM_UBUNTU), n)
+       aic8800_btlpm-$(CONFIG_SUPPORT_LPM) += lpm.o
+endif
+
 ccflags-y += -DAIC_TRACE_INCLUDE_PATH=$(src)
 
+ccflags-$(CONFIG_AUTO_PM) += -DCONFIG_AUTO_PM
+
 ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
 KDIR  ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/kernel
 ARCH ?= arm
@@ -38,6 +48,14 @@ ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
 ccflags-y += -DANDROID_PLATFORM
 endif
 
+ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
+ARCH = arm64
+KDIR = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
+CROSS_COMPILE = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
+ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2
+ccflags-y += -DANDROID_PLATFORM
+endif
+
 ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
 ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
 KDIR  ?= /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/kernel/linux-4.9/
index f69937c8e16e3adb49fff48dff6e05c868268323..52d768d83da8038ec9664888d118e90af095b53b 100644 (file)
@@ -44,6 +44,8 @@
 #include <linux/wakelock.h>
 #endif
 
+#include "aic_bsp_export.h"
+
 /*
  * #define BT_SLEEP_DBG
  */
@@ -407,6 +409,24 @@ static ssize_t bluesleep_write_proc_btwrite(struct file *file,
        return count;
 }
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
+static const struct proc_ops lpm_fops = {
+       .proc_open    = bluesleep_lpm_proc_open,
+       .proc_read    = seq_read,
+       .proc_lseek   = seq_lseek,
+       .proc_release = single_release,
+       .proc_write   = bluesleep_write_proc_lpm,
+};
+static const struct proc_ops btwrite_fops = {
+       .proc_open    = bluesleep_btwrite_proc_open,
+       .proc_read    = seq_read,
+       .proc_lseek   = seq_lseek,
+       .proc_release = single_release,
+       .proc_write   = bluesleep_write_proc_btwrite,
+};
+
+#else
+
 static const struct file_operations lpm_fops = {
        .owner          = THIS_MODULE,
        .open           = bluesleep_lpm_proc_open,
@@ -423,6 +443,8 @@ static const struct file_operations btwrite_fops = {
        .release        = single_release,
        .write          = bluesleep_write_proc_btwrite,
 };
+#endif
+
 #else
 /**
  * Handles HCI device events.
@@ -773,6 +795,7 @@ static int __init bluesleep_probe(struct platform_device *pdev)
        enum of_gpio_flags config;
        int ret, uart_index;
        u32 val;
+       struct aicbsp_feature_t bsp_feature_lpm;
 
        bsi = devm_kzalloc(&pdev->dev, sizeof(struct bluesleep_info),
                        GFP_KERNEL);
@@ -787,7 +810,12 @@ static int __init bluesleep_probe(struct platform_device *pdev)
        }
 
        /* set host_wake_assert */
-       bsi->host_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 0 : 1;
+       aicbsp_get_feature(&bsp_feature_lpm);
+       if (bsp_feature_lpm.irqf == 0)
+               bsi->host_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 0 : 1;
+       else
+               bsi->host_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 1 : 0;
+
        BT_DBG("bt_hostwake gpio=%d assert=%d\n", bsi->host_wake, bsi->host_wake_assert);
 
        if (assert_level != -1) {
@@ -816,6 +844,7 @@ static int __init bluesleep_probe(struct platform_device *pdev)
 #endif
                BT_DBG("wakeup source is disabled!\n");
        } else {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
                ret = device_init_wakeup(dev, true);
                if (ret < 0) {
                        BT_ERR("device init wakeup failed!\n");
@@ -828,6 +857,9 @@ static int __init bluesleep_probe(struct platform_device *pdev)
                        goto err2;
                }
                bsi->wakeup_enable = 1;
+#else
+                       BT_ERR("%s kernel unsupport this feature!\r\n", __func__);
+#endif
        }
 
        bsi->ext_wake = of_get_named_gpio_flags(np, "bt_wake", 0, &config);
@@ -929,26 +961,52 @@ static int bluesleep_remove(struct platform_device *pdev)
 #else
        wake_lock_destroy(&bsi->wake_lock);
 #endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
        if (bsi->wakeup_enable) {
                BT_DBG("Deinit wakeup source");
                device_init_wakeup(&pdev->dev, false);
                dev_pm_clear_wake_irq(&pdev->dev);
        }
+#else
+       BT_ERR("%s kernel unsupport this feature!\r\n", __func__);
+#endif
+       return 0;
+}
 
+#ifdef CONFIG_AUTO_PM
+static int bluesleep_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       printk("%s\n", __func__);
+
+       bluesleep_tx_allow_sleep();
        return 0;
 }
 
+static int bluesleep_resume(struct platform_device *pdev)
+{
+       printk("%s\n", __func__);
+
+       bluesleep_outgoing_data();
+       return 0;
+}
+#endif
+
 static const struct of_device_id sunxi_btlpm_ids[] = {
        { .compatible = "allwinner,sunxi-btlpm" },
        { /* Sentinel */ }
 };
 
 static struct platform_driver bluesleep_driver = {
-       .remove = bluesleep_remove,
-       .driver = {
-               .owner  = THIS_MODULE,
-               .name   = "sunxi-btlpm",
-               .of_match_table = sunxi_btlpm_ids,
+       .remove             = bluesleep_remove,
+#ifdef CONFIG_AUTO_PM
+       .suspend            = bluesleep_suspend,
+       .resume             = bluesleep_resume,
+#endif
+       .driver             = {
+               .owner          = THIS_MODULE,
+               .name           = "sunxi-btlpm",
+               .of_match_table = sunxi_btlpm_ids,
        },
 };
 
index 603f67e9a815133c32c9b9ffe47b9de6d0edfc64..122d867f0ed685f8a302a9b0dcad45abc2145b57 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/kernel.h>
 #include <linux/version.h>
 #include <linux/platform_device.h>
-//#include "lpm.h"
+#include "lpm.h"
 #include "rfkill.h"
 
 #define DRV_CONFIG_FW_NAME    "fw.bin"
@@ -47,7 +47,7 @@ static int __init aic_bluetooth_mod_init(void)
                pr_err("rfkill init fail\n");
                goto err1;
        }
-#if 0
+#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2)
        ret = bluesleep_init(aicbt_pdev);
        if (ret) {
                pr_err("bluesleep init fail\n");
@@ -57,7 +57,9 @@ static int __init aic_bluetooth_mod_init(void)
 
        return 0;
 
-//err2:
+#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2)
+err2:
+#endif
        rfkill_bluetooth_remove(aicbt_pdev);
 err1:
        platform_device_del(aicbt_pdev);
@@ -69,7 +71,9 @@ err0:
 static void __exit aic_bluetooth_mod_exit(void)
 {
        printk("%s\n", __func__);
-       //bluesleep_exit(aicbt_pdev);
+#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2)
+       bluesleep_exit(aicbt_pdev);
+#endif
        rfkill_bluetooth_remove(aicbt_pdev);
        platform_device_del(aicbt_pdev);
        platform_driver_unregister(&aicbt_driver);
index 0c4b588d85c6b122b7daeb38acaa3ca1592ce7f1..88f6b565cd5f73f06205bfcbe4403ffe1e840bb8 100644 (file)
@@ -10,6 +10,7 @@ struct aicbsp_feature_t {
        bool band_5g_support;
        uint32_t sdio_clock;
        uint8_t  sdio_phase;
+       uint8_t irqf;
 };
 
 int aicbsp_set_subsys(int, int);
index 26195f472c69dbe960d14635dffb8cecf7b06a07..6e9b71564f19dd086c16eaa2adeaabf11bd5f448 100644 (file)
@@ -146,7 +146,7 @@ static unsigned long flags;
 static struct tasklet_struct hostwake_task;
 
 /** Reception timer */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
 static void bluesleep_rx_timer_expire(struct timer_list *t);
 #else
 static void bluesleep_rx_timer_expire(unsigned long data);
@@ -485,7 +485,7 @@ static void bluesleep_tx_allow_sleep(void)
  * Clear BT_RXTIMER.
  * @param data Not used.
  */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
 static void bluesleep_rx_timer_expire(struct timer_list *t)
 #else
 static void bluesleep_rx_timer_expire(unsigned long data)
@@ -896,7 +896,13 @@ static int bluesleep_probe(struct platform_device *pdev)
        bluesleep_uart_dev = sw_uart_get_pdev(uart_index);
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
-       bsi->ws = wakeup_source_register(dev, "bluesleep");
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
+    bsi->ws = wakeup_source_register(dev, "bluesleep");
+#else
+       bsi->ws = wakeup_source_register("bluesleep");
+#endif
+
 #else
        wake_lock_init(&bsi->wake_lock, WAKE_LOCK_SUSPEND, "bluesleep");
 #endif
@@ -1045,7 +1051,7 @@ int bluesleep_init(struct platform_device *pdev)
        spin_lock_init(&rw_lock);
 
        /* Initialize timer */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
        timer_setup(&rx_timer, bluesleep_rx_timer_expire, 0);
 #else
        init_timer(&rx_timer);
diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/.gitignore b/drivers/net/wireless/aic8800/aic8800_fdrv/.gitignore
new file mode 100644 (file)
index 0000000..c3c2d15
--- /dev/null
@@ -0,0 +1,10 @@
+*.o
+*.ko
+*.order
+*.symvers
+*.o.d
+*.o.cmd
+*.ko.cmd
+*.mod
+*.mod.c
+*.mod.cmd
index 623643e641986916c6ebe2c691018136943cc53f..74957daef8d01ce66759662f735c7aee42dff33f 100644 (file)
@@ -1,8 +1,15 @@
+EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS)
+EXTRA_CFLAGS += -Wno-implicit-fallthrough
+#EXTRA_CFLAGS += -Wno-unused-function
+#EXTRA_CFLAGS += -Wno-maybe-uninitialized
+#EXTRA_CFLAGS += -Wno-unused-variable
+
 RWNX_VERS_NUM := 6.4.3.0
 
 CONFIG_COUNTRY_CODE = "00"
 
 MODULE_NAME = aic8800_fdrv
+CONFIG_AIC8800_WLAN_SUPPORT = m
 
 # Support of bootrom start
 CONFIG_START_FROM_BOOTROM = y
@@ -69,7 +76,7 @@ CONFIG_USB_BT =y
 CONFIG_USE_5G ?= y
 CONFIG_SDIO_PWRCTRL ?= y
 CONFIG_CREATE_TRACE_POINTS = n
-CONFIG_TXRX_THREAD_PRIO = n
+CONFIG_TXRX_THREAD_PRIO = y
 # CONFIG_COEX = n for BT_ONLY, CONFIG_COEX =y for combo and sw
 CONFIG_COEX = y
 CONFIG_RX_NETIF_RECV_SKB = y
@@ -87,12 +94,16 @@ CONFIG_USE_P2P0=n
 CONFIG_BR_SUPPORT =n
 BR_NAME = br0
 CONFIG_FDRV_NO_REG_SDIO=n
-CONFIG_SCHED_SCAN = y
+CONFIG_SCHED_SCAN = n
 CONFIG_OOB = n
 CONFIG_USE_CUSTOMER_MAC = n
 CONFIG_PREALLOC_TXQ = y
-CONFIG_DPD = n
-CONFIG_FORCE_DPD_CALIB = n
+CONFIG_DPD = y
+CONFIG_FORCE_DPD_CALIB = y
+CONFIG_FILTER_TCP_ACK =n
+CONFIG_RESV_MEM_SUPPORT = y
+CONFIG_GKI = n
+CONFIG_TEMP_COMP = n
 
 # Support of MU-MIMO transmission (need FW support)
 ifeq ($(CONFIG_RWNX_BFMER), y)
@@ -117,7 +128,6 @@ CONFIG_DEBUG_FS ?= n
 
 obj-$(CONFIG_AIC8800_WLAN_SUPPORT) := $(MODULE_NAME).o
 $(MODULE_NAME)-y := \
-       rwnx_gki.o             \
        rwnx_msg_tx.o          \
        rwnx_msg_rx.o          \
        rwnx_utils.o           \
@@ -155,10 +165,14 @@ $(MODULE_NAME)-$(CONFIG_RWNX_MUMIMO_TX)   += rwnx_mu_group.o
 $(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT)     += sdio_host.o
 $(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT)     += aicwf_txrxif.o
 $(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT)     += aicwf_sdio.o
+$(MODULE_NAME)-$(CONFIG_FILTER_TCP_ACK)   += aicwf_tcp_ack.o
 
 $(MODULE_NAME)-$(CONFIG_USB_SUPPORT)     += usb_host.o
 $(MODULE_NAME)-$(CONFIG_USB_SUPPORT)     += aicwf_txrxif.o
 $(MODULE_NAME)-$(CONFIG_USB_SUPPORT)     += aicwf_usb.o
+$(MODULE_NAME)-$(CONFIG_GKI)     += rwnx_gki.o
+
+
 
 ccflags-$(CONFIG_DEBUG_FS) += -DCONFIG_RWNX_DEBUGFS
 ccflags-$(CONFIG_DEBUG_FS) += -DCONFIG_RWNX_UM_HELPER_DFLT=\"$(CONFIG_RWNX_UM_HELPER_DFLT)\"
@@ -231,6 +245,10 @@ ccflags-$(CONFIG_USE_CUSTOMER_MAC) += -DCONFIG_USE_CUSTOMER_MAC
 ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ
 ccflags-$(CONFIG_DPD) += -DCONFIG_DPD
 ccflags-$(CONFIG_FORCE_DPD_CALIB) += -DCONFIG_FORCE_DPD_CALIB -DCONFIG_DPD
+ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK
+ccflags-$(CONFIG_RESV_MEM_SUPPORT) += -DCONFIG_RESV_MEM_SUPPORT
+ccflags-$(CONFIG_GKI) += -DCONFIG_GKI
+ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP
 
 
 ifeq ($(CONFIG_SDIO_SUPPORT), y)
@@ -272,6 +290,7 @@ ccflags-$(CONFIG_RX_NETIF_RECV_SKB) += -DCONFIG_RX_NETIF_RECV_SKB
 
 # Platform support list
 CONFIG_PLATFORM_ROCKCHIP ?= n
+CONFIG_PLATFORM_ROCKCHIP2 ?= n
 CONFIG_PLATFORM_ALLWINNER ?= n
 CONFIG_PLATFORM_INGENIC_T20 ?= n
 CONFIG_PLATFORM_AMLOGIC ?= n
@@ -307,6 +326,16 @@ ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
 ccflags-y += -DANDROID_PLATFORM
 endif
 
+ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
+ARCH := arm64
+KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
+CROSS_COMPILE := /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
+
+ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2
+ccflags-y += -DANDROID_PLATFORM
+endif
+
+
 ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
 ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
 ccflags-y += -DANDROID_PLATFORM
index adf8f55ec1877be4155894054858511a440c8f16..bd806fad593505861bfed766ff225668efdd8b0b 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef __AIC_BSP_EXPORT_H
 #define __AIC_BSP_EXPORT_H
 
-#define AICBSP_RESV_MEM_SUPPORT 0
-
 enum aicbsp_subsys {
        AIC_BLUETOOTH,
        AIC_WIFI,
@@ -17,13 +15,40 @@ struct aicbsp_feature_t {
        int      hwinfo;
        uint32_t sdio_clock;
        uint8_t  sdio_phase;
-    int fwlog_en;
+       int fwlog_en;
+       uint8_t irqf;
 };
 
 enum skb_buff_id {
        AIC_RESV_MEM_TXDATA,
 };
 
+#ifdef CONFIG_DPD
+typedef struct {
+    uint32_t bit_mask[3];
+    uint32_t reserved;
+    uint32_t dpd_high[96];
+    uint32_t dpd_11b[96];
+    uint32_t dpd_low[96];
+    uint32_t idac_11b[48];
+    uint32_t idac_high[48];
+    uint32_t idac_low[48];
+    uint32_t loft_res[18];
+    uint32_t rx_iqim_res[16];
+} rf_misc_ram_t;
+
+typedef struct {
+    uint32_t bit_mask[4];
+    uint32_t dpd_high[96];
+    uint32_t loft_res[18];
+} rf_misc_ram_lite_t;
+
+#define MEMBER_SIZE(type, member)   sizeof(((type *)0)->member)
+#define DPD_RESULT_SIZE_8800DC      sizeof(rf_misc_ram_lite_t)
+
+extern rf_misc_ram_lite_t dpd_res;
+#endif
+
 int aicbsp_set_subsys(int, int);
 int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path);
 bool aicbsp_get_load_fw_in_fdrv(void);
index 6e8469d6454274d74b869a1ac7c70f16f85f327e..0cc6d5a392b55243e8f53a8b877386b815f44974 100644 (file)
@@ -658,7 +658,7 @@ aicwf_cfg80211_subcmd_set_mac_policy[WIFI_VENDOR_ATTR_DRIVER_MAX + 1] = {
        [0] = {.type = NLA_UNSPEC },
        [WIFI_VENDOR_ATTR_DRIVER_MAC_ADDR] = { .type = NLA_MSECS, .len  = ETH_ALEN },
 };
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
 static int aicwf_dump_interface(struct wiphy *wiphy,
                                struct wireless_dev *wdev, struct sk_buff *skb,
                                const void *data, int data_len,
@@ -666,7 +666,9 @@ static int aicwf_dump_interface(struct wiphy *wiphy,
 {
        return 0;
 }
+#endif
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
 const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
        {
                {
@@ -675,7 +677,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_start_mkeep_alive,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = aicwf_cfg80211_mkeep_alive_policy,
                .maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX
@@ -688,7 +692,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_stop_mkeep_alive,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = aicwf_cfg80211_mkeep_alive_policy,
                .maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX
@@ -701,7 +707,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_get_ver,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = aicwf_cfg80211_logger_policy,
                .maxattr = LOGGER_ATTRIBUTE_MAX
@@ -714,7 +722,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_subcmd_get_channel_list,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = aicwf_cfg80211_subcmd_policy,
                .maxattr = GSCAN_ATTRIBUTE_MAX
@@ -727,7 +737,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_subcmd_set_country_code,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = aicwf_cfg80211_andr_wifi_policy,
                .maxattr = ANDR_WIFI_ATTRIBUTE_MAX
@@ -740,7 +752,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV |  WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_logger_trigger_memory_dump,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = VENDOR_CMD_RAW_DATA,
 #endif
@@ -752,7 +766,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV |  WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_subcmd_get_feature_set,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = VENDOR_CMD_RAW_DATA,
 #endif
@@ -764,7 +780,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV |  WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_logger_get_feature,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = VENDOR_CMD_RAW_DATA,
 #endif
@@ -776,7 +794,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV |  WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_logger_get_ring_status,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = VENDOR_CMD_RAW_DATA,
 #endif
@@ -788,7 +808,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV |  WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_logger_start_logging,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = aicwf_cfg80211_logger_policy,
                .maxattr = LOGGER_ATTRIBUTE_MAX
@@ -801,7 +823,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV |  WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_logger_get_ring_data,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = aicwf_cfg80211_logger_policy,
                .maxattr = LOGGER_ATTRIBUTE_MAX
@@ -814,7 +838,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV |  WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_logger_get_wake_reason_stats,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = VENDOR_CMD_RAW_DATA,
 #endif
@@ -826,7 +852,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV |  WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = aicwf_vendor_apf_subcmd_get_capabilities,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = VENDOR_CMD_RAW_DATA,
 #endif
@@ -838,7 +866,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
                .doit = aicwf_vendor_sub_cmd_set_mac,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
                .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
                .policy = aicwf_cfg80211_subcmd_set_mac_policy,
                .maxattr = WIFI_VENDOR_ATTR_DRIVER_MAX,
@@ -851,7 +881,9 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
         },
         .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
         .doit = aicwf_vendor_sub_cmd_set_mac,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
         .dumpit = aicwf_dump_interface,
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
         .policy = aicwf_cfg80211_subcmd_set_mac_policy,
         .maxattr = WIFI_VENDOR_ATTR_DRIVER_MAX,
index 337fe6266409106934e204612c1a21689e1a4279..f817fc0428df0680e23c5e8f253b27a36508f717 100644 (file)
@@ -1,14 +1,12 @@
 #include "rwnx_main.h"
 #include "rwnx_msg_tx.h"
 #include "reg_access.h"
+#include "aic_bsp_export.h"
 
 #define RWNX_MAC_RF_PATCH_BASE_NAME_8800DC     "fmacfw_rf_patch_8800dc"
 #define RWNX_MAC_RF_PATCH_NAME_8800DC RWNX_MAC_RF_PATCH_BASE_NAME_8800DC".bin"
 #define FW_USERCONFIG_NAME_8800DC         "aic_userconfig_8800dc.txt"
 #define FW_USERCONFIG_NAME_8800DW         "aic_userconfig_8800dw.txt"
-#ifdef CONFIG_DPD
-#define FW_DPDRESULT_NAME_8800DC        "aic_dpdresult_8800dc.bin"
-#endif
 
 int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
                                char *filename);
@@ -296,18 +294,25 @@ u32 wifi_rxgain_table_24g_40m_8800dcdw[64] = {
     0x000000f0
 };
 
-#ifdef CONFIG_DPD
 #define RAM_LMAC_FW_ADDR               0x00150000
+#ifdef CONFIG_DPD
+#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
 extern int is_file_exist(char* name);
+#endif
+extern rf_misc_ram_lite_t dpd_res;
 
-int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw)
+int aicwf_fdrv_dpd_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res)
 {
     int ret = 0;
     uint32_t cfg_base = 0x10164;
     struct dbg_mem_read_cfm cfm;
     uint32_t misc_ram_addr;
-
-       printk("%s\n", __func__);
+    uint32_t ram_base_addr, ram_byte_cnt;
+    AICWFDBG(LOGINFO, "bit_mask[1]=%x\n", dpd_res->bit_mask[1]);
+    if (dpd_res->bit_mask[1] == 0) {
+        AICWFDBG(LOGERROR, "void dpd_res, bypass it.\n");
+        return 0;
+    }
     if (testmode == 1) {
         cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
     }
@@ -316,23 +321,75 @@ int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw)
         return ret;
     }
     misc_ram_addr = cfm.memdata;
-    ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, misc_ram_addr, FW_DPDRESULT_NAME_8800DC);
+    AICWFDBG(LOGINFO, "misc_ram_addr: %x\n", misc_ram_addr);
+    /* Copy dpd_res on the Embedded side */
+    // bit_mask
+    AICWFDBG(LOGINFO, "bit_mask[0]=%x\n", dpd_res->bit_mask[0]);
+    ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask);
+    ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved);
+    ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->bit_mask[0]);
     if (ret) {
-        AICWFDBG(LOGINFO, "load calib bin fail: %d\n", ret);
+        AICWFDBG(LOGERROR, "bit_mask wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
         return ret;
     }
+    // dpd_high
+    AICWFDBG(LOGINFO, "dpd_high[0]=%x\n", dpd_res->dpd_high[0]);
+    ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high);
+    ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high);
+    ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->dpd_high[0]);
+    if (ret) {
+        AICWFDBG(LOGERROR, "dpd_high wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
+        return ret;
+    }
+    // loft_res
+    AICWFDBG(LOGINFO, "loft_res[0]=%x\n", dpd_res->loft_res[0]);
+    ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res);
+    ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res);
+    ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->loft_res[0]);
+    if (ret) {
+        AICWFDBG(LOGERROR, "loft_res wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
+        return ret;
+    }
+    return ret;
+}
+
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res)
+{
+    int ret = 0;
+    int size;
+    u32 *dst=NULL;
+    char *filename = FW_DPDRESULT_NAME_8800DC;
+    AICWFDBG(LOGINFO, "dpd_res file path:%s \r\n", filename);
+    /* load file */
+    size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
+    if (size <= 0) {
+        AICWFDBG(LOGERROR, "wrong size of dpd_res file\n");
+        dst = NULL;
+        return -1;
+    }
+    AICWFDBG(LOGINFO, "### Load file done: %s, size=%d, dst[0]=%x\n", filename, size, dst[0]);
+    memcpy((u8 *)dpd_res, (u8 *)dst, sizeof(rf_misc_ram_lite_t));
+    if (dst) {
+        rwnx_release_firmware_common(&dst);
+    }
     return ret;
 }
 #endif
+#endif
 
 int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw)
 {
     int ret = 0;
-    const uint32_t cfg_base = 0x10164;
+    uint32_t cfg_base = 0x10164;
     struct dbg_mem_read_cfm cfm;
     uint32_t misc_ram_addr;
     uint32_t misc_ram_size = 12;
     int i;
+
+    if (testmode == 1) {
+        cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
+    }
     // init misc ram
     printk("%s\n", __func__);
     ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm);
@@ -390,26 +447,43 @@ int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_c
                        return -1;
                }
        } else if (testmode == 1) {
-               if (chip_sub_id == 1) {
+        if (chip_sub_id >= 1) {
             #ifdef CONFIG_DPD
+                       #ifndef CONFIG_FORCE_DPD_CALIB
             if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) {
                 AICWFDBG(LOGINFO, "%s load dpd bin\n", __func__);
-                ret = aicwf_fdrv_dpd_result_load_8800dc(rwnx_hw);
+                ret = aicwf_fdrv_dpd_result_load_8800dc(rwnx_hw, &dpd_res);
                 if (ret) {
                     AICWFDBG(LOGINFO, "load dpd bin fail: %d\n", ret);
                     return ret;
                 }
             }
             #endif
+            if (dpd_res.bit_mask[1]) {
+                ret = aicwf_fdrv_dpd_result_apply_8800dc(rwnx_hw, &dpd_res);
+                if (ret) {
+                    AICWFDBG(LOGINFO, "apply dpd bin fail: %d\n", ret);
+                    return ret;
+                }
+            }
+            #else
+            {
+                ret = aicwf_fdrv_misc_ram_init_8800dc(rwnx_hw);
+                if (ret) {
+                    AICWFDBG(LOGINFO, "misc ram init fail: %d\n", ret);
+                    return ret;
+                }
+            }
+            #endif
             ret = rwnx_send_rf_calib_req(rwnx_hw, cfm);
             if (ret) {
                 AICWFDBG(LOGINFO, "rf calib req fail: %d\n", ret);
                 return ret;
             }
         }
-       }
+    }
 
-       return 0 ;
+    return 0 ;
 }
 
 int    rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw){
index 7b591dbf54b87afb3d28d46ede6a6cec0235e35f..249703b68389976af49126517d8d0cc4fb567912 100644 (file)
@@ -1,7 +1,11 @@
 #include <linux/types.h>
+#include "aic_bsp_export.h"
 
 #ifdef CONFIG_DPD
-int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw);
+int aicwf_fdrv_dpd_result_apply_8800dc(struct rwnx_hw * rwnx_hw, rf_misc_ram_lite_t * dpd_res);
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res);
+#endif
 #endif
 int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw);
 int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
index 66fc7e5281307886859fa4c3f65c45a88c67493f..53c9710dd6908a2543d126f69ba6ee96e557de72 100644 (file)
 #ifdef CONFIG_PLATFORM_ROCKCHIP
 #include <linux/rfkill-wlan.h>
 #endif
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+#include <linux/rfkill-wlan.h>
+#endif
+
 #include "aic_bsp_export.h"
 extern uint8_t scanning;
 
@@ -327,7 +331,9 @@ static irqreturn_t rwnx_hostwake_irq_handler(int irq, void *para)
 #if 0//old oob feature
     complete(&g_rwnx_plat->sdiodev->bus_if->busrx_trgg);
 #else//new oob feature
-    complete(&g_rwnx_plat->sdiodev->bus_if->busirq_trgg);
+    if(g_rwnx_plat->sdiodev->oob_enable){
+        complete(&g_rwnx_plat->sdiodev->bus_if->busirq_trgg);
+    }
 #endif//old oob feature
 #endif
 
@@ -344,9 +350,18 @@ static int rwnx_register_hostwake_irq(struct device *dev)
 {
        int ret = 0;//-1;
 #ifdef CONFIG_GPIO_WAKEUP
+       unsigned long flag_edge;
+       struct aicbsp_feature_t aicwf_feature;
        int irq_flags;
 //TODO hostwake_irq_num hostwake_irq_num and wakeup_enable
 
+       aicbsp_get_feature(&aicwf_feature, NULL);
+       if (aicwf_feature.irqf == 0)
+               flag_edge = IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND;
+       else
+               flag_edge = IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND;
+
+
 #ifdef CONFIG_PLATFORM_ALLWINNER
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
        hostwake_irq_num = sunxi_wlan_get_oob_irq(&irq_flags, &wakeup_enable);
@@ -365,6 +380,14 @@ static int rwnx_register_hostwake_irq(struct device *dev)
                printk("%s irq_flags:%d \r\n", __func__, irq_flags);
                wakeup_enable = 1;
 #endif //CONFIG_PLATFORM_ROCKCHIP
+    //For Rockchip
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+            hostwake_irq_num = rockchip_wifi_get_oob_irq();
+            printk("%s hostwake_irq_num:%d \r\n", __func__, hostwake_irq_num);
+            irq_flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE) & IRQF_TRIGGER_MASK;
+            printk("%s irq_flags:%d \r\n", __func__, irq_flags);
+            wakeup_enable = 1;
+#endif //CONFIG_PLATFORM_ROCKCHIP
 
 
 
@@ -391,9 +414,7 @@ static int rwnx_register_hostwake_irq(struct device *dev)
                        goto fail1;
                }
 
-               ret = request_irq(hostwake_irq_num,
-                               rwnx_hostwake_irq_handler, IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
-                               "rwnx_hostwake_irq", NULL);
+               ret = request_irq(hostwake_irq_num, rwnx_hostwake_irq_handler, flag_edge, "rwnx_hostwake_irq", NULL);
 
                if (ret < 0) {
                        pr_err("%s(%d): request_irq fail! ret = %d\n", __func__, __LINE__, ret);
@@ -535,16 +556,20 @@ static int aicwf_sdio_probe(struct sdio_func *func,
 
        err = aicwf_sdio_chipmatch(sdiodev, func->vendor, func->device);
 
+       sdiodev->func = func;
+       sdiodev->bus_if = bus_if;
+    
 #ifdef CONFIG_OOB
     if(sdiodev->chipid == PRODUCT_ID_AIC8801){
         AICWFDBG(LOGERROR, "%s ERROR!!! 8801 not support OOB \r\n", __func__);
-        goto fail;
+        sdiodev->oob_enable = false;
+    }else{    
+           sdiodev->oob_enable = true;
     }
-#endif //CONFIG_OOB
+#else
+    sdiodev->oob_enable = false;
+#endif
 
-       sdiodev->func = func;
-       sdiodev->bus_if = bus_if;
-       sdiodev->oob_enable = false;
     atomic_set(&sdiodev->is_bus_suspend, 0);
        bus_if->bus_priv.sdio = sdiodev;
 
@@ -578,20 +603,24 @@ static int aicwf_sdio_probe(struct sdio_func *func,
 
 #ifdef CONFIG_GPIO_WAKEUP
 #ifdef CONFIG_OOB
-    AICWFDBG(LOGINFO, "%s SDIOWIFI_INTR_CONFIG_REG Disable\n", __func__);
-    sdio_claim_host(sdiodev->func);
-    //disable sdio interrupt    
-    err = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x0);
-    if (err < 0) {
-        sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG);
-    }    
-    sdio_release_irq(sdiodev->func);
-    sdio_release_host(sdiodev->func);
+    if(sdiodev->oob_enable){
+        AICWFDBG(LOGINFO, "%s SDIOWIFI_INTR_CONFIG_REG Disable\n", __func__);
+        sdio_claim_host(sdiodev->func);
+        //disable sdio interrupt    
+        err = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x0);
+        if (err < 0) {
+            sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG);
+        }    
+        sdio_release_irq(sdiodev->func);
+        sdio_release_host(sdiodev->func);
+#if 0      
 #if 0//old oob feature
-    sdiodev->oob_enable = true;
+        sdiodev->oob_enable = true;
 #else//new oob feature
-    sdiodev->oob_enable = false;
+        sdiodev->oob_enable = true;
 #endif//old oob feature
+#endif
+    }
 #endif
 
 #ifdef CONFIG_WIFI_SUSPEND_FOR_LINUX
@@ -689,16 +718,20 @@ static int aicwf_sdio_suspend(struct device *dev)
 #ifdef CONFIG_GPIO_WAKEUP
 //     rwnx_enable_hostwake_irq();
 #endif
-#if 0
-       sdio_dbg("%s SDIOWIFI_INTR_CONFIG_REG Disable\n", __func__);
-       sdio_claim_host(sdiodev->func);
-       //disable sdio interrupt
-       ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x0);
-       if (ret < 0) {
-               sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG);
+
+
+#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2)
+       if(sdiodev->chipid == PRODUCT_ID_AIC8801){
+               sdio_dbg("%s SDIOWIFI_INTR_CONFIG_REG Disable\n", __func__);
+               sdio_claim_host(sdiodev->func);
+               //disable sdio interrupt
+               ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x0);
+               if (ret < 0) {
+                       sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG);
+               }
+               sdio_release_irq(sdiodev->func);
+               sdio_release_host(sdiodev->func);
        }
-       sdio_release_irq(sdiodev->func);
-       sdio_release_host(sdiodev->func);
 #endif
     atomic_set(&sdiodev->is_bus_suspend, 1);
 //    smp_mb();
@@ -713,7 +746,9 @@ static int aicwf_sdio_resume(struct device *dev)
        struct aicwf_bus *bus_if = dev_get_drvdata(dev);
        struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
        struct rwnx_vif *rwnx_vif, *tmp;
-       //int ret;
+#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2)
+       int ret;
+#endif
 
        sdio_dbg("%s enter \n", __func__);
 //#ifdef CONFIG_GPIO_WAKEUP
@@ -736,16 +771,18 @@ static int aicwf_sdio_resume(struct device *dev)
 
 //     aicwf_sdio_hal_irqhandler(sdiodev->func);
 
-#if 0
-       sdio_dbg("%s SDIOWIFI_INTR_CONFIG_REG Enable\n", __func__);
-       sdio_claim_host(sdiodev->func);
-       sdio_claim_irq(sdiodev->func, aicwf_sdio_hal_irqhandler);
+#if defined(CONFIG_PLATFORM_ROCKCHIP) || defined(CONFIG_PLATFORM_ROCKCHIP2)
+       if(sdiodev->chipid == PRODUCT_ID_AIC8801){
+               sdio_dbg("%s SDIOWIFI_INTR_CONFIG_REG Enable\n", __func__);
+               sdio_claim_host(sdiodev->func);
+               sdio_claim_irq(sdiodev->func, aicwf_sdio_hal_irqhandler);
 
-       //enable sdio interrupt
-       ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x07);
-       if (ret != 0)
-               sdio_err("intr register failed:%d\n", ret);
-       sdio_release_host(sdiodev->func);
+               //enable sdio interrupt
+               ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x07);
+               if (ret != 0)
+                       sdio_err("intr register failed:%d\n", ret);
+               sdio_release_host(sdiodev->func);
+       }
 #endif
     atomic_set(&sdiodev->is_bus_suspend, 0);
 //    smp_mb();
@@ -883,7 +920,7 @@ int aicwf_sdio_wakeup(struct aic_sdio_dev *sdiodev)
        int ret = 0;
        int read_retry;
        int write_retry = 20;
-    int wakeup_reg_val;
+    int wakeup_reg_val = 0;
 
     if (sdiodev->chipid == PRODUCT_ID_AIC8801 ||
         sdiodev->chipid == PRODUCT_ID_AIC8800DC ||
@@ -1538,7 +1575,7 @@ static int aicwf_sdio_bus_start(struct device *dev)
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
 #include "uapi/linux/sched/types.h"
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0))
 #include "linux/sched/types.h"
 #else
 #include "linux/sched/rt.h"
@@ -1755,7 +1792,7 @@ int sdio_busrx_thread(void *data)
        cpumask_set_cpu(3, &cpumask);
        sched_setaffinity(0, &cpumask);
 #endif
-
+#if 0
 #ifdef CONFIG_THREAD_INFO_IN_TASK
     int set_cpu_ret = 0;
 
@@ -1764,7 +1801,7 @@ int sdio_busrx_thread(void *data)
     AICWFDBG(LOGINFO, "%s set_cpu_ret is:%d\n", __func__, set_cpu_ret);
     AICWFDBG(LOGINFO, "%s change cpu to:%d\n", __func__, current->cpu);
 #endif
-
+#endif
 #ifdef CONFIG_TXRX_THREAD_PRIO
     if (busrx_thread_prio > 0) {
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
@@ -1943,8 +1980,7 @@ void aicwf_sdio_hal_irqhandler(struct sdio_func *func)
        if (pkt)
                aicwf_sdio_enq_rxpkt(sdiodev, pkt);
 
-        if(atomic_read(&sdiodev->rx_priv->rx_cnt) == 1 && 
-            sdiodev->oob_enable == false){
+        if(atomic_read(&sdiodev->rx_priv->rx_cnt) == 1){
             complete(&bus_if->busrx_trgg);
         }
 
@@ -2005,8 +2041,7 @@ void aicwf_sdio_hal_irqhandler(struct sdio_func *func)
         if (pkt)
             aicwf_sdio_enq_rxpkt(sdiodev, pkt);
 
-        if(atomic_read(&sdiodev->rx_priv->rx_cnt) == 1 && 
-            sdiodev->oob_enable == false){
+        if(atomic_read(&sdiodev->rx_priv->rx_cnt) == 1){
             complete(&bus_if->busrx_trgg);
         }
     }
@@ -2046,22 +2081,24 @@ static struct aicwf_bus_ops aicwf_sdio_bus_ops = {
 void aicwf_sdio_release(struct aic_sdio_dev *sdiodev)
 {
        struct aicwf_bus *bus_if;
-#ifndef CONFIG_OOB
+#ifdef CONFIG_OOB
     int ret;
 #endif
        AICWFDBG(LOGINFO, "%s Enter\n", __func__);
 
        bus_if = dev_get_drvdata(sdiodev->dev);
        bus_if->state = BUS_DOWN_ST;
-#ifndef CONFIG_OOB
-       sdio_claim_host(sdiodev->func);
-       //disable sdio interrupt
-    ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x0);
-       if (ret < 0) {
-               AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.intr_config_reg);
-       }
-       sdio_release_irq(sdiodev->func);
-       sdio_release_host(sdiodev->func);
+#ifdef CONFIG_OOB
+    if(sdiodev->oob_enable){
+       sdio_claim_host(sdiodev->func);
+       //disable sdio interrupt
+        ret = aicwf_sdio_writeb(sdiodev, sdiodev->sdio_reg.intr_config_reg, 0x0);
+       if (ret < 0) {
+               AICWFDBG(LOGERROR, "reg:%d write failed!\n", sdiodev->sdio_reg.intr_config_reg);
+       }
+       sdio_release_irq(sdiodev->func);
+       sdio_release_host(sdiodev->func);
+    }
 #endif
        if (sdiodev->dev)
                aicwf_bus_deinit(sdiodev->dev);
diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.c b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.c
new file mode 100644 (file)
index 0000000..6d766bc
--- /dev/null
@@ -0,0 +1,633 @@
+#include"aicwf_tcp_ack.h"
+//#include"rwnx_tx.h"
+//#include "aicwf_tcp_ack.h"
+#include"rwnx_defs.h"
+extern int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg);
+struct msg_buf *intf_tcp_alloc_msg(struct msg_buf *msg)
+{
+       //printk("%s \n",__func__);
+       int len=sizeof(struct msg_buf) ;
+       msg = kzalloc(len , GFP_KERNEL);
+       if(!msg)
+               printk("%s: alloc failed \n", __func__);
+       memset(msg,0,len);
+       return msg;
+}
+                                               
+void intf_tcp_drop_msg(struct rwnx_hw *priv,
+                                           struct msg_buf *msg)
+{
+       //printk("%s \n",__func__);
+       if (msg->skb)
+               dev_kfree_skb_any(msg->skb);
+
+       kfree(msg);
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) 
+void tcp_ack_timeout(unsigned long data)
+#else
+void tcp_ack_timeout(struct timer_list *t)
+#endif
+{
+       //printk("%s \n",__func__);
+       struct tcp_ack_info *ack_info;
+       struct msg_buf *msg;
+       struct tcp_ack_manage *ack_m = NULL;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) 
+       ack_info = (struct tcp_ack_info *)data;
+#else
+       ack_info = container_of(t,struct tcp_ack_info,timer);
+#endif
+
+       ack_m = container_of(ack_info, struct tcp_ack_manage,
+                            ack_info[ack_info->ack_info_num]);
+
+       write_seqlock_bh(&ack_info->seqlock);
+       msg = ack_info->msgbuf;
+       if (ack_info->busy && msg && !ack_info->in_send_msg) {
+               ack_info->msgbuf = NULL;
+               ack_info->drop_cnt = 0;
+               ack_info->in_send_msg = msg;
+               write_sequnlock_bh(&ack_info->seqlock);
+               intf_tx(ack_m->priv, msg);//send skb
+               //ack_info->in_send_msg = NULL;//add by dwx
+               //write_sequnlock_bh(&ack_info->seqlock);
+               //intf_tx(ack_m->priv, msg);
+               return;
+       }
+       write_sequnlock_bh(&ack_info->seqlock);
+}
+
+void tcp_ack_init(struct rwnx_hw *priv)
+{
+       int i;
+       struct tcp_ack_info *ack_info;
+       struct tcp_ack_manage *ack_m = &priv->ack_m;
+
+       printk("%s \n",__func__);
+       memset(ack_m, 0, sizeof(struct tcp_ack_manage));
+       ack_m->priv = priv;
+       spin_lock_init(&ack_m->lock);
+       atomic_set(&ack_m->max_drop_cnt, TCP_ACK_DROP_CNT);
+       ack_m->last_time = jiffies;
+       ack_m->timeout = msecs_to_jiffies(ACK_OLD_TIME);
+
+       for (i = 0; i < TCP_ACK_NUM; i++) {
+               ack_info = &ack_m->ack_info[i];
+               ack_info->ack_info_num = i;
+               seqlock_init(&ack_info->seqlock);
+               ack_info->last_time = jiffies;
+               ack_info->timeout = msecs_to_jiffies(ACK_OLD_TIME);
+
+               #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) 
+                       setup_timer(&ack_info->timer, tcp_ack_timeout,
+                                   (unsigned long)ack_info);
+               #else
+                       timer_setup(&ack_info->timer,tcp_ack_timeout,0);
+               #endif
+       }
+
+       atomic_set(&ack_m->enable, 1);
+       ack_m->ack_winsize = MIN_WIN;
+}
+
+void tcp_ack_deinit(struct rwnx_hw *priv)
+{
+       int i;
+       struct tcp_ack_manage *ack_m = &priv->ack_m;
+       struct msg_buf *drop_msg = NULL;
+
+       printk("%s \n",__func__);
+       atomic_set(&ack_m->enable, 0);
+
+       for (i = 0; i < TCP_ACK_NUM; i++) {
+               drop_msg = NULL;
+
+               write_seqlock_bh(&ack_m->ack_info[i].seqlock);
+               del_timer(&ack_m->ack_info[i].timer);
+               drop_msg = ack_m->ack_info[i].msgbuf;
+               ack_m->ack_info[i].msgbuf = NULL;
+               write_sequnlock_bh(&ack_m->ack_info[i].seqlock);
+
+               if (drop_msg)
+                       intf_tcp_drop_msg(priv, drop_msg);//drop skb
+       }
+}
+
+int tcp_check_quick_ack(unsigned char *buf,
+                                     struct tcp_ack_msg *msg)
+{
+       int ip_hdr_len;
+       unsigned char *temp;
+       struct ethhdr *ethhdr;
+       struct iphdr *iphdr;
+       struct tcphdr *tcphdr;
+
+       ethhdr = (struct ethhdr *)buf;
+       if (ethhdr->h_proto != htons(ETH_P_IP))
+               return 0;
+       iphdr = (struct iphdr *)(ethhdr + 1);
+       if (iphdr->version != 4 || iphdr->protocol != IPPROTO_TCP)
+               return 0;
+       ip_hdr_len = iphdr->ihl * 4;
+       temp = (unsigned char *)(iphdr) + ip_hdr_len;
+       tcphdr = (struct tcphdr *)temp;
+       /* TCP_FLAG_ACK */
+       if (!(temp[13] & 0x10))
+               return 0;
+
+       if (temp[13] & 0x8) {
+               msg->saddr = iphdr->daddr;
+               msg->daddr = iphdr->saddr;
+               msg->source = tcphdr->dest;
+               msg->dest = tcphdr->source;
+               msg->seq = ntohl(tcphdr->seq);
+               return 1;
+       }
+
+       return 0;
+}
+
+int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len,
+                               unsigned short *win_scale)
+{
+       //printk("%s \n",__func__);
+       int drop = 1;
+       int len = tcphdr->doff * 4;
+       unsigned char *ptr;
+
+       if(tcp_tot_len > len) {
+               drop = 0;
+       } else {
+               len -= sizeof(struct tcphdr);
+               ptr = (unsigned char *)(tcphdr + 1);
+
+               while ((len > 0) && drop) {
+                       int opcode = *ptr++;
+                       int opsize;
+
+                       switch (opcode) {
+                       case TCPOPT_EOL:
+                               break;
+                       case TCPOPT_NOP:
+                               len--;
+                               continue;
+                       default:
+                               opsize = *ptr++;
+                               if (opsize < 2)
+                                       break;
+                               if (opsize > len)
+                                       break;
+
+                               switch (opcode) {
+                               /* TODO: Add other ignore opt */
+                               case TCPOPT_TIMESTAMP:
+                                       break;
+                               case TCPOPT_WINDOW:
+                                       if (*ptr < 15)
+                                               *win_scale = (1 << (*ptr));
+                                       printk("%d\n",*win_scale);
+                                       break;
+                               default:
+                                       drop = 2;
+                               }
+
+                               ptr += opsize - 2;
+                               len -= opsize;
+                       }
+               }
+       }
+
+       return drop;
+}
+
+
+/* flag:0 for not tcp ack
+ *     1 for ack which can be drop
+ *     2 for other ack whith more info
+ */
+
+int tcp_check_ack(unsigned char *buf,
+                               struct tcp_ack_msg *msg,
+                               unsigned short *win_scale)
+{
+       int ret;
+       int ip_hdr_len;
+       int tcp_tot_len;
+       unsigned char *temp;
+       struct ethhdr *ethhdr;
+       struct iphdr *iphdr;
+       struct tcphdr *tcphdr;
+
+       ethhdr =(struct ethhdr *)buf;
+       if (ethhdr->h_proto != htons(ETH_P_IP))
+               return 0;
+
+       iphdr = (struct iphdr *)(ethhdr + 1);
+       if (iphdr->version != 4 || iphdr->protocol != IPPROTO_TCP)
+               return 0;
+
+       ip_hdr_len = iphdr->ihl * 4;
+       temp = (unsigned char *)(iphdr) + ip_hdr_len;
+       tcphdr = (struct tcphdr *)temp;
+       /* TCP_FLAG_ACK */
+       if (!(temp[13] & 0x10))
+               return 0;
+
+       tcp_tot_len = ntohs(iphdr->tot_len) - ip_hdr_len;// tcp total len
+       ret = is_drop_tcp_ack(tcphdr, tcp_tot_len, win_scale);
+       //printk("is drop:%d \n",ret);
+
+       if (ret > 0) {
+               msg->saddr = iphdr->saddr;
+               msg->daddr = iphdr->daddr;
+               msg->source = tcphdr->source;
+               msg->dest = tcphdr->dest;
+               msg->seq = ntohl(tcphdr->ack_seq);
+               msg->win = ntohs(tcphdr->window);
+       }
+       
+       return ret;
+}
+
+/* return val: -1 for not match, others for match */
+int tcp_ack_match(struct tcp_ack_manage *ack_m,
+                               struct tcp_ack_msg *ack_msg)
+{
+       int i, ret = -1;
+       unsigned start;
+       struct tcp_ack_info *ack_info;
+       struct tcp_ack_msg *ack;
+
+       for (i = 0; ((ret < 0) && (i < TCP_ACK_NUM)); i++) {
+               ack_info = &ack_m->ack_info[i];
+               do {
+                       start = read_seqbegin(&ack_info->seqlock);
+                       ret = -1;
+
+                       ack = &ack_info->ack_msg;
+                       if (ack_info->busy &&
+                           ack->dest == ack_msg->dest &&
+                           ack->source == ack_msg->source &&
+                           ack->saddr == ack_msg->saddr &&
+                           ack->daddr == ack_msg->daddr)
+                               ret = i;
+               } while(read_seqretry(&ack_info->seqlock, start));
+       }
+
+       return ret;
+}
+
+
+void tcp_ack_update(struct tcp_ack_manage *ack_m)
+{
+       int i;
+       struct tcp_ack_info *ack_info;
+
+       if (time_after(jiffies, ack_m->last_time + ack_m->timeout)) {
+               spin_lock_bh(&ack_m->lock);
+               ack_m->last_time = jiffies;
+               for (i = TCP_ACK_NUM - 1; i >= 0; i--) {
+                       ack_info = &ack_m->ack_info[i];
+                       write_seqlock_bh(&ack_info->seqlock);
+                       if (ack_info->busy &&
+                           time_after(jiffies, ack_info->last_time +
+                                      ack_info->timeout)) {
+                               ack_m->free_index = i;
+                               ack_m->max_num--;
+                               ack_info->busy = 0;
+                       }
+                       write_sequnlock_bh(&ack_info->seqlock);
+               }
+               spin_unlock_bh(&ack_m->lock);
+       }
+}
+
+/* return val: -1 for no index, others for index */
+int tcp_ack_alloc_index(struct tcp_ack_manage *ack_m)
+{
+       int i, ret = -1;
+       struct tcp_ack_info *ack_info;
+       unsigned start;
+
+       spin_lock_bh(&ack_m->lock);
+       if (ack_m->max_num == TCP_ACK_NUM) {
+               spin_unlock_bh(&ack_m->lock);
+               return -1;
+       }
+
+       if (ack_m->free_index >= 0) {
+               i = ack_m->free_index;
+               ack_m->free_index = -1;
+               ack_m->max_num++;
+               spin_unlock_bh(&ack_m->lock);
+               return i;
+       }
+
+       for (i = 0; ((ret < 0) && (i < TCP_ACK_NUM)); i++) {
+               ack_info = &ack_m->ack_info[i];
+               do {
+                       start = read_seqbegin(&ack_info->seqlock);
+                       ret = -1;
+                       if (!ack_info->busy) {
+                               ack_m->free_index = -1;
+                               ack_m->max_num++;
+                               ret = i;
+                       }
+               } while(read_seqretry(&ack_info->seqlock, start));
+       }
+       spin_unlock_bh(&ack_m->lock);
+
+       return ret;
+}
+
+
+/* return val: 0 for not handle tx, 1 for handle tx */
+int tcp_ack_handle(struct msg_buf *new_msgbuf,
+                         struct tcp_ack_manage *ack_m,
+                         struct tcp_ack_info *ack_info,
+                         struct tcp_ack_msg *ack_msg,
+                         int type)
+{
+       int quick_ack = 0;
+       struct tcp_ack_msg *ack;
+       int ret = 0;
+       struct msg_buf *drop_msg = NULL;
+
+       //printk("%s %d",__func__,type);
+       write_seqlock_bh(&ack_info->seqlock);
+
+       ack_info->last_time = jiffies;
+       ack = &ack_info->ack_msg;
+
+       if (type == 2) {
+               if (U32_BEFORE(ack->seq, ack_msg->seq)) {
+                       ack->seq = ack_msg->seq;
+                       if (ack_info->psh_flag &&
+                           !U32_BEFORE(ack_msg->seq,
+                                              ack_info->psh_seq)) {
+                               ack_info->psh_flag = 0;
+                       }
+
+                       if (ack_info->msgbuf) {
+                               //printk("%lx \n",ack_info->msgbuf);
+                               drop_msg = ack_info->msgbuf;
+                               ack_info->msgbuf = NULL;
+                               del_timer(&ack_info->timer);
+                       }else{
+                               //printk("msgbuf is NULL \n");
+                       }
+
+                       ack_info->in_send_msg = NULL;
+                       ack_info->drop_cnt = atomic_read(&ack_m->max_drop_cnt);
+               } else {
+                       printk("%s before abnormal ack: %d, %d\n",
+                              __func__, ack->seq, ack_msg->seq);
+                       drop_msg = new_msgbuf;
+                       ret = 1;
+               }
+       } else if (U32_BEFORE(ack->seq, ack_msg->seq)) {
+               if (ack_info->msgbuf) {
+                       drop_msg = ack_info->msgbuf;
+                       ack_info->msgbuf = NULL;
+               }
+
+               if (ack_info->psh_flag &&
+                   !U32_BEFORE(ack_msg->seq, ack_info->psh_seq)) {
+                       ack_info->psh_flag = 0;
+                       quick_ack = 1;
+               } else {
+                       ack_info->drop_cnt++;
+               }
+
+               ack->seq = ack_msg->seq;
+
+               if (quick_ack || (!ack_info->in_send_msg &&
+                                 (ack_info->drop_cnt >=
+                                  atomic_read(&ack_m->max_drop_cnt)))) {
+                       ack_info->drop_cnt = 0;
+                       ack_info->in_send_msg = new_msgbuf;
+                       del_timer(&ack_info->timer);
+               } else {
+                       ret = 1;
+                       ack_info->msgbuf = new_msgbuf;
+                       if (!timer_pending(&ack_info->timer))
+                               mod_timer(&ack_info->timer,
+                                         (jiffies + msecs_to_jiffies(5)));
+               }
+       } else {
+               printk("%s before ack: %d, %d\n",
+                      __func__, ack->seq, ack_msg->seq);
+               drop_msg = new_msgbuf;
+               ret = 1;
+       }
+
+       write_sequnlock_bh(&ack_info->seqlock);
+
+       if (drop_msg)
+               intf_tcp_drop_msg(ack_m->priv, drop_msg);// drop skb
+
+       return ret;
+}
+
+int tcp_ack_handle_new(struct msg_buf *new_msgbuf,
+                         struct tcp_ack_manage *ack_m,
+                         struct tcp_ack_info *ack_info,
+                         struct tcp_ack_msg *ack_msg,
+                         int type)
+{
+       int quick_ack = 0;
+       struct tcp_ack_msg *ack;
+       int ret = 0;
+       struct msg_buf *drop_msg = NULL;
+       struct msg_buf * send_msg = NULL;
+       //printk("",);
+       write_seqlock_bh(&ack_info->seqlock);
+
+        ack_info->last_time = jiffies;
+        ack = &ack_info->ack_msg;
+
+       if(U32_BEFORE(ack->seq, ack_msg->seq)){
+               if (ack_info->msgbuf) {
+                       drop_msg = ack_info->msgbuf;
+                       ack_info->msgbuf = NULL;
+                       //ack_info->drop_cnt++;
+               }
+
+               if (ack_info->psh_flag &&
+                   !U32_BEFORE(ack_msg->seq, ack_info->psh_seq)) {
+                       ack_info->psh_flag = 0;
+                       quick_ack = 1;
+               } else {
+                       ack_info->drop_cnt++;
+               }
+
+               ack->seq = ack_msg->seq;
+
+               if(quick_ack || (!ack_info->in_send_msg &&
+                                 (ack_info->drop_cnt >=
+                                  atomic_read(&ack_m->max_drop_cnt)))){
+                       ack_info->drop_cnt = 0;
+                       send_msg = new_msgbuf;
+                       ack_info->in_send_msg = send_msg;
+                       del_timer(&ack_info->timer);
+               }else{
+                       ret = 1;
+                       ack_info->msgbuf = new_msgbuf;
+                       if (!timer_pending(&ack_info->timer))
+                               mod_timer(&ack_info->timer,
+                                         (jiffies + msecs_to_jiffies(5)));
+               }
+               
+               //ret = 1;
+       }else {
+               printk("%s before ack: %d, %d\n",
+                      __func__, ack->seq, ack_msg->seq);
+               drop_msg = new_msgbuf;
+               ret = 1;
+       }
+
+       /*if(send_msg){
+               intf_tx(ack_m->priv,send_msg);
+               ack_info->in_send_msg=NULL;
+       }*/
+
+       //ack_info->in_send_msg=NULL;
+       
+       write_sequnlock_bh(&ack_info->seqlock);
+
+       /*if(send_msg){
+            intf_tx(ack_m->priv,send_msg);
+            //ack_info->in_send_msg=NULL;
+       }*/
+
+       if (drop_msg)
+               intf_tcp_drop_msg(ack_m->priv, drop_msg);// drop skb
+
+       return ret;
+
+}
+
+void filter_rx_tcp_ack(struct rwnx_hw *priv,
+                             unsigned char *buf, unsigned plen)
+{
+       int index;
+       struct tcp_ack_msg ack_msg;
+       struct tcp_ack_info *ack_info;
+       struct tcp_ack_manage *ack_m = &priv->ack_m;
+
+       if (!atomic_read(&ack_m->enable))
+               return;
+
+       if ((plen > MAX_TCP_ACK) ||
+           !tcp_check_quick_ack(buf, &ack_msg))
+               return;
+
+       index = tcp_ack_match(ack_m, &ack_msg);
+       if (index >= 0) {
+               ack_info = ack_m->ack_info + index;
+               write_seqlock_bh(&ack_info->seqlock);
+               ack_info->psh_flag = 1;
+               ack_info->psh_seq = ack_msg.seq;
+               write_sequnlock_bh(&ack_info->seqlock);
+       }
+}
+
+/* return val: 0 for not filter, 1 for filter */
+int filter_send_tcp_ack(struct rwnx_hw *priv,
+                              struct msg_buf *msgbuf,
+                              unsigned char *buf, unsigned int plen)
+{
+       //printk("%s \n",__func__);
+       int ret = 0;
+       int index, drop;
+       unsigned short win_scale = 0;
+       unsigned int win = 0;
+       struct tcp_ack_msg ack_msg;
+       struct tcp_ack_msg *ack;
+       struct tcp_ack_info *ack_info;
+       struct tcp_ack_manage *ack_m = &priv->ack_m;
+
+       if (plen > MAX_TCP_ACK)
+               return 0;
+
+       tcp_ack_update(ack_m);
+       drop = tcp_check_ack(buf, &ack_msg, &win_scale);
+       //printk("drop:%d win_scale:%d",drop,win_scale);
+       if (!drop && (0 == win_scale))
+               return 0;
+
+       index = tcp_ack_match(ack_m, &ack_msg);
+       if (index >= 0) {
+               ack_info = ack_m->ack_info + index;
+               if ((0 != win_scale) &&
+                       (ack_info->win_scale != win_scale)) {
+                       write_seqlock_bh(&ack_info->seqlock);
+                       ack_info->win_scale = win_scale;
+                       write_sequnlock_bh(&ack_info->seqlock);
+               }
+
+               if (drop > 0 && atomic_read(&ack_m->enable)) {
+                       win = ack_info->win_scale * ack_msg.win;
+                       if ((win_scale!=0) && (win < (ack_m->ack_winsize * SIZE_KB)))
+                       {       
+                               drop = 2;
+                               printk("%d %d %d",win_scale,win,(ack_m->ack_winsize * SIZE_KB));
+                       }
+                       ret = tcp_ack_handle_new(msgbuf, ack_m, ack_info,
+                                               &ack_msg, drop);
+               }
+
+               goto out;
+       }
+
+       index = tcp_ack_alloc_index(ack_m);
+       if (index >= 0) {
+               write_seqlock_bh(&ack_m->ack_info[index].seqlock);
+               ack_m->ack_info[index].busy = 1;
+               ack_m->ack_info[index].psh_flag = 0;
+               ack_m->ack_info[index].last_time = jiffies;
+               ack_m->ack_info[index].drop_cnt =
+                       atomic_read(&ack_m->max_drop_cnt);
+               ack_m->ack_info[index].win_scale =
+                       (win_scale != 0) ? win_scale : 1;
+               
+               //ack_m->ack_info[index].msgbuf = NULL;
+               //ack_m->ack_info[index].in_send_msg = NULL;
+               ack = &ack_m->ack_info[index].ack_msg;
+               ack->dest = ack_msg.dest;
+               ack->source = ack_msg.source;
+               ack->saddr = ack_msg.saddr;
+               ack->daddr = ack_msg.daddr;
+               ack->seq = ack_msg.seq;
+               write_sequnlock_bh(&ack_m->ack_info[index].seqlock);
+       }
+
+out:
+       return ret;
+}
+
+void move_tcpack_msg(struct rwnx_hw *priv,
+                           struct msg_buf *msg)
+{
+       struct tcp_ack_info *ack_info;
+       struct tcp_ack_manage *ack_m = &priv->ack_m;
+       int i = 0;
+
+       if (!atomic_read(&ack_m->enable))
+               return;
+
+       //if (msg->len > MAX_TCP_ACK)
+       //      return;
+
+       for (i = 0; i < TCP_ACK_NUM; i++) {
+               ack_info = &ack_m->ack_info[i];
+               write_seqlock_bh(&ack_info->seqlock);
+               if (ack_info->busy && (ack_info->in_send_msg == msg))
+                       ack_info->in_send_msg = NULL;
+               write_sequnlock_bh(&ack_info->seqlock);
+       }
+}
+
diff --git a/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.h b/drivers/net/wireless/aic8800/aic8800_fdrv/aicwf_tcp_ack.h
new file mode 100644 (file)
index 0000000..ff7f11d
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef _AICWF_TCP_ACK_H_
+#define _AICWF_TCP_ACK_H_
+
+#include <uapi/linux/if_ether.h>
+#include <uapi/linux/tcp.h>
+#include <uapi/linux/ip.h>
+#include <uapi/linux/in.h>
+#include <linux/moduleparam.h>
+#include <net/tcp.h>
+#include <linux/timer.h>
+
+
+#define TCP_ACK_NUM  32
+#define TCP_ACK_EXIT_VAL               0x800
+#define TCP_ACK_DROP_CNT               10
+
+#define ACK_OLD_TIME   4000
+#define U32_BEFORE(a, b)       ((__s32)((__u32)a - (__u32)b) <= 0)
+
+#define MAX_TCP_ACK 200
+/*min window size in KB, it's 256KB*/
+#define MIN_WIN 256
+#define SIZE_KB 1024
+
+
+struct msg_buf {
+       //struct list_head list;
+       struct sk_buff *skb;
+       struct rwnx_vif *rwnx_vif;
+
+       /* data just tx cmd use,not include the head */
+       /*void *data;
+       void *tran_data;
+       unsigned long pcie_addr;
+       u8 type;
+       u8 mode;
+       u16 len;
+       unsigned long timeout;*/
+       /* marlin 2 */
+       /*unsigned int fifo_id;
+       struct sprdwl_msg_list *msglist;*/
+       /* marlin 3 */
+       /*unsigned char buffer_type;
+       struct sprdwl_xmit_msg_list *xmit_msg_list;
+       unsigned char msg_type;
+
+       unsigned long last_time;
+       u8 ctxt_id;*/
+
+};
+
+struct tcp_ack_msg {
+       u16 source;
+       u16 dest;
+       s32 saddr;
+       s32 daddr;
+       u32 seq;
+       u16 win;
+};
+
+
+struct tcp_ack_info {
+       int ack_info_num;
+       int busy;
+       int drop_cnt;
+       int psh_flag;
+       u32 psh_seq;
+       u16 win_scale;
+       /* seqlock for ack info */
+       seqlock_t seqlock;
+       unsigned long last_time;
+       unsigned long timeout;
+       struct timer_list timer;
+       struct msg_buf *msgbuf;
+       struct msg_buf *in_send_msg;
+       struct tcp_ack_msg ack_msg;
+};
+
+struct tcp_ack_manage {
+       /* 1 filter */
+       atomic_t enable;
+       int max_num;
+       int free_index;
+       unsigned long last_time;
+       unsigned long timeout;
+       atomic_t max_drop_cnt;
+       /* lock for tcp ack alloc and free */
+       spinlock_t lock;
+       struct rwnx_hw *priv;
+       struct tcp_ack_info ack_info[TCP_ACK_NUM];
+       /*size in KB*/
+       unsigned int ack_winsize;
+};
+
+struct msg_buf *intf_tcp_alloc_msg(struct msg_buf *msg);
+
+void tcp_ack_init(struct rwnx_hw *priv);
+
+void tcp_ack_deinit(struct rwnx_hw *priv);
+
+
+int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len, unsigned short *win_scale);
+
+int is_tcp_ack(struct sk_buff *skb, unsigned short *win_scale);
+
+int filter_send_tcp_ack(struct rwnx_hw *priv, struct msg_buf *msgbuf,unsigned char *buf, unsigned int plen);
+
+void filter_rx_tcp_ack(struct rwnx_hw *priv,unsigned char *buf, unsigned plen);
+
+void move_tcpack_msg(struct rwnx_hw *priv, struct msg_buf * msg);
+#endif
index 7f8c7d924b93664381be39c102fbb2b5b90ac4fd..47613d7c6cca099e3970854ce529611c10937b58 100644 (file)
@@ -100,7 +100,9 @@ int aicwf_bus_init(uint bus_hdrlen, struct device *dev)
        bus_if->busrx_thread = kthread_run(sdio_busrx_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busrx_thread");
     //new oob feature
 #ifdef CONFIG_OOB
-    bus_if->busirq_thread = kthread_run(sdio_busirq_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busirq_thread");
+    if(bus_if->bus_priv.sdio->oob_enable){
+        bus_if->busirq_thread = kthread_run(sdio_busirq_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busirq_thread");
+    }
 #endif //CONFIG_OOB
 #endif
 #ifdef AICWF_USB_SUPPORT
@@ -203,7 +205,7 @@ struct aicwf_tx_priv *aicwf_tx_init(void *arg)
 #endif
 
        atomic_set(&tx_priv->aggr_count, 0);
-#if AICBSP_RESV_MEM_SUPPORT
+#ifdef  CONFIG_RESV_MEM_SUPPORT
        tx_priv->aggr_buf = aicbsp_resv_mem_alloc_skb(MAX_AGGR_TXPKT_LEN, AIC_RESV_MEM_TXDATA);
 #else
        tx_priv->aggr_buf = dev_alloc_skb(MAX_AGGR_TXPKT_LEN);
@@ -222,7 +224,7 @@ struct aicwf_tx_priv *aicwf_tx_init(void *arg)
 void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv)
 {
        if (tx_priv && tx_priv->aggr_buf) {
-#if AICBSP_RESV_MEM_SUPPORT
+#ifdef  CONFIG_RESV_MEM_SUPPORT
                aicbsp_resv_mem_kfree_skb(tx_priv->aggr_buf, AIC_RESV_MEM_TXDATA);
 #else
                dev_kfree_skb(tx_priv->aggr_buf);
@@ -532,7 +534,6 @@ static struct recv_msdu *aicwf_rxframe_queue_init(struct list_head *q, int qsize
        for (i = 0; i < qsize; i++) {
                INIT_LIST_HEAD(&req->rxframe_list);
                list_add(&req->rxframe_list, q);
-               req->len = 0;
                req++;
        }
 
@@ -613,11 +614,13 @@ void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv)
                rx_priv->sdiodev->bus_if->busrx_thread = NULL;
        }
 #ifdef CONFIG_OOB
-    //new oob feature
-    if (rx_priv->sdiodev->bus_if->busirq_thread) {
-        complete_all(&rx_priv->sdiodev->bus_if->busirq_trgg);
-        kthread_stop(rx_priv->sdiodev->bus_if->busirq_thread);
-        rx_priv->sdiodev->bus_if->busirq_thread = NULL;
+    if(rx_priv->sdiodev->oob_enable){
+        //new oob feature
+        if (rx_priv->sdiodev->bus_if->busirq_thread) {
+            complete_all(&rx_priv->sdiodev->bus_if->busirq_trgg);
+            kthread_stop(rx_priv->sdiodev->bus_if->busirq_thread);
+            rx_priv->sdiodev->bus_if->busirq_thread = NULL;
+        }
     }
 #endif //CONFIG_OOB
 #endif
index 393fb5dcc844d32a870210ad94bb404bc0ac9b12..2a06442799b2a10df9dfb315a937e15db5c93083 100644 (file)
@@ -161,7 +161,8 @@ struct recv_msdu {
         u8  tid;
         u16 seq_num;
         u8 forward;
-        uint len;
+        //uint len;
+        u32 is_amsdu;
         u8 *rx_data;
         //for pending rx reorder list
        struct list_head reord_pending_list;
index 81740182e3f8bb25693884cb00594ffc2d20a80a..061248c1015d52190a62753796541b389bb357c0 100644 (file)
@@ -391,6 +391,9 @@ enum mm_msg_tag {
 
     MM_CFG_RSSI_CFM,
 
+    MM_SET_VENDOR_SWCONFIG_REQ,
+    MM_SET_VENDOR_SWCONFIG_CFM,
+
     /// MAX number of messages
     MM_MAX,
 };
@@ -1819,6 +1822,7 @@ enum vendor_hwconfig_tag{
        MAC_TIMESCALE_REQ,
        CCA_THRESHOLD_REQ,
        BWMODE_REQ,
+       CHIP_TEMP_GET_REQ,
 };
 
 enum {
@@ -1846,6 +1850,7 @@ struct mm_set_channel_access_req
        u8_l  long_nav_en;
        u8_l  cfe_en;
        u8_l  rc_retry_cnt[3];
+       s8_l ccademod_th;
 };
 
 struct mm_set_mac_timescale_req
@@ -1876,6 +1881,24 @@ struct mm_set_bwmode_req
     u8_l bwmode;
 };
 
+struct mm_get_chip_temp_req
+{
+    u32_l hwconfig_id;
+};
+
+struct mm_get_chip_temp_cfm
+{
+    /// Temp degree val
+    s8_l degree;
+};
+
+struct mm_set_vendor_hwconfig_cfm
+{
+    u32_l hwconfig_id;
+    union {
+        struct mm_get_chip_temp_cfm chip_temp_cfm;
+    };
+};
 
 struct mm_set_txop_req
 {
@@ -1893,6 +1916,71 @@ struct mm_get_fw_version_cfm
     u8_l fw_version[63];
 };
 
+struct mm_get_wifi_disable_cfm
+{
+    u8_l wifi_disable;
+};
+
+enum vendor_swconfig_tag
+{
+    BCN_CFG_REQ = 0,
+    TEMP_COMP_SET_REQ,
+    TEMP_COMP_GET_REQ,
+};
+
+struct mm_set_bcn_cfg_req
+{
+    /// Ignore or not bcn tim bcmc bit
+    bool_l tim_bcmc_ignored_enable;
+};
+
+struct mm_set_bcn_cfg_cfm
+{
+    /// Request status
+    bool_l tim_bcmc_ignored_status;
+};
+
+struct mm_set_temp_comp_req
+{
+    /// Enable or not temp comp
+    u8_l enable;
+    u8_l reserved[3];
+    u32_l tmr_period_ms;
+};
+
+struct mm_set_temp_comp_cfm
+{
+    /// Request status
+    u8_l status;
+};
+
+struct mm_get_temp_comp_cfm
+{
+    /// Request status
+    u8_l status;
+    /// Temp degree val
+    s8_l degree;
+};
+
+struct mm_set_vendor_swconfig_req
+{
+    u32_l swconfig_id;
+    union {
+        struct mm_set_bcn_cfg_req bcn_cfg_req;
+        struct mm_set_temp_comp_req temp_comp_set_req;
+    };
+};
+
+struct mm_set_vendor_swconfig_cfm
+{
+    u32_l swconfig_id;
+    union {
+        struct mm_set_bcn_cfg_cfm bcn_cfg_cfm;
+        struct mm_set_temp_comp_cfm temp_comp_set_cfm;
+        struct mm_get_temp_comp_cfm temp_comp_get_cfm;
+    };
+};
+
 /// Structure containing the parameters of the @ref ME_RC_STATS_REQ message.
 struct me_rc_stats_req {
        /// Index of the station for which the RC statistics are requested
index 000874b678255b3dbe570b93f45c4c3cedc7e75c..9287eca607f8e2395db36104b75263c6968dce1e 100644 (file)
 #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)
index e04bbbb1076fe54ab7afe5cae5d6051e593e52bb..f4594f4bcc1d839cbb1fdf17bcc355139b2bd01c 100644 (file)
@@ -1242,7 +1242,7 @@ static ssize_t rwnx_dbgfs_regdbg_write(struct file *file,
 
        buf[len] = '\0';
 
-       if (sscanf(buf, "%x %x %x" , &oper, &addr, &val ) > 0) 
+       if (sscanf(buf, "%x %x %x" , &oper, &addr, &val ) > 0)
                printk("addr=%x, val=%x,oper=%d\n", addr, val, oper);
 
        if(oper== 0) {
@@ -1261,7 +1261,8 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file,
 {
        struct rwnx_hw *priv = file->private_data;
        char buf[64];
-       int32_t addr[12];
+       int32_t addr[13];
+    int32_t addr_out[12];
        u32_l hwconfig_id;
        size_t len = min_t(size_t,count,sizeof(buf)-1);
        int ret;
@@ -1274,10 +1275,10 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file,
        }
 
        buf[len] = '\0';
-       ret = sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x",
-                            &hwconfig_id, &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5], &addr[6], &addr[7], &addr[8], &addr[9], &addr[10], &addr[11]);
-       if(ret > 13) {
-               printk("param error > 13\n");
+       ret = sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x",
+                            &hwconfig_id, &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5], &addr[6], &addr[7], &addr[8], &addr[9], &addr[10], &addr[11], &addr[12]);
+       if(ret > 14) {
+               printk("param error > 14\n");
        } else {
                switch(hwconfig_id)
                    {
@@ -1285,22 +1286,23 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file,
                        if(ret != 5) {
                            printk("param error  != 5\n");
                            break;}
-                       ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr);
+                       ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL);
                        printk("ACS_TXOP_REQ bk:0x%x be:0x%x vi:0x%x vo:0x%x\n",addr[0],  addr[1], addr[2], addr[3]);
                        break;
                    case 1:
-                       if(ret != 13) {
-                           printk("param error  != 13\n");
+                       if(ret != 14) {
+                           printk("param error  != 14\n");
                            break;}
-                       ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr);
-                       printk("CHANNEL_ACCESS_REQ edca:%x,%x,%x,%x, vif:%x, retry_cnt:%x, rts:%x, long_nav:%x, cfe:%x, rc_retry_cnt:%x:%x:%x\n",
-                                addr[0],  addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11]);
+                       addr[12] = ~addr[12] + 1;
+                       ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL);
+                       printk("CHANNEL_ACCESS_REQ edca:%x,%x,%x,%x, vif:%x, retry_cnt:%x, rts:%x, long_nav:%x, cfe:%x, rc_retry_cnt:%x:%x:%x ccademod_th %x\n",
+                                addr[0],  addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12]);
                        break;
                    case 2:
                        if(ret != 7) {
                            printk("param error  != 7\n");
                            break;}
-                       ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr);
+                       ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL);
                        printk("MAC_TIMESCALE_REQ sifsA:%x,sifsB:%x,slot:%x,ofdm_delay:%x,long_delay:%x,short_delay:%x\n",
                                 addr[0],  addr[1], addr[2], addr[3], addr[4], addr[5]);
                        break;
@@ -1312,11 +1314,27 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file,
                        addr[2] = ~addr[2] + 1;
                        addr[3] = ~addr[3] + 1;
                        addr[4] = ~addr[4] + 1;
-                       ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr);
+                       ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL);
                        printk("CCA_THRESHOLD_REQ auto_cca:%d, cca20p_rise:%d cca20s_rise:%d cca20p_fail:%d cca20s_fail:%d\n",
                                 addr[0],  addr[1], addr[2], addr[3], addr[4]);
                        break;
-                   default:
+            case 4: // BWMODE_REQ
+                if (ret != 2) {
+                    printk("param error != 2\n");
+                } else {
+                    ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL);
+                    printk("BWMODE_REQ md=%d\n", addr[0]);
+                }
+            break;
+            case 5: // CHIP_TEMP_GET_REQ
+                if (ret != 1) {
+                    printk("param error != 1\n");
+                } else {
+                    ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, addr_out);
+                    printk("CHIP_TEMP_GET_REQ degree=%d\n", addr_out[0]);
+                }
+            break;
+            default:
                        printk("param error\n");
                        break;
                }
@@ -1330,6 +1348,73 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file,
 
 DEBUGFS_WRITE_FILE_OPS(vendor_hwconfig)
 
+static ssize_t rwnx_dbgfs_vendor_swconfig_write(struct file *file,
+            const char __user *user_buf,
+            size_t count, loff_t *ppos)
+{
+    struct rwnx_hw *priv = file->private_data;
+    char buf[64];
+    int32_t addr[12];
+    int32_t addr_out[12];
+    u32_l swconfig_id;
+    size_t len = min_t(size_t, count, sizeof(buf) - 1);
+    int ret;
+    printk("%s\n", __func__);
+
+    if (copy_from_user(buf, user_buf, len)) {
+        return -EFAULT;
+    }
+
+    buf[len] = '\0';
+    ret = sscanf(buf, "%x %x %x", &swconfig_id, &addr[0], &addr[1]);
+    if (ret > 3) {
+        printk("param error > 3\n");
+    } else {
+        switch (swconfig_id)
+        {
+            case 0: // BCN_CFG_REQ
+                if (ret != 2) {
+                    printk("param error != 2\n");
+                } else {
+                    ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out);
+                    printk("BCN_CFG_REQ set_en=%d, get_en=%d\n", addr[0], addr_out[0]);
+                }
+            break;
+
+            case 1: // TEMP_COMP_SET_REQ
+                if (ret != 3) {
+                    printk("param error != 3\n");
+                } else {
+                    ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out);
+                    printk("TEMP_COMP_SET_REQ set_en=%d, tmr=%dms, get_st=%d\n",
+                        addr[0], addr[1], addr_out[0]);
+                }
+            break;
+
+            case 2: // TEMP_COMP_GET_REQ
+                if (ret != 1) {
+                    printk("param error != 1\n");
+                } else {
+                    ret = rwnx_send_vendor_swconfig_req(priv, swconfig_id, addr, addr_out);
+                    printk("TEMP_COMP_GET_REQ get_st=%d, degree=%d\n", addr_out[0], addr_out[1]);
+                }
+            break;
+
+            default:
+                printk("param error\n");
+                break;
+        }
+
+        if (ret) {
+            printk("rwnx_send_vendor_swconfig_req fail: %x\n", ret);
+        }
+    }
+
+    return count;
+}
+
+DEBUGFS_WRITE_FILE_OPS(vendor_swconfig)
+
 
 #ifdef CONFIG_RWNX_FULLMAC
 
@@ -1831,8 +1916,8 @@ static ssize_t rwnx_dbgfs_last_rx_read(struct file *file,
                if (rate_stats->table[i]) {
                        union rwnx_rate_ctrl_info rate_config;
                        int percent = (rate_stats->table[i] * 1000) / rate_stats->cpt;
-                       int p;
-                       int ru_size;
+                       int p = 0;
+                       int ru_size = 0;
 
                        idx_to_rate_cfg(i, &rate_config, &ru_size);
                        len += print_rate_from_cfg(&buf[len], bufsz - len,
@@ -2153,6 +2238,7 @@ int rwnx_dbgfs_register(struct rwnx_hw *rwnx_hw, const char *name)
 #endif
        DEBUGFS_ADD_FILE(regdbg, dir_drv, S_IWUSR);
        DEBUGFS_ADD_FILE(vendor_hwconfig, dir_drv,S_IWUSR);
+       DEBUGFS_ADD_FILE(vendor_swconfig, dir_drv,S_IWUSR);
 
 #ifdef CONFIG_RWNX_P2P_DEBUGFS
        {
index 7c49f3aeee922f6a187e156b3c0b983785af76b6..4e966dee2fadf0c79f2a3403e2cb25b0a5d97218 100644 (file)
 #include "rwnx_mu_group.h"
 #include "rwnx_platform.h"
 #include "rwnx_cmds.h"
+#ifdef CONFIG_GKI
 #include "rwnx_gki.h"
+#endif
 #include "rwnx_compat.h"
+#ifdef CONFIG_FILTER_TCP_ACK
+#include "aicwf_tcp_ack.h"
+#endif
 
 #ifdef AICWF_SDIO_SUPPORT
 #include "aicwf_sdio.h"
@@ -295,6 +300,7 @@ struct rwnx_vif {
        struct net_device *ndev;
        struct net_device_stats net_stats;
        struct rwnx_key key[6];
+    unsigned long drv_flags;
        atomic_t drv_conn_state;
        u8 drv_vif_index;           /* Identifier of the VIF in driver */
        u8 vif_index;               /* Identifier of the station in FW */
@@ -320,6 +326,13 @@ struct rwnx_vif {
                        bool external_auth;  /* Indicate if external authentication is in progress */
                        u32 group_cipher_type;
                        u32 paired_cipher_type;
+                       //connected network info start
+                       char ssid[33];//ssid max is 32, but this has one spare for '\0'
+                       int ssid_len;
+                       u8 bssid[ETH_ALEN];
+                       u32 conn_owner_nlportid;
+                       bool is_roam;
+                       //connected network info end
                } sta;
                struct {
                        u16 flags;                 /* see rwnx_ap_flags */
@@ -602,13 +615,17 @@ struct rwnx_hw {
 
        u8 monitor_vif; /* FW id of the monitor interface, RWNX_INVALID_VIF if no monitor vif at fw level */
 
+#ifdef CONFIG_FILTER_TCP_ACK
+       /* tcp ack management */
+       struct tcp_ack_manage ack_m;
+#endif
+
        /* RoC Management */
        struct rwnx_roc_elem *roc_elem;             /* Information provided by cfg80211 in its remain on channel request */
        u32 roc_cookie_cnt;                         /* Counter used to identify RoC request sent by cfg80211 */
 
        struct rwnx_cmd_mgr *cmd_mgr;
 
-       unsigned long drv_flags;
        struct rwnx_plat *plat;
 
        spinlock_t tx_lock;
@@ -652,7 +669,7 @@ struct rwnx_hw {
 
        struct rwnx_hwq hwq[NX_TXQ_CNT];
 
-       u8 avail_idx_map;
+       u64 avail_idx_map;
        u8 vif_started;
        bool adding_sta;
        struct rwnx_phy_info phy;
index 6e5bdea0269a2ea6edef7c7b8a76c27d5caf9f57..17d55da1156f4ab43c5db39a719dbdafa3d6bf8d 100644 (file)
@@ -243,7 +243,7 @@ int rwnx_dini_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_pla
        pci_read_config_word(pci_dev, PCI_COMMAND, &pci_cmd);
        pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
        pci_write_config_word(pci_dev, PCI_COMMAND, pci_cmd);
-       pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2);
+       //pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2);
 
        ret = pci_enable_device(pci_dev);
        if (ret) {
@@ -252,13 +252,13 @@ int rwnx_dini_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_pla
        }
 
        pci_set_master(pci_dev);
-
+#if 0
        ret = pci_request_regions(pci_dev, KBUILD_MODNAME);
        if (ret) {
                dev_err(&(pci_dev->dev), "pci_request_regions failed\n");
                goto out_request;
        }
-
+#endif
        rwnx_dini->pci_bar0_vaddr = (u8 *)pci_ioremap_bar(pci_dev, 0);
        if (!rwnx_dini->pci_bar0_vaddr) {
                dev_err(&(pci_dev->dev), "pci_ioremap_bar(%d) failed\n", 0);
@@ -289,7 +289,7 @@ out_bar4:
        iounmap(rwnx_dini->pci_bar0_vaddr);
 out_bar0:
        pci_release_regions(pci_dev);
-out_request:
+//out_request:
        pci_disable_device(pci_dev);
 out_enable:
        kfree(*rwnx_plat);
index ad6c52d46f3ef11898ad0199113f7eed6bc813a6..7f6333d91e598ccf1573a1da517c78cb257c33f4 100644 (file)
@@ -2,12 +2,12 @@
 #ifdef ANDROID_PLATFORM
 #include "net/wireless/core.h"
 #endif
-
+#include <include/linux/types.h>
 
 #undef NL80211_MCGRP_MLME
 #define NL80211_MCGRP_MLME 3
-#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
-
+//#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
 
 static struct genl_family rwnx_nl80211_fam;
 
index 6a8fb3ef7335e93423fc18e756fafa4192fc50c7..a41f578322797b253fa400c3ed7a0d476d64d004 100644 (file)
@@ -5,7 +5,8 @@
 #include "net/wireless/core.h"
 #endif
 
-#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
+//#if IS_ENABLED(CONFIG_GKI_OPT_FEATURES) && IS_ENABLED(CONFIG_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
 
 
 bool rwnx_cfg80211_rx_spurious_frame(struct net_device *dev,
index ca33d79c0990051210daf5a92423d9c649c5369f..e364ba59549504140c48286331fd502bd03c0eba 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/if_arp.h>
 #include <linux/ctype.h>
 #include <linux/random.h>
+#include <linux/vmalloc.h>
 #include "rwnx_defs.h"
 #include "rwnx_dini.h"
 #include "rwnx_msg_tx.h"
@@ -774,12 +775,12 @@ static void rwnx_csa_finish(struct work_struct *ws)
                } else
                        rwnx_txq_vif_stop(vif, RWNX_TXQ_STOP_CHAN, rwnx_hw);
                spin_unlock_bh(&rwnx_hw->cb_lock);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 94))
-                cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0, 0);
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
-                cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0);
+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION3)
+               cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0, 0);
+#elif (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION)
+               cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0);
 #else
-                cfg80211_ch_switch_notify(vif->ndev, &csa->chandef);
+               cfg80211_ch_switch_notify(vif->ndev, &csa->chandef);
 #endif
                mutex_unlock(&vif->wdev.mtx);
                __release(&vif->wdev.mtx);
@@ -924,10 +925,22 @@ static int rwnx_open(struct net_device *dev)
        struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw;
        struct mm_add_if_cfm add_if_cfm;
        int error = 0;
-    u8 rwnx_rx_gain = 0x0E;
+       u8 rwnx_rx_gain = 0x0E;
+       int err = 0;
+       int waiting_counter = 10;
 
        RWNX_DBG(RWNX_FN_ENTRY_STR);
 
+       while(test_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags)){
+               msleep(100);
+               AICWFDBG(LOGDEBUG, "%s waiting for rwnx_close \r\n", __func__);
+               waiting_counter--;
+               if(waiting_counter == 0){
+                       AICWFDBG(LOGERROR, "%s error waiting for close time out \r\n", __func__);
+                       break;
+               }
+       }
+
 #ifdef CONFIG_GPIO_WAKEUP
 //close lp mode
 //     rwnx_send_me_set_lp_level(g_rwnx_plat->sdiodev->rwnx_hw, 0);
@@ -959,7 +972,7 @@ static int rwnx_open(struct net_device *dev)
           #endif
 
           /* Device is now started */
-          set_bit(RWNX_DEV_STARTED, &rwnx_hw->drv_flags);
+          set_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags);
           atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED);
        }
        #ifdef CONFIG_COEX
@@ -968,6 +981,32 @@ static int rwnx_open(struct net_device *dev)
        }
        #endif
 
+       if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_GO) {
+               if (!rwnx_hw->is_p2p_alive) {
+                       if (rwnx_hw->p2p_dev_vif && !rwnx_hw->p2p_dev_vif->up) {
+                               err = rwnx_send_add_if (rwnx_hw, rwnx_hw->p2p_dev_vif->wdev.address,
+                                                                                         RWNX_VIF_TYPE(rwnx_hw->p2p_dev_vif), false, &add_if_cfm);
+                               if (err) {
+                                       return -EIO;
+                               }
+
+                               if (add_if_cfm.status != 0) {
+                                       return -EIO;
+                               }
+
+                               /* Save the index retrieved from LMAC */
+                               spin_lock_bh(&rwnx_hw->cb_lock);
+                               rwnx_hw->p2p_dev_vif->vif_index = add_if_cfm.inst_nbr;
+                               rwnx_hw->p2p_dev_vif->up = true;
+                               rwnx_hw->vif_started++;
+                               rwnx_hw->vif_table[add_if_cfm.inst_nbr] = rwnx_hw->p2p_dev_vif;
+                               spin_unlock_bh(&rwnx_hw->cb_lock);
+                       }
+                       rwnx_hw->is_p2p_alive = 1;
+                       mod_timer(&rwnx_hw->p2p_alive_timer, jiffies + msecs_to_jiffies(1000));
+                       atomic_set(&rwnx_hw->p2p_alive_timer_count, 0);
+               }
+       }
 
        if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP_VLAN) {
                /* For AP_vlan use same fw and drv indexes. We ensure that this index
@@ -1059,9 +1098,24 @@ static int rwnx_close(struct net_device *dev)
        struct aic_sdio_dev *sdiodev = NULL;
 #else
 #endif
+       int waiting_counter = 20;
+       int test_counter = 0;
 
        RWNX_DBG(RWNX_FN_ENTRY_STR);
 
+       test_counter = waiting_counter;
+       while(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING||
+               atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING){
+               AICWFDBG(LOGDEBUG, "%s wifi is connecting or disconnecting, waiting 200ms for state to stable\r\n", __func__);
+               msleep(200);
+               test_counter--;
+               if(test_counter == 0){
+                       AICWFDBG(LOGERROR, "%s connecting or disconnecting, not finish\r\n", __func__);
+                       WARN_ON(1);
+                       break;
+               }
+       }
+
 #if defined(AICWF_USB_SUPPORT) || defined(AICWF_SDIO_SUPPORT)
        if (scanning) {
                scanning = false;
@@ -1143,9 +1197,17 @@ static int rwnx_close(struct net_device *dev)
                if (sdiodev->bus_if->state != BUS_DOWN_ST){
                        if(RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION ||
                                RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT){
-                               if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING){
+                               test_counter = waiting_counter;
+                               if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED){
+                                       atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING);
                                        rwnx_send_sm_disconnect_req(rwnx_hw, rwnx_vif, 3);
-                                       atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED);
+                                       while (atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING) {
+                                               AICWFDBG(LOGDEBUG, "%s wifi is disconnecting, waiting 100ms for state to stable\r\n", __func__);
+                                               msleep(100);
+                                               test_counter--;
+                                               if (test_counter ==0)
+                                                       break;
+                                       }
                                }
                        }
 #ifdef CONFIG_USE_P2P0
@@ -1194,7 +1256,7 @@ static int rwnx_close(struct net_device *dev)
                        }
                }
 #endif
-               clear_bit(RWNX_DEV_STARTED, &rwnx_hw->drv_flags);
+               clear_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags);
        }
 #ifdef CONFIG_COEX
        else {
@@ -1875,7 +1937,7 @@ int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
                                bytes_written = -EINVAL;
                                break;
                        }
-                       if(g_rwnx_plat->sdiodev->chipid != PRODUCT_ID_AIC8800D80){
+                       if(g_rwnx_plat->sdiodev->chipid == PRODUCT_ID_AIC8800D80){
                                memcpy(command, &cfm.rftest_result[0], 6 * 12);
                                bytes_written = 6 * 12;
                        } else {
@@ -2884,12 +2946,22 @@ static struct rwnx_vif *rwnx_interface_add(struct rwnx_hw *rwnx_hw,
        }
 
        if (type == NL80211_IFTYPE_AP_VLAN) {
-               memcpy(ndev->dev_addr, params->macaddr, ETH_ALEN);
-               memcpy(vif->wdev.address, params->macaddr, ETH_ALEN);
+               memcpy((void *)ndev->dev_addr, (const void *)params->macaddr, ETH_ALEN);
+               memcpy((void *)vif->wdev.address, (const void *)params->macaddr, ETH_ALEN);
        } else {
-               memcpy(ndev->dev_addr, rwnx_hw->wiphy->perm_addr, ETH_ALEN);
-               ndev->dev_addr[5] ^= vif_idx;
-               memcpy(vif->wdev.address, ndev->dev_addr, ETH_ALEN);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 17, 0)
+                       unsigned char mac_addr[6];
+                       memcpy(mac_addr, rwnx_hw->wiphy->perm_addr, ETH_ALEN);
+                       mac_addr[5] ^= vif_idx;
+                       //memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+                       eth_hw_addr_set(ndev, mac_addr);
+                       memcpy(vif->wdev.address, mac_addr, ETH_ALEN);
+#else
+                       memcpy(ndev->dev_addr, rwnx_hw->wiphy->perm_addr, ETH_ALEN);
+                       ndev->dev_addr[5] ^= vif_idx;
+                       memcpy(vif->wdev.address, ndev->dev_addr, ETH_ALEN);
+#endif
+
        }
 
        AICWFDBG(LOGINFO, "interface add:%x %x %x %x %x %x\n", vif->wdev.address[0], vif->wdev.address[1], \
@@ -3278,6 +3350,7 @@ static int rwnx_cfg80211_change_iface(struct wiphy *wiphy,
        /* Abort scan request on the vif */
            if (vif->rwnx_hw->scan_request &&
                vif->rwnx_hw->scan_request->wdev == &vif->wdev) {
+#if 0
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
                        struct cfg80211_scan_info info = {
                                .aborted = true,
@@ -3293,6 +3366,12 @@ static int rwnx_cfg80211_change_iface(struct wiphy *wiphy,
                        return ret;
                }
                vif->rwnx_hw->scan_request = NULL;
+#else
+        if ((ret = rwnx_send_scanu_cancel_req(vif->rwnx_hw, NULL))) {
+            AICWFDBG(LOGERROR, "scanu_cancel fail\n");
+            return ret;
+        }
+#endif
            }
            ret = rwnx_send_remove_if(vif->rwnx_hw, vif->vif_index, false);
            if (ret) {
@@ -3400,6 +3479,7 @@ static int rwnx_cfg80211_scan(struct wiphy *wiphy,
        }
 
        if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING){
+               AICWFDBG(LOGERROR, "%s wifi is connecting, return it\r\n", __func__);
                return -EBUSY;
        }
 
@@ -3414,6 +3494,13 @@ static int rwnx_cfg80211_scan(struct wiphy *wiphy,
         return -EBUSY;
        }
 
+       if ((RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION ||
+               RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) &&
+               rwnx_vif->sta.external_auth) {
+               AICWFDBG(LOGERROR, "scan about: external auth\r\n");
+               return -EBUSY;
+       }
+
        rwnx_hw->scan_request = request;
        error = rwnx_send_scanu_req(rwnx_hw, rwnx_vif, request);
        if (error)
@@ -3427,12 +3514,13 @@ bool key_flag = false;
  * @add_key: add a key with the given parameters. @mac_addr will be %NULL
  *     when adding a group key.
  */
-static int rwnx_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
-                                                                 int link_id,
+       static int rwnx_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
+                                                                                                                                        int link_id,
 #endif
-                                                                u8 key_index, bool pairwise, const u8 *mac_addr,
-                                                                struct key_params *params)
+                                                                        u8 key_index, bool pairwise, const u8 *mac_addr,
+                                                                        struct key_params *params)
+
 {
        struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
        struct rwnx_vif *vif = netdev_priv(netdev);
@@ -3524,7 +3612,7 @@ static int rwnx_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
  *
  */
 static int rwnx_cfg80211_get_key(struct wiphy *wiphy, struct net_device *netdev,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
                                                                  int link_id,
 #endif
                                                                 u8 key_index, bool pairwise, const u8 *mac_addr,
@@ -3542,7 +3630,7 @@ static int rwnx_cfg80211_get_key(struct wiphy *wiphy, struct net_device *netdev,
  *     and @key_index, return -ENOENT if the key doesn't exist.
  */
 static int rwnx_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
                                                                  int link_id,
 #endif
                                                                 u8 key_index, bool pairwise, const u8 *mac_addr)
@@ -3581,7 +3669,7 @@ static int rwnx_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
  */
 static int rwnx_cfg80211_set_default_key(struct wiphy *wiphy,
                                                                                 struct net_device *netdev,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
                                                                                  int link_id,
 #endif
                                                                                 u8 key_index, bool unicast, bool multicast)
@@ -3596,7 +3684,7 @@ static int rwnx_cfg80211_set_default_key(struct wiphy *wiphy,
  */
 static int rwnx_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
                                                                                          struct net_device *netdev,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
                                                                                           int link_id,
 #endif
                                                                                          u8 key_index)
@@ -3631,10 +3719,18 @@ static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                        return -EALREADY;
                }
 #endif
-               if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING){
-                       AICWFDBG(LOGERROR, "%s driver is disconnecting return it \r\n", __func__);
-                       return -EALREADY;
-               }
+       if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED) {
+               AICWFDBG(LOGDEBUG, "%s this connection is roam \r\n", __func__);
+               rwnx_vif->sta.is_roam = true;
+       }else{
+               rwnx_vif->sta.is_roam = false; 
+       }
+
+       if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING||
+               (int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING) {
+               AICWFDBG(LOGERROR, "%s driver is disconnecting or connecting ,return it \r\n", __func__);
+               return -EALREADY;
+       }
 #endif
 
                atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTING);
@@ -3675,7 +3771,7 @@ static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                key_params.seq_len = 0;
                key_params.cipher = sme->crypto.cipher_group;
                rwnx_cfg80211_add_key(wiphy, dev, 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41))
+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2)
                                 0,
 #endif
                                sme->key_idx, false, NULL, &key_params);
@@ -3751,6 +3847,12 @@ static int rwnx_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
                msleep(500);
        }
 
+       if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_DISCONNECTING) {
+               AICWFDBG(LOGERROR, "%s wifi is disconnecting, return it:%d \r\n",
+                               __func__, reason_code);
+               return -EBUSY;
+       }
+
        if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTED){
                atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING);
                key_flag = true;
@@ -3759,6 +3861,7 @@ static int rwnx_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
                cfg80211_connect_result(dev,  NULL, NULL, 0, NULL, 0,
                        reason_code?reason_code:WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC);
                atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED);
+               rwnx_external_auth_disable(rwnx_vif);
                return 0;
        }
 
@@ -3935,7 +4038,7 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy,
                sta->vif_idx = rwnx_vif->vif_index;
                sta->vlan_idx = sta->vif_idx;
                sta->qos = (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) != 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41)
+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
                 sta->ht = params->link_sta_params.ht_capa ? 1 : 0;
                 sta->vht = params->link_sta_params.vht_capa ? 1 : 0;
 #else
@@ -4341,7 +4444,7 @@ static int rwnx_cfg80211_change_station(struct wiphy *wiphy,
                                sta->vif_idx = rwnx_vif->vif_index;
                                sta->vlan_idx = sta->vif_idx;
                                sta->qos = (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) != 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41)
+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
                                 sta->ht = params->link_sta_params.ht_capa ? 1 : 0;
                                 sta->vht = params->link_sta_params.vht_capa ? 1 : 0;
 #else
@@ -4588,7 +4691,7 @@ static int rwnx_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *d
 /**
  * * @stop_ap: Stop being an AP, including stopping beaconing.
  */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION)
 static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev, unsigned int link_id)
 #else
 static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
@@ -4990,6 +5093,11 @@ static int rwnx_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
        return rwnx_send_cancel_roc(rwnx_hw);
 }
 
+#define IS_2P4GHZ(n) (n >= 2412 && n <= 2484)
+#define IS_5GHZ(n) (n >= 4000 && n <= 5895)
+#define DEFAULT_NOISE_FLOOR_2GHZ (-89)
+#define DEFAULT_NOISE_FLOOR_5GHZ (-92)
+
 /**
  * @dump_survey: get site survey information.
  */
@@ -5034,7 +5142,9 @@ static int rwnx_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *net
        if (rwnx_survey->filled != 0) {
                SURVEY_TIME(info) = (u64)rwnx_survey->chan_time_ms;
                SURVEY_TIME_BUSY(info) = (u64)rwnx_survey->chan_time_busy_ms;
-               info->noise = rwnx_survey->noise_dbm;
+               //info->noise = rwnx_survey->noise_dbm;
+               info->noise = ((IS_2P4GHZ(info->channel->center_freq)) ? DEFAULT_NOISE_FLOOR_2GHZ :
+                               (IS_5GHZ(info->channel->center_freq)) ? DEFAULT_NOISE_FLOOR_5GHZ : DEFAULT_NOISE_FLOOR_5GHZ);
 
                // Set the survey report as not used
         if(info->noise == 0){
@@ -5055,7 +5165,7 @@ static int rwnx_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *net
  */
 static int rwnx_cfg80211_get_channel(struct wiphy *wiphy,
                                                                          struct wireless_dev *wdev,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
                                                                          unsigned int link_id,
 #endif
                                                                          struct cfg80211_chan_def *chandef)
@@ -5260,7 +5370,7 @@ int rwnx_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
        return rwnx_send_cfg_rssi_req(rwnx_hw, rwnx_vif->vif_index, rssi_thold, rssi_hyst);
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
 /**
  *
  * @channel_switch: initiate channel-switch procedure (with CSA). Driver is
@@ -5349,22 +5459,16 @@ int rwnx_cfg80211_channel_switch (struct wiphy *wiphy,
                goto end;
        } else {
                INIT_WORK(&csa->work, rwnx_csa_finish);
-                rwnx_cfg80211_ch_switch_started_notify(dev
-                                        , &csa->chandef
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
-                                        , 0
-#endif
-                                        , params->count
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
-                                        , false
+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION4
+               cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false, 0);
+#elif LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2
+               cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false);
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
-                                        , params->block_tx
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 94)
-                                        , 0
+               cfg80211_ch_switch_started_notify(dev, &csa->chandef, params->count, params->block_tx);
+#else
+               cfg80211_ch_switch_started_notify(dev, &csa->chandef, params->count);
 #endif
-                                        );
-       
+
        }
 
 end:
@@ -6353,7 +6457,7 @@ static struct cfg80211_ops rwnx_cfg80211_ops = {
        .start_radar_detection = rwnx_cfg80211_start_radar_detection,
        .update_ft_ies = rwnx_cfg80211_update_ft_ies,
        .set_cqm_rssi_config = rwnx_cfg80211_set_cqm_rssi_config,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
        .channel_switch = rwnx_cfg80211_channel_switch,
 #endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
@@ -6563,6 +6667,9 @@ extern int get_wifi_custom_mac_address(char *addr_str);
 #ifdef CONFIG_PLATFORM_ROCKCHIP
 #include <linux/rfkill-wlan.h>
 #endif
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+#include <linux/rfkill-wlan.h>
+#endif
 
 #ifdef CONFIG_USE_CUSTOMER_MAC
 int rwnx_get_custom_mac_addr(u8_l *mac_addr_efuse){
@@ -6585,6 +6692,9 @@ int rwnx_get_custom_mac_addr(u8_l *mac_addr_efuse){
 #ifdef CONFIG_PLATFORM_ROCKCHIP
         ret = rockchip_wifi_mac_addr(mac_addr_efuse);
 #endif//CONFIG_PLATFORM_ROCKCHIP
+#ifdef CONFIG_PLATFORM_ROCKCHIP2
+            ret = rockchip_wifi_mac_addr(mac_addr_efuse);
+#endif//CONFIG_PLATFORM_ROCKCHIP
 
     if(ret == 0){
         AICWFDBG(LOGINFO, "%s %02x:%02x:%02x:%02x:%02x:%02x", __func__,
@@ -6612,6 +6722,9 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data)
        u8_l mac_addr_efuse[ETH_ALEN];
        struct aicbsp_feature_t feature;
        struct mm_set_stack_start_cfm set_start_cfm;
+#ifdef CONFIG_TEMP_COMP
+       struct mm_set_vendor_swconfig_cfm swconfig_cfm;
+#endif
        char fw_path[200];
        (void)addr_str;
 
@@ -6665,6 +6778,10 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data)
                goto err_cache;
        }
 
+#ifdef CONFIG_FILTER_TCP_ACK
+       tcp_ack_init(rwnx_hw);
+#endif
+
 #if 0
        ret = rwnx_parse_configfile(rwnx_hw, RWNX_CONFIG_FW_NAME, &init_conf);
        if (ret) {
@@ -6874,6 +6991,11 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data)
        ret = rwnx_send_reset(rwnx_hw);
        if (ret)
                goto err_lmac_reqs;
+
+#ifdef CONFIG_TEMP_COMP
+       rwnx_send_set_temp_comp_req(rwnx_hw, &swconfig_cfm);
+#endif
+
        ret = rwnx_send_version_req(rwnx_hw, &rwnx_hw->version_cfm);
        if (ret)
                goto err_lmac_reqs;
@@ -7038,6 +7160,9 @@ void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw)
        rwnx_radar_detection_deinit(&rwnx_hw->radar);
        rwnx_platform_off(rwnx_hw, NULL);
        kmem_cache_destroy(rwnx_hw->sw_txhdr_cache);
+#ifdef CONFIG_FILTER_TCP_ACK
+       tcp_ack_deinit(rwnx_hw);
+#endif
     aicwf_wakeup_lock_deinit(rwnx_hw);
        wiphy_free(rwnx_hw->wiphy);
 }
index 30f369f0c5ec4cd195bb3fa2acd31d191b774fe7..4aa6eba9c51b8d774c4854fe4e90927e9474176c 100644 (file)
@@ -1165,6 +1165,11 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
                                                IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
                he_cap->ppe_thres[0] |= 0x10;
        }
+       if (rwnx_hw->mod_params->use_80) {
+               he_cap->ppe_thres[0] |= 0x20;
+               he_cap->ppe_thres[2] |= 0xc0;
+               he_cap->ppe_thres[3] |= 0x07;
+       }
        //if (rwnx_hw->mod_params->use_80)
        {
                he_cap->he_cap_elem.phy_cap_info[0] |=
@@ -1274,6 +1279,11 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
                                                IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
                he_cap->ppe_thres[0] |= 0x10;
        }
+       if (rwnx_hw->mod_params->use_80) {
+           he_cap->ppe_thres[0] |= 0x20;
+           he_cap->ppe_thres[2] |= 0xc0;
+           he_cap->ppe_thres[3] |= 0x07;
+       }
        //if (rwnx_hw->mod_params->use_80)
        {
                he_cap->he_cap_elem.phy_cap_info[0] |=
@@ -1388,6 +1398,11 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
                                                        IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
                        he_cap->ppe_thres[0] |= 0x10;
                }
+               if (rwnx_hw->mod_params->use_80) {
+                   he_cap->ppe_thres[0] |= 0x20;
+                   he_cap->ppe_thres[2] |= 0xc0;
+                   he_cap->ppe_thres[3] |= 0x07;
+               }
                //if (rwnx_hw->mod_params->use_80)
                {
                        he_cap->he_cap_elem.phy_cap_info[0] |=
index eb07e7cced560ff43cc8a6ad2a6dd59839d526a7..662fb9378dff7c292bec6aeb5bea6248d7790889 100644 (file)
@@ -9,6 +9,7 @@
  *
  ****************************************************************************************
  */
+#include <linux/vmalloc.h>
 #include "rwnx_defs.h"
 #include "rwnx_prof.h"
 #include "rwnx_tx.h"
@@ -24,6 +25,7 @@
 #include "rwnx_compat.h"
 #include "aicwf_txrxif.h"
 #include "rwnx_msg_rx.h"
+void rwnx_cfg80211_unlink_bss(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif);
 
 static int rwnx_freq_to_idx(struct rwnx_hw *rwnx_hw, int freq)
 {
@@ -712,8 +714,12 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
        const u8 *extcap_ie;
        const struct ieee_types_extcap *extcap;
        struct ieee80211_channel *chan;
+       struct cfg80211_bss *bss = NULL;
+    struct wireless_dev *wdev = NULL;
+    int retry_counter = 10;
 
        RWNX_DBG(RWNX_FN_ENTRY_STR);
+       wdev = dev->ieee80211_ptr;
 
        /* Retrieve IE addresses and lengths */
        req_ie = (const u8 *)ind->assoc_ie_buf;
@@ -811,7 +817,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
                        rwnx_chanctx_link(rwnx_mon_vif, ind->ch_idx, NULL);
                }
 #endif
-               atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
+               //atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
        } else if (ind->status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
                if (rwnx_vif->wep_enabled) {
                        rwnx_vif->wep_auth_err = true;
@@ -828,21 +834,100 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
         ind->status_code,
         (int)atomic_read(&rwnx_vif->drv_conn_state));
 
+       do {
+               bss = cfg80211_get_bss(wdev->wiphy, NULL, rwnx_vif->sta.bssid,
+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
+                                                       wdev->u.client.ssid, wdev->u.client.ssid_len,
+#else
+                                                       wdev->ssid, wdev->ssid_len,
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
+                                                       wdev->conn_bss_type,
+                                                       IEEE80211_PRIVACY_ANY);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
+                                                       IEEE80211_BSS_TYPE_ESS,
+                                                       IEEE80211_PRIVACY_ANY);
+#else
+                            WLAN_CAPABILITY_ESS,
+                            WLAN_CAPABILITY_PRIVACY);
+#endif
+
+
+               if (!bss) {
+                       printk("%s bss is NULL \r\n", __func__);
+
+                       printk("%s bss ssid(%d):%s conn_bss_type:%d bss2 ssid(%d):%s conn_bss_type:%d\r\n", 
+                               __func__, 
+                               (int)rwnx_vif->sta.ssid_len,
+                               rwnx_vif->sta.ssid,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
+                               IEEE80211_BSS_TYPE_ESS,
+#else
+                               WLAN_CAPABILITY_ESS,
+#endif
+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
+                               (int)wdev->u.client.ssid_len,
+                               wdev->u.client.ssid, 
+#else
+                               (int)wdev->ssid_len,
+                               wdev->ssid,
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
+                               wdev->conn_bss_type
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
+                IEEE80211_BSS_TYPE_ESS
+#else
+                WLAN_CAPABILITY_ESS
+#endif
+                               );
+
+
+                       printk("%s rwnx_vif->sta.bssid %02x %02x %02x %02x %02x %02x \r\n", __func__, 
+                               rwnx_vif->sta.bssid[0], rwnx_vif->sta.bssid[1], rwnx_vif->sta.bssid[2],
+                               rwnx_vif->sta.bssid[3], rwnx_vif->sta.bssid[4], rwnx_vif->sta.bssid[5]);
+
+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
+                       wdev->u.client.ssid_len = (int)rwnx_vif->sta.ssid_len;
+                       memcpy(wdev->u.client.ssid, rwnx_vif->sta.ssid, wdev->u.client.ssid_len);
+#else
+                       wdev->ssid_len = (int)rwnx_vif->sta.ssid_len;
+                       memcpy(wdev->ssid, rwnx_vif->sta.ssid, wdev->ssid_len);
+#endif
+                       msleep(100);
+                       retry_counter--;
+                       if(retry_counter == 0){
+                               printk("%s bss recover fail \r\n", __func__);
+                               break;
+                       }
+               }
+       } while (!bss);
 
        if (!ind->roamed){//not roaming
                cfg80211_connect_result(dev, (const u8 *)ind->bssid.array, req_ie,
                                                                ind->assoc_req_ie_len, rsp_ie,
                                                                ind->assoc_rsp_ie_len, ind->status_code,
                                                                GFP_ATOMIC);
+               if (ind->status_code == 0) {
+                       atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
+               } else {
+                       atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
+                       rwnx_external_auth_disable(rwnx_vif);
+               }
+               AICWFDBG(LOGINFO, "%s cfg80211_connect_result pass, rwnx_vif->drv_conn_state:%d\r\n", 
+                       __func__, 
+                       (int)atomic_read(&rwnx_vif->drv_conn_state));
     }else {//roaming
         if(ind->status_code != 0){
             AICWFDBG(LOGINFO, "%s roaming fail to notify disconnect \r\n", __func__);
                        cfg80211_disconnected(dev, 0, NULL, 0,1, GFP_ATOMIC);
+                       atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED);
+                       rwnx_external_auth_disable(rwnx_vif);
         }else{        
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
                struct cfg80211_roam_info info;
                memset(&info, 0, sizeof(info));
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
             if (rwnx_vif->ch_index < NX_CHAN_CTXT_CNT)
                     info.links[0].channel = rwnx_hw->chanctx_table[rwnx_vif->ch_index].chan_def.chan;
             info.links[0].bssid = (const u8 *)ind->bssid.array;
@@ -856,6 +941,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
                info.resp_ie = rsp_ie;
                info.resp_ie_len = ind->assoc_rsp_ie_len;
                cfg80211_roamed(dev, &info, GFP_ATOMIC);
+                       atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
 #else
                chan = ieee80211_get_channel(rwnx_hw->wiphy, ind->center_freq);
                cfg80211_roamed(dev
@@ -869,6 +955,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
                        , ind->assoc_rsp_ie_len
                        , GFP_ATOMIC);
 #endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)*/
+                       atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED);
        }
         }
        netif_tx_start_all_queues(dev);
@@ -877,6 +964,36 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw,
        return 0;
 }
 
+void rwnx_cfg80211_unlink_bss(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif){
+       struct wiphy *wiphy = rwnx_hw->wiphy;
+       struct cfg80211_bss *bss = NULL;
+
+       RWNX_DBG(RWNX_FN_ENTRY_STR);
+
+       bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
+               rwnx_vif->sta.bssid, rwnx_vif->sta.ssid,
+               rwnx_vif->sta.ssid_len,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
+               IEEE80211_BSS_TYPE_ESS,
+               IEEE80211_PRIVACY(true));//temp set true
+#else
+               WLAN_CAPABILITY_ESS,
+               WLAN_CAPABILITY_ESS);
+#endif
+
+       if (bss) {
+               cfg80211_unlink_bss(wiphy, bss);
+               AICWFDBG(LOGINFO, "%s(): cfg80211_unlink %s!!\n", __func__, rwnx_vif->sta.ssid);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+               cfg80211_put_bss(wiphy, bss);
+#else
+               cfg80211_put_bss(bss);
+#endif
+       }else{
+               AICWFDBG(LOGINFO, "%s(): cfg80211_unlink error %s!!\n", __func__, rwnx_vif->sta.ssid);
+       }
+}
+
 extern u8 dhcped;
 static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
                                                                                        struct rwnx_cmd *cmd,
@@ -892,12 +1009,23 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
 #endif
 
        RWNX_DBG(RWNX_FN_ENTRY_STR);
+       if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTED){
+               AICWFDBG(LOGINFO, "%s, is already disconnected, drop disconnect ind", __func__);
+               return 0;
+       }
+
        dhcped = 0;
 
        if(!rwnx_vif)
                return 0;
        dev = rwnx_vif->ndev;
 
+       if (rwnx_vif->sta.is_roam == false) {
+               rwnx_cfg80211_unlink_bss(rwnx_hw, rwnx_vif);
+       } else {
+               AICWFDBG(LOGINFO, "%s roaming no rwnx_cfg80211_unlink_bss \r\n", __func__);
+       }
+
        #ifdef CONFIG_BR_SUPPORT
                struct rwnx_vif *vif = netdev_priv(dev);
                         /* clear bridge database */
@@ -928,13 +1056,13 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
        rx_priv = rwnx_hw->usbdev->rx_priv;
 #endif
        if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) {
-               macaddr = rwnx_vif->ndev->dev_addr;
+               macaddr = (u8*)rwnx_vif->ndev->dev_addr;
                printk("deinit:macaddr:%x,%x,%x,%x,%x,%x\r\n", macaddr[0], macaddr[1], macaddr[2], \
                                                           macaddr[3], macaddr[4], macaddr[5]);
 
-               spin_lock_bh(&rx_priv->stas_reord_lock);
+               //spin_lock_bh(&rx_priv->stas_reord_lock);
                list_for_each_entry_safe(reord_info, tmp, &rx_priv->stas_reord_list, list) {
-                       macaddr = rwnx_vif->ndev->dev_addr;
+                       macaddr = (u8*)rwnx_vif->ndev->dev_addr;
                        printk("reord_mac:%x,%x,%x,%x,%x,%x\r\n", reord_info->mac_addr[0], reord_info->mac_addr[1], reord_info->mac_addr[2], \
                                                                   reord_info->mac_addr[3], reord_info->mac_addr[4], reord_info->mac_addr[5]);
                        if (!memcmp(reord_info->mac_addr, macaddr, 6)) {
@@ -942,7 +1070,7 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
                                break;
                        }
                }
-               spin_unlock_bh(&rx_priv->stas_reord_lock);
+               //spin_unlock_bh(&rx_priv->stas_reord_lock);
        } else if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
                BUG();//should be not here: del_sta function
        }
@@ -973,6 +1101,9 @@ static inline int rwnx_rx_sm_external_auth_required_ind(struct rwnx_hw *rwnx_hw,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL)
        struct net_device *dev = rwnx_vif->ndev;
        struct cfg80211_external_auth_params params;
+       int ret = 0;
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       int retry_counter = 10;
 
        RWNX_DBG(RWNX_FN_ENTRY_STR);
 
@@ -983,11 +1114,28 @@ static inline int rwnx_rx_sm_external_auth_required_ind(struct rwnx_hw *rwnx_hw,
                   min_t(size_t, ind->ssid.length, sizeof(params.ssid.ssid)));
        params.key_mgmt_suite = ind->akm;
 
+       while (wdev->conn_owner_nlportid == 0) {
+               AICWFDBG(LOGINFO, "%s WARNING conn_owner_nlportid = 0, msleep 100ms.\r\n", __func__);
+               msleep(100);
+               retry_counter--;
+               if (retry_counter == 0) {
+                       break;
+               }
+       }
+       AICWFDBG(LOGINFO, "%s wdev->conn_owner_nlportid:%d \r\n", __func__, (int)wdev->conn_owner_nlportid);
+
+       if (wdev->conn_owner_nlportid != 0) {
+               rwnx_vif->sta.conn_owner_nlportid = wdev->conn_owner_nlportid;
+       } else {
+               AICWFDBG(LOGINFO, "%s try to recover conn_owner_nlportid\r\n", __func__);
+               wdev->conn_owner_nlportid = rwnx_vif->sta.conn_owner_nlportid;
+       }
+
        if ((ind->vif_idx > NX_VIRT_DEV_MAX) || !rwnx_vif->up ||
                (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_STATION) ||
-               cfg80211_external_auth_request(dev, &params, GFP_ATOMIC)) {
-               wiphy_err(rwnx_hw->wiphy, "Failed to start external auth on vif %d",
-                                 ind->vif_idx);
+               (ret = cfg80211_external_auth_request(dev, &params, GFP_ATOMIC))) {
+               wiphy_err(rwnx_hw->wiphy, "Failed to start external auth on vif %d, rwnx_vif->up %d, iftype:%d, ret %d",
+                                 ind->vif_idx, rwnx_vif->up, RWNX_VIF_TYPE(rwnx_vif), ret);
                rwnx_send_sm_external_auth_required_rsp(rwnx_hw, rwnx_vif,
                                                                                                WLAN_STATUS_UNSPECIFIED_FAILURE);
                return 0;
index 71f25884147b403377260cf2cd855650de160943..054afeb7a5c3b0b195558c36e1858995e488b724 100644 (file)
@@ -1025,7 +1025,7 @@ int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *
        rf_calib_req->cal_cfg_24g = 0x0f8f;
        rf_calib_req->cal_cfg_5g = 0x0f0f;
     }
-    
+
        rf_calib_req->param_alpha = 0x0c34c008;
        rf_calib_req->bt_calib_en = 0;
        rf_calib_req->bt_calib_param = 0x264203;
@@ -1116,33 +1116,33 @@ int rwnx_send_set_stack_start_req(struct rwnx_hw *rwnx_hw, u8_l on, u8_l efuse_v
        return error;
 }
 
-#if 0
-int rwnx_send_txop_req(struct rwnx_hw *rwnx_hw, uint16_t *txop, u8_l long_nav_en, u8_l cfe_en)
+int rwnx_send_set_temp_comp_req(struct rwnx_hw *rwnx_hw, struct mm_set_vendor_swconfig_cfm *cfm)
 {
-       struct mm_set_txop_req *req;
-       int error;
-
-       /* Build the MM_SET_TXOP_REQ message */
-        req = rwnx_msg_zalloc(MM_SET_TXOP_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_txop_req));
-
-        if (!req) {
-                return -ENOMEM;
-        }
+       struct mm_set_vendor_swconfig_req *req;
+       int ret;
 
-        req->txop_bk = txop[0];
-       req->txop_be = txop[1];
-       req->txop_vi = txop[2];
-       req->txop_vo = txop[3];
-        req->long_nav_en = long_nav_en;
-        req->cfe_en = cfe_en;
-        /* Send the MM_SET_TXOP_REQ  message to UMAC FW */
-        error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_TXOP_CFM, NULL);
+       RWNX_DBG(RWNX_FN_ENTRY_STR);
+       /* Build the TEMP_COMP_SET_REQ message */
+       req = rwnx_msg_zalloc(MM_SET_VENDOR_SWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_vendor_swconfig_req));
+       if (!req) {
+               printk("%s msg_alloc fail\n", __func__);
+               return -ENOMEM;
+       }
+       req->swconfig_id = TEMP_COMP_SET_REQ;
+       req->temp_comp_set_req.enable = 1;
+       req->temp_comp_set_req.tmr_period_ms = 15 * 1000;
 
-        return error;
+       ret = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, cfm);
+       if (!ret)
+               printk("temp_comp status: %d\n", cfm->temp_comp_set_cfm.status);
+       else {
+               printk("%s msg_fail\n", __func__);
+               return ret;
+       }
+       return ret;
 }
-#endif
 
-int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param)
+int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param, int32_t *param_out)
 {
        struct mm_set_acs_txop_req *req0;
        struct mm_set_channel_access_req *req1;
@@ -1150,7 +1150,7 @@ int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id,
        struct mm_set_cca_threshold_req *req3;
        struct mm_set_bwmode_req *req4;
 
-       int error;
+       int error = 0;
 
        switch (hwconfig_id)
        {
@@ -1188,8 +1188,9 @@ int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id,
                req1->rc_retry_cnt[0] = param[9];
                req1->rc_retry_cnt[1] = param[10];
                req1->rc_retry_cnt[2] = param[11];
-               printk("set_channel_access_req:edca[]= %x %x %x %x\nvif_idx: %x, retry_cnt: %x, rts_en: %x, long_nav_en: %x, cfe_en: %x, rc_retry_cnt: %x:%x:%x\n",
-                       req1->edca[0], req1->edca[1], req1->edca[2], req1->edca[3], req1->vif_idx, req1->retry_cnt, req1->rts_en, req1->long_nav_en, req1->cfe_en, req1->rc_retry_cnt[0],req1->rc_retry_cnt[1], req1->rc_retry_cnt[2]);
+               req1->ccademod_th = param[12];
+               printk("set_channel_access_req:edca[]= %x %x %x %x\nvif_idx: %x, retry_cnt: %x, rts_en: %x, long_nav_en: %x, cfe_en: %x, rc_retry_cnt: %x:%x:%x, ccademod_th = %d\n",
+                       req1->edca[0], req1->edca[1], req1->edca[2], req1->edca[3], req1->vif_idx, req1->retry_cnt, req1->rts_en, req1->long_nav_en, req1->cfe_en, req1->rc_retry_cnt[0],req1->rc_retry_cnt[1], req1->rc_retry_cnt[2], req1->ccademod_th);
                /* Send the MM_SET_VENDOR_HWCONFIG_CFM  message to UMAC FW */
                error = rwnx_send_msg(rwnx_hw, req1, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL);
                break;
@@ -1239,12 +1240,95 @@ int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id,
                 /* Send the MM_SET_VENDOR_HWCONFIG_CFM  message to UMAC FW */
                error = rwnx_send_msg(rwnx_hw, req4, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL);
                break;
+        case CHIP_TEMP_GET_REQ:
+        if ((rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DC) ||
+            (rwnx_hw->sdiodev->chipid == PRODUCT_ID_AIC8800DW))
+        {
+            struct mm_get_chip_temp_req *req;
+            struct mm_set_vendor_hwconfig_cfm cfm = {0,};
+            /* Build the CHIP_TEMP_GET_REQ message */
+            req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_get_chip_temp_req));
+            if (!req)
+                return -ENOMEM;
+            req->hwconfig_id = hwconfig_id;
+            /* Send the MM_SET_VENDOR_HWCONFIG_REQ  message to UMAC FW */
+            error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, &cfm);
+            if (!error) {
+                if (param_out) {
+                    param_out[0] = (int32_t)cfm.chip_temp_cfm.degree;
+                }
+                printk("get_chip_temp degree=%d\n", cfm.chip_temp_cfm.degree);
+            } else {
+                printk("get_chip_temp err=%d\n", error);
+            }
+        }
+        break;
            default:
                return -ENOMEM;
        }
     return error;
 }
 
+int rwnx_send_vendor_swconfig_req(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, int32_t *param_in, int32_t *param_out)
+{
+    struct mm_set_vendor_swconfig_req *req;
+    struct mm_set_vendor_swconfig_cfm cfm = {0,};
+    int error;
+
+    req = rwnx_msg_zalloc(MM_SET_VENDOR_SWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_vendor_swconfig_req));
+    if (!req) {
+        return -ENOMEM;
+    }
+    req->swconfig_id = swconfig_id;
+
+    switch (swconfig_id)
+    {
+        case BCN_CFG_REQ:
+            /* Build the BCN_CFG_REQ message */
+            req->bcn_cfg_req.tim_bcmc_ignored_enable = (bool_l)param_in[0];
+            printk("bcn_cfg_req: tim_bcmc_ignd=%d\n", req->bcn_cfg_req.tim_bcmc_ignored_enable);
+            /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */
+            error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm);
+            if (!error) {
+                param_out[0] = (int32_t)cfm.bcn_cfg_cfm.tim_bcmc_ignored_status;
+                printk("status=%d\n", cfm.bcn_cfg_cfm.tim_bcmc_ignored_status);
+            }
+            break;
+
+        case TEMP_COMP_SET_REQ:
+            /* Build the TEMP_COMP_SET_REQ message */
+            req->temp_comp_set_req.enable = (u8_l)param_in[0];
+            req->temp_comp_set_req.tmr_period_ms = (u32_l)param_in[1];
+            printk("temp_comp_set_req: en=%d, tmr=%x\n",
+                req->temp_comp_set_req.enable, req->temp_comp_set_req.tmr_period_ms);
+            /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */
+            error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm);
+            if (!error) {
+                param_out[0] = (int32_t)cfm.temp_comp_set_cfm.status;
+                printk("status=%d\n", cfm.temp_comp_set_cfm.status);
+            }
+            break;
+
+        case TEMP_COMP_GET_REQ:
+            printk("temp_comp_get_req\n");
+            /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */
+            error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm);
+            if (!error) {
+                param_out[0] = (int32_t)cfm.temp_comp_get_cfm.status;
+                param_out[1] = (int32_t)cfm.temp_comp_get_cfm.degree;
+                printk("status=%d, degree=%d\n",
+                    cfm.temp_comp_get_cfm.status, cfm.temp_comp_get_cfm.degree);
+            }
+            break;
+
+        default:
+            error = -ENOMEM;
+            break;
+    }
+
+    return error;
+}
+
 
 int rwnx_send_get_fw_version_req(struct rwnx_hw *rwnx_hw, struct mm_get_fw_version_cfm *cfm)
 {
@@ -1831,8 +1915,8 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par
                                                 const u8 *mac, u8 inst_nbr, struct me_sta_add_cfm *cfm)
 {
        struct me_sta_add_req *req;
-    
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 41)
+
+#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
     struct link_station_parameters *link_sta_params = &params->link_sta_params;
 #else
     struct station_parameters *link_sta_params = params;
@@ -1862,7 +1946,7 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par
        /* Set parameters for the MM_STA_ADD_REQ message */
        memcpy(&(req->mac_addr.array[0]), mac, ETH_ALEN);
 
-       req->rate_set.length = link_sta_params->supported_rates_len;;
+       req->rate_set.length = link_sta_params->supported_rates_len;
        for (i = 0; i < link_sta_params->supported_rates_len; i++)
                req->rate_set.array[i] = link_sta_params->supported_rates[i];
 
@@ -2205,15 +2289,19 @@ int rwnx_send_sm_connect_req(struct rwnx_hw *rwnx_hw,
                rwnx_vif->last_auth_type = sme->auth_type;
        }
 
+       rwnx_vif->sta.ssid_len = (int)sme->ssid_len;
+       memset(rwnx_vif->sta.ssid, 0, rwnx_vif->sta.ssid_len + 1);
+       memcpy(rwnx_vif->sta.ssid, sme->ssid, rwnx_vif->sta.ssid_len);
+       memcpy(rwnx_vif->sta.bssid, sme->bssid, ETH_ALEN);
+
        printk("%s drv_vif_index:%d connect to %s(%d) channel:%d auth_type:%d\r\n",
                __func__,
                rwnx_vif->drv_vif_index,
-               sme->ssid,
-               (int)sme->ssid_len,
+               rwnx_vif->sta.ssid,
+               rwnx_vif->sta.ssid_len,
                req->chan.freq,
                req->auth_type);
 
-
        /* Send the SM_CONNECT_REQ message to LMAC FW */
        return rwnx_send_msg(rwnx_hw, req, 1, SM_CONNECT_CFM, cfm);
 
@@ -2493,7 +2581,7 @@ int rwnx_send_scanu_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
                        if (rwnx_vif->is_p2p_vif && !rwnx_hw->is_p2p_alive) {
 #else
                        if (rwnx_vif == rwnx_hw->p2p_dev_vif && !rwnx_vif->up) {
-#endif                 
+#endif
                                err = rwnx_send_add_if (rwnx_hw, rwnx_vif->wdev.address,
                                                                                          RWNX_VIF_TYPE(rwnx_vif), false, &add_if_cfm);
                                if (err)
index 99f1017ca756f36e58b2f99f22e553d7ace27d15..a3890fe2b26db2be6be089ebdf5e55bdd2d89387 100644 (file)
@@ -166,7 +166,9 @@ int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_
 int rwnx_send_set_stack_start_req(struct rwnx_hw *rwnx_hw, u8_l on, u8_l efuse_valid, u8_l set_vendor_info,
                                        u8_l fwtrace_redir_en, struct mm_set_stack_start_cfm *cfm);
 int rwnx_send_txop_req(struct rwnx_hw *rwnx_hw, uint16_t *txop, u8_l long_nav_en, u8_l cfe_en);
-int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param);
+int rwnx_send_set_temp_comp_req(struct rwnx_hw *rwnx_hw, struct mm_set_vendor_swconfig_cfm *cfm);
+int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param, int32_t *param_out);
+int rwnx_send_vendor_swconfig_req(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, int32_t *param_in, int32_t *param_out);
 int rwnx_send_get_fw_version_req(struct rwnx_hw *rwnx_hw, struct mm_get_fw_version_cfm *cfm);
 int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw);
 int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw);
index e5e8475eb0b016a74f9c75f852e3b1f592ccd4a8..9250612349d3271060624289821334bd20d6501a 100644 (file)
@@ -33,6 +33,9 @@
 #endif
 
 #define RWNX_FCU_FW_NAME                "fcuram.bin"
+#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
+#define FW_DPDRESULT_NAME_8800DC        "aic_dpdresult_lite_8800dc.bin"
+#endif
 
 /**
  * Type of memory to access (cf rwnx_plat.get_address)
index 5f650bc8fb4860b1a4d415c328531c0d8967e307..02641e41bd3298b9708c6c68195654cb8dcf0cde 100644 (file)
@@ -410,6 +410,11 @@ static void rwnx_rx_data_skb_forward(struct rwnx_hw *rwnx_hw, struct rwnx_vif *r
        rx_skb->protocol = eth_type_trans(rx_skb, rwnx_vif->ndev);
        memset(rx_skb->cb, 0, sizeof(rx_skb->cb));
        REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_IEEE80211RX);
+
+       #ifdef CONFIG_FILTER_TCP_ACK
+       filter_rx_tcp_ack(rwnx_hw,rx_skb->data, cpu_to_le16(rx_skb->len));
+       #endif
+
        #ifdef CONFIG_RX_NETIF_RECV_SKB //modify by aic
        local_bh_disable();
        netif_receive_skb(rx_skb);
@@ -445,6 +450,7 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
        struct sk_buff_head list;
        struct sk_buff *rx_skb;
        bool amsdu = rxhdr->flags_is_amsdu;
+       u8 flags_dst_idx = rxhdr->flags_dst_idx;
        bool resend = false, forward = true;
 
        skb->dev = rwnx_vif->ndev;
@@ -452,6 +458,9 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
        __skb_queue_head_init(&list);
 
        if (amsdu) {
+               #if 1
+        rwnx_rxdata_process_amsdu(rwnx_hw, skb, rxhdr->flags_vif_idx, &list); //rxhdr not used below since skb free!
+               #else
                int count;
                ieee80211_amsdu_to_8023s(skb, &list, rwnx_vif->ndev->dev_addr,
                                                                 RWNX_VIF_TYPE(rwnx_vif), 0, NULL, NULL);
@@ -460,6 +469,7 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
                if (count > ARRAY_SIZE(rwnx_hw->stats.amsdus_rx))
                        count = ARRAY_SIZE(rwnx_hw->stats.amsdus_rx);
                rwnx_hw->stats.amsdus_rx[count - 1]++;
+               #endif
        } else {
                rwnx_hw->stats.amsdus_rx[0]++;
                __skb_queue_head(&list, skb);
@@ -481,8 +491,8 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
                } else {
                        /* unicast pkt for STA inside the BSS, no need to forward to upper
                           layer simply resend on wireless interface */
-                       if (rxhdr->flags_dst_idx != RWNX_INVALID_STA) {
-                               struct rwnx_sta *sta = &rwnx_hw->sta_table[rxhdr->flags_dst_idx];
+                       if (flags_dst_idx != RWNX_INVALID_STA) {
+                struct rwnx_sta *sta = &rwnx_hw->sta_table[flags_dst_idx];
                                if (sta->valid && (sta->vlan_idx == rwnx_vif->vif_index)) {
                                        forward = false;
                                        resend = true;
@@ -498,7 +508,7 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
                if (!is_multicast_ether_addr(eth->h_dest)) {
                        /* unicast pkt for STA inside the BSS, no need to forward to upper
                           layer simply resend on wireless interface */
-                       if (rxhdr->flags_dst_idx != RWNX_INVALID_STA) {
+                       if (flags_dst_idx != RWNX_INVALID_STA) {
                                forward = false;
                                resend = true;
                        }
@@ -577,6 +587,11 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
 #endif
                        memset(rx_skb->cb, 0, sizeof(rx_skb->cb));
             REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_IEEE80211RX);
+
+#ifdef CONFIG_FILTER_TCP_ACK
+                       filter_rx_tcp_ack(rwnx_hw,rx_skb->data, cpu_to_le16(rx_skb->len));
+#endif
+
             #ifdef CONFIG_RX_NETIF_RECV_SKB //modify by aic
             local_bh_disable();
                        netif_receive_skb(rx_skb);
@@ -707,23 +722,48 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
                if ((RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_MESH_POINT) &&
                        hw_rxhdr->flags_new_peer) {
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0))
+#ifdef CONFIG_GKI
+            rwnx_cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa,
+                                               mgmt->u.beacon.variable,
+                                               skb->len - offsetof(struct ieee80211_mgmt,
+                                                                   u.beacon.variable),
+                                               GFP_ATOMIC);
+#else
                        cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa,
                                                                                           mgmt->u.beacon.variable,
                                                                                           skb->len - offsetof(struct ieee80211_mgmt,
                                                                                                                                   u.beacon.variable),
                                                                                           GFP_ATOMIC);
+#endif
 #else
+
+#ifdef CONFIG_GKI
                        /* TODO: the value of parameter sig_dbm need to be confirmed */
                        rwnx_cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa,
                                                                                           mgmt->u.beacon.variable,
                                                                                           skb->len - offsetof(struct ieee80211_mgmt,
                                                                                                                                   u.beacon.variable),
                                                                                           rxvect->rssi1, GFP_ATOMIC);
+#else
+            /* TODO: the value of parameter sig_dbm need to be confirmed */
+            cfg80211_notify_new_peer_candidate(rwnx_vif->ndev, mgmt->sa,
+                                               mgmt->u.beacon.variable,
+                                               skb->len - offsetof(struct ieee80211_mgmt,
+                                                                   u.beacon.variable),
+                                               rxvect->rssi1, GFP_ATOMIC);
+#endif
+
 #endif
                } else {
+#ifdef CONFIG_GKI
                        rwnx_cfg80211_report_obss_beacon(rwnx_hw->wiphy, skb->data, skb->len,
                                                                                hw_rxhdr->phy_info.phy_prim20_freq,
                                                                                rxvect->rssi1);
+#else
+            cfg80211_report_obss_beacon(rwnx_hw->wiphy, skb->data, skb->len,
+                                        hw_rxhdr->phy_info.phy_prim20_freq,
+                                        rxvect->rssi1);
+#endif
                }
        } else if ((ieee80211_is_deauth(mgmt->frame_control) ||
                                ieee80211_is_disassoc(mgmt->frame_control)) &&
@@ -1212,7 +1252,11 @@ static int rwnx_rx_monitor(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
        skb->ip_summed = CHECKSUM_UNNECESSARY;
        skb->pkt_type = PACKET_OTHERHOST;
        skb->protocol = htons(ETH_P_802_2);
-    
+
+#ifdef CONFIG_FILTER_TCP_ACK
+       filter_rx_tcp_ack(rwnx_hw,skb->data, cpu_to_le16(skb->len));
+#endif
+
     local_bh_disable();
        netif_receive_skb(skb);
     local_bh_enable();
@@ -1426,6 +1470,8 @@ int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prfr
        struct list_head *rxframes_freequeue = NULL;
        struct sk_buff *skb = NULL;
        struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif;
+       struct sk_buff_head list;
+       struct sk_buff *rx_skb;
 
        rxframes_freequeue = &rx_priv->rxframes_freequeue;
        skb = prframe->pkt;
@@ -1468,49 +1514,64 @@ int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prfr
                return 0;
        }
 
-       skb->data = prframe->rx_data;
-       skb_set_tail_pointer(skb, prframe->len);
-       skb->len = prframe->len;
+       //skb->data = prframe->rx_data;
+       //skb_set_tail_pointer(skb, prframe->len);
+       //skb->len = prframe->len;
+    __skb_queue_head_init(&list);
+    //printk("sg:%d\n", prframe->is_amsdu);
+    if(prframe->is_amsdu) {
+        rwnx_rxdata_process_amsdu(rwnx_vif->rwnx_hw, skb, rwnx_vif->vif_index, &list); //rxhdr not used below since skb free!
+    } else {
+       __skb_queue_head(&list, skb);
+    }
 
-       rwnx_vif->net_stats.rx_packets++;
-       rwnx_vif->net_stats.rx_bytes += skb->len;
-       //printk("netif sn=%d, len=%d\n", precv_frame->attrib.seq_num, skb->len);
 
-       skb->dev = rwnx_vif->ndev;
-       skb->protocol = eth_type_trans(skb, rwnx_vif->ndev);
+    while (!skb_queue_empty(&list)) {
+        rx_skb = __skb_dequeue(&list);
+
+       rwnx_vif->net_stats.rx_packets++;
+       rwnx_vif->net_stats.rx_bytes += rx_skb->len;
+       //printk("netif sn=%d, len=%d\n", precv_frame->attrib.seq_num, skb->len);
+
+       rx_skb->dev = rwnx_vif->ndev;
+       rx_skb->protocol = eth_type_trans(rx_skb, rwnx_vif->ndev);
 
 #ifdef AICWF_ARP_OFFLOAD
-       if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) {
-               arpoffload_proc(skb, rwnx_vif);
-       }
+       if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) {
+               arpoffload_proc(rx_skb, rwnx_vif);
+       }
+#endif
+       memset(rx_skb->cb, 0, sizeof(rx_skb->cb));
+
+#ifdef CONFIG_FILTER_TCP_ACK
+       filter_rx_tcp_ack(rwnx_vif->rwnx_hw,rx_skb->data, cpu_to_le16(skb->len));
 #endif
-    memset(skb->cb, 0, sizeof(skb->cb));
 
 #ifdef CONFIG_RX_NETIF_RECV_SKB//AIDEN test
-    local_bh_disable();
-       netif_receive_skb(skb);
-    local_bh_enable();
+       local_bh_disable();
+       netif_receive_skb(rx_skb);
+       local_bh_enable();
 #else
-    if (in_interrupt()) {
-        netif_rx(skb);
-    } else {
-    /*
-    * If the receive is not processed inside an ISR, the softirqd must be woken explicitly to service the NET_RX_SOFTIRQ.
-    * * In 2.6 kernels, this is handledby netif_rx_ni(), but in earlier kernels, we need to do it manually.
-    */
+        if (in_interrupt()) {
+            netif_rx(rx_skb);
+        } else {
+            /*
+             * If the receive is not processed inside an ISR, the softirqd must be woken explicitly to service the NET_RX_SOFTIRQ.
+             * * In 2.6 kernels, this is handledby netif_rx_ni(), but in earlier kernels, we need to do it manually.
+             */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
-               netif_rx_ni(skb);
+            netif_rx_ni(rx_skb);
 #else
-               ulong flags;
-               netif_rx(skb);
-               local_irq_save(flags);
-               RAISE_RX_SOFTIRQ();
-               local_irq_restore(flags);
+            ulong flags;
+            netif_rx(rx_skb);
+            local_irq_save(flags);
+            RAISE_RX_SOFTIRQ();
+            local_irq_restore(flags);
 #endif
+        }
+#endif /* CONFIG_RX_NETIF_RECV_SKB */
     }
-#endif//CONFIG_RX_NETIF_RECV_SKB
-    //rwnx_vif->net_stats.rx_packets++;
-    //rwnx_vif->net_stats.rx_bytes += skb->len;
+
     prframe->pkt = NULL;
     reord_rxframe_free(&rx_priv->freeq_lock, rxframes_freequeue, &prframe->rxframe_list);
 
@@ -1627,7 +1688,7 @@ void reord_timeout_worker(struct work_struct *work)
     return ;
 }
 
-int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 seq_num, u8 tid, u8 forward)
+int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 seq_num, u8 tid, u8 forward, u8 is_amsdu)
 {
        int ret = 0;
        u8 *mac;
@@ -1654,10 +1715,11 @@ int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 s
        pframe->seq_num = seq_num;
        pframe->tid = tid;
        pframe->rx_data = skb->data;
-       pframe->len = skb->len;
+       //pframe->len = skb->len;
        pframe->pkt = skb;
        pframe->forward = forward;
        preorder_ctrl = pframe->preorder_ctrl;
+       pframe->is_amsdu = is_amsdu;
 
        if ((ntohs(eh->h_proto) == ETH_P_PAE) || is_mcast)
                return reord_single_frame_ind(rx_priv, pframe);
@@ -1709,23 +1771,26 @@ int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 s
 
     spin_lock_bh(&preorder_ctrl->reord_list_lock);
     if (reord_need_check(preorder_ctrl, pframe->seq_num)) {
-               if(pframe->rx_data[42] == 0x80){//this is rtp package
-                       if(pframe->seq_num == preorder_ctrl->ind_sn){
-                               //printk("%s pframe->seq_num1:%d \r\n", __func__, pframe->seq_num);
-                       reord_single_frame_ind(rx_priv, pframe);//not need to reorder
-                       }else{
-                               printk("%s free pframe->seq_num:%d \r\n", __func__, pframe->seq_num);
-                           if (pframe->pkt){
-                               dev_kfree_skb(pframe->pkt);
-                               pframe->pkt = NULL;
-                           }
-                               reord_rxframe_free(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue, &pframe->rxframe_list);
-                       }
-               }else{
-                       //printk("%s pframe->seq_num2:%d \r\n", __func__, pframe->seq_num);
-                       reord_single_frame_ind(rx_priv, pframe);//not need to reorder
-               }
-
+#if 0
+        if(pframe->rx_data[42] == 0x80){//this is rtp package
+            if(pframe->seq_num == preorder_ctrl->ind_sn){
+                printk("%s pframe->seq_num1:%d \r\n", __func__, pframe->seq_num);
+                reord_single_frame_ind(rx_priv, pframe);//not need to reorder
+            }else{
+                printk("%s free pframe->seq_num:%d \r\n", __func__, pframe->seq_num);
+                if (pframe->pkt){
+                    dev_kfree_skb(pframe->pkt);
+                    pframe->pkt = NULL;
+                }
+                reord_rxframe_free(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue, &pframe->rxframe_list);
+            }
+        }else{
+            //printk("%s pframe->seq_num2:%d \r\n", __func__, pframe->seq_num);
+            reord_single_frame_ind(rx_priv, pframe);//not need to reorder
+        }
+#else
+        reord_single_frame_ind(rx_priv, pframe);//not need to reor
+#endif
         spin_unlock_bh(&preorder_ctrl->reord_list_lock);
                return 0;
     }
@@ -1851,6 +1916,65 @@ void defrag_timeout_cb(struct timer_list *t)
        spin_unlock_bh(&defrag_ctrl->rwnx_hw->defrag_lock);
 }
 
+void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx,
+                                        struct sk_buff_head *list)
+{
+       u16 len_alligned = 0;
+       u16 sublen = 0;
+       struct sk_buff *sub_skb = NULL;
+    struct rwnx_vif *rwnx_vif;
+
+    //if (is_amsdu) 
+    {
+        //skb_pull(skb, pull_len-8);
+        /* |amsdu sub1 | amsdu sub2 | ... */
+        len_alligned = 0;
+        sublen = 0;
+        sub_skb = NULL;
+        while (skb->len > 16) {
+            sublen = (skb->data[12]<<8)|(skb->data[13]);
+            if (skb->len > (sublen+14))
+                len_alligned = roundup(sublen + 14, 4);
+            else if (skb->len == (sublen+14))
+                len_alligned = sublen+14;
+            else {
+                printk("accroding to amsdu: this will not happen\n");
+                break;
+            }
+            //printk("sublen = %d, %x, %x, %x, %x\r\n", sublen,skb->data[0], skb->data[1], skb->data[12], skb->data[13]);
+#if 1
+            sub_skb = __dev_alloc_skb(sublen - 6 + 12, GFP_KERNEL);
+            if(!sub_skb){
+                printk("sub_skb alloc fail:%d\n", sublen);
+                break;
+            }
+            skb_put(sub_skb, sublen - 6 + 12);
+            memcpy(sub_skb->data, skb->data, MAC_ADDR_LEN);
+            memcpy(&sub_skb->data[6], &skb->data[6], MAC_ADDR_LEN);
+            memcpy(&sub_skb->data[12], &skb->data[14 + 6], sublen - 6);
+
+            rwnx_vif = rwnx_rx_get_vif(rwnx_hw, vif_idx);
+            if (!rwnx_vif) {
+                printk("Frame received but no active vif (%d)", vif_idx);
+                //dev_kfree_skb(sub_skb);
+                break;
+            }
+
+            __skb_queue_tail(list, sub_skb);
+
+            //printk("a:%p\n", sub_skb);
+            //if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, sub_skb, hw_rxhdr))
+            //    dev_kfree_skb(sub_skb);
+#endif
+            skb_pull(skb, len_alligned);
+        }
+        //printk("af:%p\n", skb);
+
+        dev_kfree_skb(skb);
+        //return 0;
+    }
+}
+
 u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
 {
        struct hw_rxhdr *hw_rxhdr;
@@ -1877,9 +2001,6 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv)
        u8 sta_idx = 0;
        u16_l frame_ctrl;
        u8 is_amsdu = 0;
-       u16 len_alligned = 0;
-       u16 sublen = 0;
-       struct sk_buff *sub_skb = NULL;
        bool resend = false, forward = true;
        const struct ethhdr *eth;
 
@@ -2000,7 +2121,11 @@ check_len_update:
                hdr = (struct ieee80211_hdr *)(skb->data + msdu_offset);
                rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx);
                if (rwnx_vif) {
+#ifdef CONFIG_GKI
                        rwnx_cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC);
+#else
+            cfg80211_rx_spurious_frame(rwnx_vif->ndev, hdr->addr2, GFP_ATOMIC);
+#endif
                }
                goto end;
        }
@@ -2063,8 +2188,15 @@ check_len_update:
                                memcpy(ether_type, &skb->data[hdr_len + 6], 2);
                                break;
                        }
+            if(is_amsdu)
+                hw_rxhdr->flags_is_amsdu = 1;
+            else
+               hw_rxhdr->flags_is_amsdu = 0;
 
                        if (is_amsdu) {
+                               #if 1
+                skb_pull(skb, pull_len-8);
+                               #else
                                skb_pull(skb, pull_len-8);
                                /* |amsdu sub1 | amsdu sub2 | ... */
                                len_alligned = 0;
@@ -2103,6 +2235,7 @@ check_len_update:
                                }
                                dev_kfree_skb(skb);
                                return 0;
+                               #endif
                        }
 
                        if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA)
@@ -2241,7 +2374,7 @@ check_len_update:
                                }
                        }
 
-                       if (!is_frag) {
+                       if (!is_frag && !is_amsdu) {
                                skb_pull(skb, pull_len);
                                skb_push(skb, 14);
                                memcpy(skb->data, ra, MAC_ADDR_LEN);
@@ -2278,8 +2411,13 @@ check_len_update:
                                }
 
                                if (hw_rxhdr->flags_is_4addr && !rwnx_vif->use_4addr) {
+#ifdef CONFIG_GKI
                                        rwnx_cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
                                                                                                           sta->mac_addr, GFP_ATOMIC);
+#else
+                    cfg80211_rx_unexpected_4addr_frame(rwnx_vif->ndev,
+                                                       sta->mac_addr, GFP_ATOMIC);
+#endif
                                }
                        }
 
@@ -2291,13 +2429,13 @@ check_len_update:
 
                        if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) {
                                if (is_qos && hw_rxhdr->flags_need_reord)
-                                       reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1);
+                                       reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1, hw_rxhdr->flags_is_amsdu);
                                else if (is_qos  && !hw_rxhdr->flags_need_reord) {
                                         reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid);
-                                       if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr))
+                                       if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr) && !hw_rxhdr->flags_is_amsdu)
                                                dev_kfree_skb(skb);
                                } else {
-                                       if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr))
+                                       if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr) && !hw_rxhdr->flags_is_amsdu)
                                                dev_kfree_skb(skb);
                                }
                        } else if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
@@ -2327,7 +2465,7 @@ check_len_update:
 
                                if (forward) {
                                        if (is_qos && hw_rxhdr->flags_need_reord)
-                                               reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1);
+                                               reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1, hw_rxhdr->flags_is_amsdu);
                                        else if (is_qos  && !hw_rxhdr->flags_need_reord) {
                                                reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid);
                                                rwnx_rx_data_skb_forward(rwnx_hw, rwnx_vif, skb, hw_rxhdr);
@@ -2335,7 +2473,7 @@ check_len_update:
                                                rwnx_rx_data_skb_forward(rwnx_hw, rwnx_vif, skb, hw_rxhdr);
                                } else if(resend) {
                                        if (is_qos && hw_rxhdr->flags_need_reord)
-                                               reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 0);
+                                               reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 0, hw_rxhdr->flags_is_amsdu);
                                        else if (is_qos  && !hw_rxhdr->flags_need_reord) {
                                                reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid);
                                                dev_kfree_skb(skb);
index a068083afc8a4fe3e365523f3d93a2f1f3f2e51d..36635350314bdb0685d547e6d89b75c1eaef82a1 100644 (file)
@@ -364,6 +364,8 @@ void reord_timeout_handler (struct timer_list *t);
 #endif
 
 #endif
+void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx,
+                                        struct sk_buff_head *list);
 
 #ifdef CONFIG_HE_FOR_OLD_KERNEL
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 197)
index 90cfdfd41cb186a1dbf776193e9de338bcab5b91..34196edac50894c0a1da4c28214effe85530546e 100644 (file)
@@ -320,8 +320,11 @@ rwnx_tdls_add_oper_classes(struct rwnx_vif *rwnx_vif, struct sk_buff *skb)
        chan_def.width = rwnx_vif->sta.ap->width;
        chan_def.center_freq1 = rwnx_vif->sta.ap->center_freq1;
        chan_def.center_freq2 = rwnx_vif->sta.ap->center_freq2;
-
+#ifdef CONFIG_GKI
        if (!rwnx_ieee80211_chandef_to_operating_class(&chan_def, &op_class))
+#else
+    if (!ieee80211_chandef_to_operating_class(&chan_def, &op_class))
+#endif
                return;
 
        pos = skb_put(skb, 4);
index 096d7ffe402298a375b0b6291fc3ae35d712d1a7..7be91e061cf3be300e161ca87c90160baa7b2b00 100644 (file)
@@ -1195,6 +1195,175 @@ int aic_br_client_tx(struct rwnx_vif *vif, struct sk_buff **pskb)
 #endif /* CONFIG_BR_SUPPORT */
 
 
+#ifdef CONFIG_FILTER_TCP_ACK
+/* return:
+ *      0, msg buf freed by the real driver
+ *      others, skb need free by the caller,remember not use msg->skb!
+ */
+
+int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg)
+{
+       struct rwnx_vif *rwnx_vif = msg->rwnx_vif;
+       struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw;
+       struct rwnx_txhdr *txhdr;
+       struct rwnx_sw_txhdr *sw_txhdr;
+       struct txdesc_api *desc;
+       struct rwnx_sta *sta;
+       struct rwnx_txq *txq;
+       int headroom;
+       //int max_headroom;
+       int hdr_pads;
+
+       u16 frame_len;
+       u16 frame_oft;
+       u8 tid;
+       struct sk_buff *skb=msg->skb;
+       struct ethhdr eth_t;
+
+       move_tcpack_msg(rwnx_hw,msg);
+       kfree(msg);
+
+       memcpy(&eth_t, skb->data, sizeof(struct ethhdr));
+
+       /* Get the STA id and TID information */
+       sta = rwnx_get_tx_priv(rwnx_vif, skb, &tid);
+       if (!sta)
+               goto free;
+
+       txq = rwnx_txq_sta_get(sta, tid, rwnx_hw);
+       if (txq->idx == TXQ_INACTIVE)
+               goto free;
+
+#ifdef CONFIG_RWNX_AMSDUS_TX
+       if (rwnx_amsdu_add_subframe(rwnx_hw, skb, sta, txq))
+               return NETDEV_TX_OK;
+#endif
+
+#ifdef CONFIG_BR_SUPPORT
+                if (1) {//(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) {
+                        void *br_port = NULL;
+
+       #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
+                        br_port = rwnx_vif->ndev->br_port;
+       #else
+                        rcu_read_lock();
+                        br_port = rcu_dereference(rwnx_vif->ndev->rx_handler_data);
+                        rcu_read_unlock();
+       #endif
+
+                        if (br_port) {
+                                s32 res = aic_br_client_tx(rwnx_vif, &skb);
+                                if (res == -1) {
+                                        goto free;
+                                }
+                        }
+                }
+#endif /* CONFIG_BR_SUPPORT */
+
+
+       /* Retrieve the pointer to the Ethernet data */
+       // eth = (struct ethhdr *)skb->data;
+
+       skb_pull(skb, 14);
+       //hdr_pads      = RWNX_SWTXHDR_ALIGN_PADS((long)eth);
+       hdr_pads  = RWNX_SWTXHDR_ALIGN_PADS((long)skb->data);
+       headroom  = sizeof(struct rwnx_txhdr) + hdr_pads;
+
+       skb_push(skb, headroom);
+
+       txhdr = (struct rwnx_txhdr *)skb->data;
+       sw_txhdr = kmem_cache_alloc(rwnx_hw->sw_txhdr_cache, GFP_ATOMIC);
+       if (unlikely(sw_txhdr == NULL))
+               goto free;
+       txhdr->sw_hdr = sw_txhdr;
+       desc = &sw_txhdr->desc;
+
+       frame_len = (u16)skb->len - headroom;// - sizeof(*eth);
+
+       sw_txhdr->txq           = txq;
+       sw_txhdr->frame_len = frame_len;
+       sw_txhdr->rwnx_sta      = sta;
+       sw_txhdr->rwnx_vif      = rwnx_vif;
+       sw_txhdr->skb           = skb;
+       sw_txhdr->headroom      = headroom;
+       sw_txhdr->map_len       = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
+
+#ifdef CONFIG_RWNX_AMSDUS_TX
+       sw_txhdr->amsdu.len = 0;
+       sw_txhdr->amsdu.nb = 0;
+#endif
+       // Fill-in the descriptor
+       memcpy(&desc->host.eth_dest_addr, eth_t.h_dest, ETH_ALEN);
+       memcpy(&desc->host.eth_src_addr, eth_t.h_source, ETH_ALEN);
+       desc->host.ethertype = eth_t.h_proto;
+       desc->host.staid = sta->sta_idx;
+       desc->host.tid = tid;
+       if (unlikely(rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP_VLAN))
+               desc->host.vif_idx = rwnx_vif->ap_vlan.master->vif_index;
+       else
+               desc->host.vif_idx = rwnx_vif->vif_index;
+
+       if (rwnx_vif->use_4addr && (sta->sta_idx < NX_REMOTE_STA_MAX))
+               desc->host.flags = TXU_CNTRL_USE_4ADDR;
+       else
+               desc->host.flags = 0;
+
+       if ((rwnx_vif->tdls_status == TDLS_LINK_ACTIVE) &&
+               rwnx_vif->sta.tdls_sta &&
+               (memcmp(desc->host.eth_dest_addr.array, rwnx_vif->sta.tdls_sta->mac_addr, ETH_ALEN) == 0)) {
+               desc->host.flags |= TXU_CNTRL_TDLS;
+               rwnx_vif->sta.tdls_sta->tdls.last_tid = desc->host.tid;
+               //rwnx_vif->sta.tdls_sta->tdls.last_sn = desc->host.sn;
+       }
+
+       if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_MESH_POINT) {
+               if (rwnx_vif->is_resending) {
+                       desc->host.flags |= TXU_CNTRL_MESH_FWD;
+               }
+       }
+
+#ifdef CONFIG_RWNX_SPLIT_TX_BUF
+       desc->host.packet_len[0] = frame_len;
+#else
+       desc->host.packet_len = frame_len;
+#endif
+
+       txhdr->hw_hdr.cfm.status.value = 0;
+
+       if (unlikely(rwnx_prep_tx(rwnx_hw, txhdr))) {
+               kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr);
+               skb_pull(skb, headroom);
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_BUSY;
+       }
+
+       /* Fill-in TX descriptor */
+       frame_oft = sizeof(struct rwnx_txhdr) - offsetof(struct rwnx_txhdr, hw_hdr)
+                               + hdr_pads;// + sizeof(*eth);
+#if 0
+#ifdef CONFIG_RWNX_SPLIT_TX_BUF
+       desc->host.packet_addr[0] = sw_txhdr->dma_addr + frame_oft;
+       desc->host.packet_cnt = 1;
+#else
+       desc->host.packet_addr = sw_txhdr->dma_addr + frame_oft;
+#endif
+#endif
+       desc->host.hostid = sw_txhdr->dma_addr;
+
+       spin_lock_bh(&rwnx_hw->tx_lock);
+       if (rwnx_txq_queue_skb(skb, txq, rwnx_hw, false))
+               rwnx_hwq_process(rwnx_hw, txq->hwq);
+       spin_unlock_bh(&rwnx_hw->tx_lock);
+
+       return 0;//NETDEV_TX_OK
+
+free:
+       dev_kfree_skb_any(skb);
+
+       return 0;//NETDEV_TX_OK
+}
+#endif
+
 /**
  * netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb,
  *                               struct net_device *dev);
@@ -1225,13 +1394,14 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev)
        u8 tid;
 
        struct ethhdr eth_t;
+#ifdef CONFIG_FILTER_TCP_ACK
+       struct msg_buf *msgbuf;
+#endif
 
 #ifdef CONFIG_ONE_TXQ
     skb->queue_mapping = rwnx_select_txq(rwnx_vif, skb);
 #endif
 
-       memcpy(&eth_t, skb->data, sizeof(struct ethhdr));
-
        sk_pacing_shift_update(skb->sk, rwnx_hw->tcp_pacing_shift);
        max_headroom = sizeof(struct rwnx_txhdr);
 
@@ -1248,6 +1418,20 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev)
                skb = newskb;
        }
 
+#ifdef CONFIG_FILTER_TCP_ACK
+               msgbuf=intf_tcp_alloc_msg(msgbuf);
+               msgbuf->rwnx_vif=rwnx_vif;
+               msgbuf->skb=skb;
+               if(filter_send_tcp_ack(rwnx_hw,msgbuf,skb->data,cpu_to_le16(skb->len))){
+                       return NETDEV_TX_OK;
+               }else{
+                       move_tcpack_msg(rwnx_hw,msgbuf);
+                       kfree(msgbuf);
+               }
+#endif
+
+       memcpy(&eth_t, skb->data, sizeof(struct ethhdr));
+
        /* Get the STA id and TID information */
        sta = rwnx_get_tx_priv(rwnx_vif, skb, &tid);
        if (!sta)
@@ -1493,7 +1677,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
                robust = ieee80211_is_robust_mgmt_frame((void *)skb->data);
 #endif
 
-       #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+       #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
        /* Update CSA counter if present */
        if (unlikely(params->n_csa_offsets) &&
                vif->wdev.iftype == NL80211_IFTYPE_AP &&
index a0fd7a0f317369c5d7f4aeb625346c63ca0742c7..a776e31e9a0908ee58b364bbf4f82dcdfe61fb02 100644 (file)
@@ -836,7 +836,11 @@ int rwnx_txq_queue_skb(struct sk_buff *skb, struct rwnx_txq *txq,
                skb_queue_tail(&txq->sk_list, skb);
        } else {
                if (txq->last_retry_skb)
+#ifdef CONFIG_GKI
                        rwnx_skb_append(txq->last_retry_skb, skb, &txq->sk_list);
+#else
+            skb_append(txq->last_retry_skb, skb, &txq->sk_list);
+#endif
                else
                        skb_queue_head(&txq->sk_list, skb);
 
@@ -1240,6 +1244,8 @@ void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq)
                BUG_ON(!(txq->status & RWNX_TXQ_IN_HWQ_LIST));
                if(txq->idx == TXQ_INACTIVE){
                        printk("%s txq->idx == TXQ_INACTIVE \r\n", __func__);
+            rwnx_txq_del_from_hw_list(txq);
+            rwnx_txq_flush(rwnx_hw, txq);  
                        continue;
                }
                BUG_ON(txq->idx == TXQ_INACTIVE);
index 21e907ccf902ff05d96e36309e238f853501b202..72e3c850b48e681026335fc16384b0568b9488b4 100644 (file)
@@ -129,7 +129,7 @@ int rwnx_v7_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_plat)
        pci_read_config_word(pci_dev, PCI_COMMAND, &pci_cmd);
        pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
        pci_write_config_word(pci_dev, PCI_COMMAND, pci_cmd);
-       pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2);
+       //pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2);
 
        ret = pci_enable_device(pci_dev);
        if (ret) {
@@ -139,12 +139,13 @@ int rwnx_v7_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_plat)
 
        pci_set_master(pci_dev);
 
+#if 0
        ret = pci_request_regions(pci_dev, KBUILD_MODNAME);
        if (ret) {
                dev_err(&(pci_dev->dev), "pci_request_regions failed\n");
                goto out_request;
        }
-
+#endif
        #ifdef CONFIG_PCI
        if (pci_enable_msi(pci_dev)) {
                dev_err(&(pci_dev->dev), "pci_enable_msi failed\n");
@@ -183,7 +184,7 @@ out_bar0:
 out_msi:
 #endif
        pci_release_regions(pci_dev);
-out_request:
+//out_request:
 #ifdef CONFIG_PCI
        pci_clear_master(pci_dev);
 #endif
index 6983ac8d5de5fcac58617df9eb0a4c3085627cbd..e2d038e8802eed7b61937755996c731b5583ff32 100644 (file)
@@ -1,4 +1,4 @@
 #define RWNX_VERS_REV "241c091M (master)"
 #define RWNX_VERS_MOD "6.4.3.0"
 #define RWNX_VERS_BANNER "rwnx v6.4.3.0 - - 241c091M (master)"
-#define RELEASE_DATE "2023_0904_1725"
+#define RELEASE_DATE "2023_1212_15dcf017"
index 4f9b7ca23fd829518da280917cc8eb1930a514e8..69bcf3f5d7842501ce22d628eeb9e1a32de1ddc8 100644 (file)
@@ -27,19 +27,23 @@ void rwnx_wakeup_deinit(struct wakeup_source *ws)
 
 struct wakeup_source *rwnx_wakeup_register(struct device *dev, const char *name)
 {
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
        return wakeup_source_register(dev, name);
 #else
-#ifdef CONFIG_PLATFORM_ROCKCHIP
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
+
+#if defined(CONFIG_PLATFORM_ROCKCHIP2) || defined(CONFIG_PLATFORM_ROCKCHIP)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
     return wakeup_source_register(dev, name);
 #else
     return wakeup_source_register(name);
 #endif
+
 #else
        return wakeup_source_register(name);
-#endif//CONFIG_PLATFORM_ROCKCHIP
-#endif
+#endif//#if defined(CONFIG_PLATFORM_ROCKCHIP2) || defined(CONFIG_PLATFORM_ROCKCHIP)
+
+#endif//LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
 }
 
 void rwnx_wakeup_unregister(struct wakeup_source *ws)