#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" int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr, char *filename); int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw, u32** buffer, const char *filename); void rwnx_plat_userconfig_parsing2(char *buffer, int size); void rwnx_release_firmware_common(u32** buffer); u32 wifi_txgain_table_24g_8800dcdw[32] = { 0xA4B22189, //index 0 0x00007825, 0xA4B2214B, //index 1 0x00007825, 0xA4B2214F, //index 2 0x00007825, 0xA4B221D5, //index 3 0x00007825, 0xA4B221DC, //index 4 0x00007825, 0xA4B221E5, //index 5 0x00007825, 0xAC9221E5, //index 6 0x00006825, 0xAC9221EF, //index 7 0x00006825, 0xBC9221EE, //index 8 0x00006825, 0xBC9221FF, //index 9 0x00006825, 0xBC9221FF, //index 10 0x00004025, 0xB792203F, //index 11 0x00004026, 0xDC92203F, //index 12 0x00004025, 0xE692203F, //index 13 0x00004025, 0xFF92203F, //index 14 0x00004035, 0xFFFE203F, //index 15 0x00004832 }; u32 wifi_txgain_table_24g_1_8800dcdw[32] = { 0x096E2011, //index 0 0x00004001, 0x096E2015, //index 1 0x00004001, 0x096E201B, //index 2 0x00004001, 0x116E2018, //index 3 0x00004001, 0x116E201E, //index 4 0x00004001, 0x116E2023, //index 5 0x00004001, 0x196E2021, //index 6 0x00004001, 0x196E202B, //index 7 0x00004001, 0x216E202B, //index 8 0x00004001, 0x236E2027, //index 9 0x00004001, 0x236E2031, //index 10 0x00004001, 0x246E2039, //index 11 0x00004001, 0x26922039, //index 12 0x00004001, 0x2E92203F, //index 13 0x00004001, 0x3692203F, //index 14 0x00004001, 0x3FF2203F, //index 15 0x00004001, }; u32 wifi_txgain_table_24g_8800dcdw_h[32] = { 0xA55629C9, //index 0 0x00005825, 0xAE5629C9, //index 1 0x00005825, 0xAD5629CD, //index 2 0x00005825, 0xAD5629D1, //index 3 0x00005825, 0xAD5629D7, //index 4 0x00005825, 0xAD5629DE, //index 5 0x00005825, 0xAD5629E6, //index 6 0x00005825, 0xBD5629E6, //index 7 0x00005825, 0xBD5629F0, //index 8 0x00005825, 0xCD5629F0, //index 9 0x00005825, 0xE55629F0, //index 10 0x00005825, 0xE55629FF, //index 11 0x00005825, 0xE55629FF, //index 12 0x00002825, 0xE75629FF, //index 13 0x00002825, 0xFF5629FF, //index 14 0x00001825, 0xFF5628FF, //index 15 0x00001025, }; u32 wifi_txgain_table_24g_1_8800dcdw_h[32] = { 0x941A2048, //index 0 0x00001825, 0x961A2048, //index 1 0x00001825, 0x9D1A2048, //index 2 0x00001825, 0x9A1A204F, //index 3 0x00001825, 0x961A204F, //index 4 0x00001825, 0x9A1A2057, //index 5 0x00001825, 0x9C1A2057, //index 6 0x00001825, 0xA31A205B, //index 7 0x00001825, 0xAB1A205B, //index 8 0x00001825, 0xAD1A205B, //index 9 0x00001825, 0xA71A2064, //index 10 0x00001825, 0xAD1A2070, //index 11 0x00001825, 0xAD72207F, //index 12 0x00001825, 0xBCAE207F, //index 13 0x00001825, 0xBFB2207F, //index 14 0x00001825, 0xD73A207F, //index 15 0x00001825, }; u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = { 0x82f282d1,//index 0 0x9591a324, 0x80808419, 0x000000f0, 0x42f282d1,//index 1 0x95923524, 0x80808419, 0x000000f0, 0x22f282d1,//index 2 0x9592c724, 0x80808419, 0x000000f0, 0x02f282d1,//index 3 0x9591a324, 0x80808419, 0x000000f0, 0x06f282d1,//index 4 0x9591a324, 0x80808419, 0x000000f0, 0x0ef29ad1,//index 5 0x9591a324, 0x80808419, 0x000000f0, 0x0ef29ad3,//index 6 0x95923524, 0x80808419, 0x000000f0, 0x0ef29ad7,//index 7 0x9595a324, 0x80808419, 0x000000f0, 0x02f282d2,//index 8 0x95951124, 0x80808419, 0x000000f0, 0x02f282f4,//index 9 0x95951124, 0x80808419, 0x000000f0, 0x02f282e6,//index 10 0x9595a324, 0x80808419, 0x000000f0, 0x02f282e6,//index 11 0x9599a324, 0x80808419, 0x000000f0, 0x02f282e6,//index 12 0x959da324, 0x80808419, 0x000000f0, 0x02f282e6,//index 13 0x959f5924, 0x80808419, 0x000000f0, 0x06f282e6,//index 14 0x959f5924, 0x80808419, 0x000000f0, 0x0ef29ae6,//index 15 0x959f5924, //loft [35:34]=3 0x80808419, 0x000000f0 }; u32 wifi_rxgain_table_24g_40m_8800dcdw[64] = { 0x83428151,//index 0 0x9631a328, 0x80808419, 0x000000f0, 0x43428151,//index 1 0x96323528, 0x80808419, 0x000000f0, 0x23428151,//index 2 0x9632c728, 0x80808419, 0x000000f0, 0x03428151,//index 3 0x9631a328, 0x80808419, 0x000000f0, 0x07429951,//index 4 0x9631a328, 0x80808419, 0x000000f0, 0x0f42d151,//index 5 0x9631a328, 0x80808419, 0x000000f0, 0x0f42d153,//index 6 0x96323528, 0x80808419, 0x000000f0, 0x0f42d157,//index 7 0x9635a328, 0x80808419, 0x000000f0, 0x03428152,//index 8 0x96351128, 0x80808419, 0x000000f0, 0x03428174,//index 9 0x96351128, 0x80808419, 0x000000f0, 0x03428166,//index 10 0x9635a328, 0x80808419, 0x000000f0, 0x03428166,//index 11 0x9639a328, 0x80808419, 0x000000f0, 0x03428166,//index 12 0x963da328, 0x80808419, 0x000000f0, 0x03428166,//index 13 0x963f5928, 0x80808419, 0x000000f0, 0x07429966,//index 14 0x963f5928, 0x80808419, 0x000000f0, 0x0f42d166,//index 15 0x963f5928, 0x80808419, 0x000000f0 }; #ifdef CONFIG_DPD #define RAM_LMAC_FW_ADDR 0x00150000 extern int is_file_exist(char* name); extern rf_misc_ram_lite_t dpd_res; 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; 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; } if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 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; 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(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) { int ret = 0; uint32_t cfg_base = 0x10164; struct dbg_mem_read_cfm cfm; uint32_t misc_ram_addr; printk("%s\n", __func__); if (testmode == 1) { cfg_base = RAM_LMAC_FW_ADDR + 0x0164; } if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 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_2(rwnx_hw, misc_ram_addr, FW_DPDRESULT_NAME_8800DC); if (ret) { AICWFDBG(LOGINFO, "load calib bin fail: %d\n", ret); return ret; } return ret; } #endif #endif int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw) { int ret = 0; 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); 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); for (i = 0; i < (misc_ram_size / 4); i++) { ret = rwnx_send_dbg_mem_write_req(rwnx_hw, misc_ram_addr + i * 4, 0); if (ret) { AICWFDBG(LOGERROR, "rf misc ram[0x%x] wr fail: %d\n", misc_ram_addr + i * 4, ret); return ret; } } return ret; } int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm){ int ret = 0; if ((ret = rwnx_send_txpwr_lvl_req(rwnx_hw))) { return -1; } if ((ret = rwnx_send_txpwr_ofst_req(rwnx_hw))) { return -1; } if (testmode == 0) { if (IS_CHIP_ID_H()) { if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0, 1, (u8_l *)wifi_txgain_table_24g_8800dcdw_h, 128))) return -1; if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw_h, 128))) return -1; } else { if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0, 1, (u8_l *)wifi_txgain_table_24g_8800dcdw, 128))) return -1; if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw, 128))) return -1; } if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0, 0, (u8_l *)wifi_rxgain_table_24g_20m_8800dcdw, 256))) return -1; if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32, 0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256))) return -1; if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) { return -1; } } else if (testmode == 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); 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 #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 ; } int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw){ int size; u32 *dst=NULL; char *filename = FW_USERCONFIG_NAME_8800DC; AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); /* load file */ size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); if (size <= 0) { AICWFDBG(LOGERROR, "wrong size of firmware file\n"); dst = NULL; return 0; } /* Copy the file on the Embedded side */ AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); rwnx_plat_userconfig_parsing2((char *)dst, size); rwnx_release_firmware_common(&dst); AICWFDBG(LOGINFO, "userconfig download complete\n\n"); return 0; } int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){ int size; u32 *dst=NULL; char *filename = FW_USERCONFIG_NAME_8800DC; AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); /* load file */ size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); if (size <= 0) { AICWFDBG(LOGERROR, "wrong size of firmware file\n"); dst = NULL; return 0; } /* Copy the file on the Embedded side */ AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); rwnx_plat_userconfig_parsing2((char *)dst, size); rwnx_release_firmware_common(&dst); AICWFDBG(LOGINFO, "userconfig download complete\n\n"); return 0; }