/****************************************************************************** * * Copyright(c) 2019 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * *****************************************************************************/ #include "halbb_precomp.h" bool halbb_chk_bb_rf_pkg_set_valid(struct bb_info *bb) { struct rtw_hal_com_t *hal_i = bb->hal_com; u8 bb_ver = 0; /*hal_i->bb_para_pkg_ver;*/ /*TBD*/ u8 rf_ver = 0; /*hal_i->rf_para_pkg_ver;*/ /*TBD*/ bool valid = true; switch (bb->ic_type) { #ifdef BB_8852A_CAV_SUPPORT case BB_RTL8852AA: valid = halbb_chk_pkg_valid_8852a(bb, bb_ver, rf_ver); break; #endif #ifdef BB_8852A_2_SUPPORT case BB_RTL8852A: valid = halbb_chk_pkg_valid_8852a_2(bb, bb_ver, rf_ver); break; #endif #ifdef BB_8852B_SUPPORT case BB_RTL8852B: valid = halbb_chk_pkg_valid_8852b(bb, bb_ver, rf_ver); break; #endif #ifdef BB_8852C_SUPPORT case BB_RTL8852C: valid = halbb_chk_pkg_valid_8852c(bb, bb_ver, rf_ver); break; #endif #ifdef BB_8834A_SUPPORT case BB_RTL8834A: valid = halbb_chk_pkg_valid_8834a(bb, bb_ver, rf_ver); break; #endif default: break; } return valid; } void halbb_ic_hw_setting_init(struct bb_info *bb) { #ifdef HALBB_TDMA_CR_SUPPORT halbb_tdma_cr_sel_init(bb); #endif switch (bb->ic_type) { #ifdef BB_8852A_CAV_SUPPORT case BB_RTL8852AA: halbb_ic_hw_setting_init_8852a(bb); break; #endif #ifdef BB_8852A_2_SUPPORT case BB_RTL8852A: halbb_ic_hw_setting_init_8852a_2(bb); #ifdef HALBB_DYN_CSI_RSP_SUPPORT halbb_dcr_init(bb); #endif #ifdef BB_DYN_CFO_TRK_LOP halbb_dyn_cfo_trk_loop_init(bb); #endif break; #endif #ifdef BB_8852B_SUPPORT case BB_RTL8852B: halbb_ic_hw_setting_init_8852b(bb); #ifdef HALBB_DYN_CSI_RSP_SUPPORT halbb_dcr_init(bb); #endif break; #endif #ifdef BB_8852C_SUPPORT case BB_RTL8852C: halbb_ic_hw_setting_init_8852c(bb); #ifdef HALBB_DYN_CSI_RSP_SUPPORT halbb_dcr_init(bb); #endif break; #endif default: break; } } void halbb_get_efuse_init(struct bb_info *bb) { switch (bb->ic_type) { #ifdef BB_8852A_2_SUPPORT case BB_RTL8852A: halbb_get_normal_efuse_init_8852a_2(bb); halbb_get_hidden_efuse_init_8852a_2(bb); break; #endif #ifdef BB_8852B_SUPPORT case BB_RTL8852B: halbb_get_normal_efuse_init_8852b(bb); halbb_get_hide_efuse_init_8852b(bb); break; #endif #ifdef BB_8852C_SUPPORT case BB_RTL8852C: halbb_get_normal_efuse_init_8852c(bb); halbb_get_hidden_efuse_init_8852c(bb); break; #endif default: break; } } void halbb_cmn_info_self_init(struct bb_info *bb) { struct rtw_hal_com_t *hal_i = bb->hal_com; /*[IC type]*/ if (hal_i->chip_id == CHIP_WIFI6_8852A) { if (hal_i->cv == CAV) bb->ic_type = BB_RTL8852AA; else bb->ic_type = BB_RTL8852A; } else if (hal_i->chip_id == CHIP_WIFI6_8852B) { bb->ic_type = BB_RTL8852B; #ifdef BB_8852C_SUPPORT } else if (hal_i->chip_id == CHIP_WIFI6_8852C) { bb->ic_type = BB_RTL8852C; #endif } else if (hal_i->chip_id == CHIP_WIFI6_8834A) { bb->ic_type = BB_RTL8834A; #ifdef BB_8192XB_SUPPORT } else if (hal_i->chip_id == CHIP_WIFI6_8192XB) { bb->ic_type = BB_RTL8192XB; #endif } /*[CR type]*/ if (bb->ic_type == BB_RTL8852AA) bb->cr_type = BB_52AA; else if (bb->ic_type & BB_IC_AX_AP) bb->cr_type = BB_AP; else if (bb->ic_type & BB_IC_AX_AP2) bb->cr_type = BB_AP2; else if (bb->ic_type & BB_IC_AX_CLIENT) bb->cr_type = BB_CLIENT; /*[RF path number]*/ if (bb->ic_type & BB_IC_1SS) bb->num_rf_path = 1; else if (bb->ic_type & BB_IC_2SS) bb->num_rf_path = 2; else if (bb->ic_type & BB_IC_3SS) bb->num_rf_path = 3; else if (bb->ic_type & BB_IC_4SS) bb->num_rf_path = 4; else bb->num_rf_path = 1; BB_DBG(bb, DBG_INIT, "cr_type=%d, num_rf_path=%d\n", bb->cr_type, bb->num_rf_path); BB_DBG(bb, DBG_INIT, "num_rf_path=%d, rate_num{Legcy, HT, VHT, HE}={%d,%d,%d,%d}\n", bb->num_rf_path, LEGACY_RATE_NUM, HT_RATE_NUM, VHT_RATE_NUM, HE_RATE_NUM); bb->manual_support_ability = 0xffffffff; bb->bb_dm_init_ready = false; bb->bb_sys_up_time = 0; bb->bb_watchdog_en = true; bb->bb_ic_api_en = true; /*[Drv Dbg Info]*/ bb->cmn_dbg_msg_period = 2; bb->cmn_dbg_msg_cnt = 0; /*[Dummy]*/ bb->bool_dummy = false; bb->u8_dummy = 0xff; bb->u16_dummy = 0xffff; bb->u32_dummy = 0xffffffff; /*@=== [HALBB Structure] ============================================*/ bb->bb_link_i.is_linked = false; bb->bb_link_i.is_linked_pre = false; bb->bb_link_i.tp_active_th = 5; bb->bb_path_i.rx_path_en = bb->num_rf_path; bb->bb_path_i.tx_path_en = bb->num_rf_path; bb->adv_bb_dm_en = true; bb->bb_cmn_info_init_ready = true; bb->bb_watchdog_period = 2; /*sec*/ bb->bb_cmn_hooker->bb_dm_number = sizeof(halbb_func_i) / sizeof(struct halbb_func_info); halbb_edcca_dev_hw_cap(bb); halbb_cmn_info_self_reset(bb); } u64 halbb_supportability_default(struct bb_info *bb) { u64 support_ability = 0; switch (bb->ic_type) { #ifdef BB_8852A_CAV_SUPPORT case BB_RTL8852AA: support_ability |= /*BB_RA |*/ BB_FA_CNT | /*BB_DFS |*/ BB_EDCCA | /*BB_ENVMNTR |*/ BB_CFO_TRK | /*BB_DIG |*/ 0; break; #endif #ifdef BB_8852A_2_SUPPORT case BB_RTL8852A: support_ability |= /*BB_RA |*/ BB_FA_CNT | BB_DFS | BB_EDCCA | BB_ENVMNTR | BB_CFO_TRK | BB_DIG | BB_UL_TB_CTRL | /*BB_ANT_DIV |*/ 0; break; #endif #ifdef BB_8852B_SUPPORT case BB_RTL8852B: support_ability |= BB_RA | BB_FA_CNT | BB_DFS | BB_EDCCA | BB_CFO_TRK | BB_ENVMNTR | BB_DIG | BB_UL_TB_CTRL | 0; break; #endif #ifdef BB_8852C_SUPPORT case BB_RTL8852C: support_ability |= /*BB_RA |*/ BB_FA_CNT | BB_DFS | BB_EDCCA | BB_ENVMNTR | BB_CFO_TRK | BB_DIG | BB_UL_TB_CTRL | /*BB_ANT_DIV |*/ 0; break; #endif default: BB_WARNING("[%s]\n", __func__); break; } return support_ability; } void halbb_supportability_init(struct bb_info *bb) { u64 support_ability; #if 0 if (bb->phl_com->bb_ability_manual != 0xffffffff) { support_ability = bb->phl_com->bb_ability_manual; } else #endif if(phl_is_mp_mode(bb->phl_com)) { support_ability = 0; } else { support_ability = halbb_supportability_default(bb); } bb->support_ability = support_ability; BB_DBG(bb, DBG_INIT, "IC=0x%x, mp=%d, Supportability=0x%llx\n", bb->ic_type, bb->phl_com->drv_mode, bb->support_ability); } void halbb_hw_init(struct bb_info *bb) { BB_DBG(bb, DBG_INIT, "[%s] phy_idx=%d\n", __func__, bb->bb_phy_idx); halbb_cmn_info_self_init(bb); if (!halbb_chk_bb_rf_pkg_set_valid(bb)) { BB_WARNING("[%s] Init fail\n", __func__); return; } } void halbb_dm_deinit(struct rtw_phl_com_t *phl_com, void *bb_phy_0) { struct bb_info *bb = (struct bb_info *)bb_phy_0; if (!bb->bb_dm_init_ready) return; halbb_timer_ctrl(bb, BB_CANCEL_TIMER); #ifdef HALBB_LA_MODE_SUPPORT halbb_la_deinit(bb); #endif #ifdef HALBB_PSD_SUPPORT halbb_psd_deinit(bb); #endif #ifdef HALBB_CH_INFO_SUPPORT halbb_ch_info_deinit(bb); #endif #ifdef HALBB_DIG_SUPPORT halbb_dig_deinit(bb); #endif #ifdef HALBB_ANT_DIV_SUPPORT halbb_antdiv_deinit(bb); #endif #ifdef BB_8852A_2_SUPPORT #endif #ifdef HALBB_CFO_TRK_SUPPORT halbb_cfo_deinit(bb); #endif bb->bb_dm_init_ready = false; } enum rtw_hal_status halbb_dm_init(struct bb_info *bb, enum phl_phy_idx phy_idx) { enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS; if (!bb) { BB_WARNING("[%s] *bb = NULL", __func__); return RTW_HAL_STATUS_FAILURE; } if (!bb->bb_cmn_info_init_ready) { BB_WARNING("bb_cmn_info_init_ready = false"); return RTW_HAL_STATUS_FAILURE; } #ifdef HALBB_DBCC_SUPPORT #ifdef HALBB_DBCC_DVLP_FLAG if (phy_idx == HW_PHY_1) return hal_status; #endif bb = halbb_get_curr_bb_pointer(bb, phy_idx); BB_DBG(bb, DBG_INIT, "[%s] phy_idx=%d\n", __func__, bb->bb_phy_idx); #endif halbb_ic_hw_setting_init(bb); halbb_gpio_setting_init(bb); halbb_get_efuse_init(bb); halbb_supportability_init(bb); halbb_physts_parsing_init(bb); halbb_cmn_rpt_init(bb); halbb_dbg_setting_init(bb); #ifdef HALBB_PWR_CTRL_SUPPORT halbb_macid_ctrl_init(bb); #endif #ifdef HALBB_STATISTICS_SUPPORT halbb_statistics_init(bb); #endif #ifdef HALBB_LA_MODE_SUPPORT halbb_la_init(bb); #endif #ifdef HALBB_PSD_SUPPORT halbb_psd_init(bb); #endif #ifdef HALBB_EDCCA_SUPPORT halbb_edcca_init(bb); #endif #ifdef HALBB_DFS_SUPPORT halbb_dfs_init(bb); #endif #ifdef HALBB_DIG_SUPPORT halbb_dig_init(bb); #endif #ifdef HALBB_CFO_TRK_SUPPORT halbb_cfo_trk_init(bb); #endif #ifdef HALBB_UL_TB_CTRL_SUPPORT halbb_ul_tb_ctrl_init(bb); #endif #ifdef HALBB_RA_SUPPORT halbb_ra_init(bb); #endif #ifdef HALBB_ENV_MNTR_SUPPORT halbb_env_mntr_init(bb); #endif #ifdef HALBB_PWR_CTRL_SUPPORT halbb_pwr_ctrl_init(bb); #endif #ifdef HALBB_RUA_SUPPORT halbb_rua_tbl_init(bb); #endif #ifdef HALBB_ANT_DIV_SUPPORT halbb_antdiv_init(bb); #endif #ifdef HALBB_CH_INFO_SUPPORT halbb_ch_info_init(bb); #endif halbb_reset_adc(bb); #ifdef HALBB_DIG_MCC_SUPPORT Halbb_init_mccdm(bb); #endif bb->bb_dm_init_ready = true; BB_DBG(bb, DBG_INIT, "bb_init_ready = %d\n", bb->bb_dm_init_ready); return hal_status; } void halbb_timer_ctrl(struct bb_info *bb, enum bb_timer_cfg_t timer_state) { BB_DBG(bb, DBG_INIT, "[%s] timer_state = %d\n", __func__, timer_state); /*BB-0 & BB-1 timer*/ #ifdef HALBB_ANT_DIV_SUPPORT halbb_cfg_timers(bb, timer_state, &bb->bb_ant_div_i.antdiv_timer_i); #endif #ifdef HALBB_CFO_TRK_SUPPORT halbb_cfg_timers(bb, timer_state, &bb->bb_cfo_trk_i.cfo_timer_i); #endif #ifdef HALBB_TDMA_CR_SUPPORT halbb_cfg_timers(bb, timer_state, &bb->bb_dbg_i.tdma_cr_timer_i); #endif #ifdef HALBB_DIG_TDMA_SUPPORT halbb_cfg_timers(bb, timer_state, &bb->bb_dig_i.dig_timer_i); #endif if (!bb->bb_cmn_hooker) return; /*BB Common Timer*/ #ifdef HALBB_LA_MODE_SUPPORT halbb_cfg_timers(bb, timer_state, &bb->bb_cmn_hooker->bb_la_mode_i.la_timer_i); #endif } void halbb_timer_init(struct bb_info *bb) { BB_DBG(bb, DBG_INIT, "[%s]\n", __func__); #ifdef HALBB_ANT_DIV_SUPPORT halbb_antdiv_timer_init(bb); #endif #ifdef HALBB_CFO_TRK_SUPPORT halbb_cfo_acc_timer_init(bb); #endif #ifdef HALBB_TDMA_CR_SUPPORT halbb_tdma_cr_timer_init(bb); #endif #ifdef HALBB_DIG_TDMA_SUPPORT halbb_dig_timer_init(bb); #endif #ifdef HALBB_LA_MODE_SUPPORT halbb_la_timer_init(bb); #endif } void halbb_cr_cfg_init(struct bb_info *bb) { halbb_cr_cfg_dbg_init(bb); halbb_cr_cfg_physts_init(bb); #ifdef HALBB_STATISTICS_SUPPORT halbb_cr_cfg_stat_init(bb); #endif #ifdef HALBB_PSD_SUPPORT halbb_cr_cfg_psd_init(bb); #endif #ifdef HALBB_DIG_SUPPORT halbb_cr_cfg_dig_init(bb); #endif #ifdef HALBB_ENV_MNTR_SUPPORT halbb_cr_cfg_env_mntr_init(bb); #endif #ifdef HALBB_EDCCA_SUPPORT halbb_cr_cfg_edcca_init(bb); #endif #ifdef HALBB_DFS_SUPPORT halbb_cr_cfg_dfs_init(bb); #endif #ifdef HALBB_LA_MODE_SUPPORT halbb_cr_cfg_la_init(bb); #endif #ifdef HALBB_ANT_DIV_SUPPORT halbb_cr_cfg_antdiv_init(bb); #endif #ifdef HALBB_PMAC_TX_SUPPORT halbb_cr_cfg_plcp_init(bb); #endif halbb_cr_cfg_mp_init(bb); #ifdef HALBB_CH_INFO_SUPPORT halbb_cr_cfg_ch_info_init(bb); #endif #ifdef HALBB_CFO_TRK_SUPPORT halbb_cr_cfg_cfo_trk_init(bb); #endif #ifdef HALBB_UL_TB_CTRL_SUPPORT halbb_cr_cfg_ul_tb_init(bb); #endif } void halbb_buffer_deinit(struct rtw_phl_com_t *phl_com, struct rtw_hal_com_t *hal_com, void *bb_phy_0) { struct bb_info *bb = (struct bb_info *)bb_phy_0; BB_DBG(bb, DBG_INIT, "deinit phy-%d", bb->bb_phy_idx); halbb_timer_ctrl(bb, BB_CANCEL_TIMER); halbb_timer_ctrl(bb, BB_RELEASE_TIMER); /*Deinit phy-cmn*/ if (bb->bb_cmn_hooker) { BB_DBG(bb, DBG_INIT, "deinit bb_cmn_hooker"); hal_mem_free(hal_com, bb->bb_cmn_hooker, sizeof(struct bb_cmn_info)); } #ifdef HALBB_DBCC_SUPPORT /*Deinit phy-1*/ if (bb->bb_phy_hooker) { BB_DBG(bb, DBG_INIT, "deinit phy-%d", bb->bb_phy_hooker->bb_phy_idx); //halbb_timer_ctrl(bb->bb_phy_hooker, BB_CANCEL_TIMER); //halbb_timer_ctrl(bb->bb_phy_hooker, BB_RELEASE_TIMER); hal_mem_free(hal_com, bb->bb_phy_hooker, sizeof(struct bb_info)); } #endif /*Deinit phy-0*/ if (bb) { hal_mem_free(hal_com, bb, sizeof(struct bb_info)); } } u32 halbb_buffer_init(struct rtw_phl_com_t *phl_com, struct rtw_hal_com_t *hal_com, void **bb_out_addr) { enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS; struct bb_info *bb_0 = NULL; struct bb_cmn_info *bb_cmn = NULL; bb_0 = hal_mem_alloc(hal_com, sizeof(struct bb_info)); if (!bb_0) { BB_WARNING("*bb = NULL\n"); return RTW_HAL_STATUS_BB_INIT_FAILURE; } *bb_out_addr = bb_0; bb_0->phl_com = phl_com;/*shared memory for all components*/ bb_0->hal_com = hal_com;/*shared memory for phl and hal*/ bb_0->bb_phy_idx = HW_PHY_0; bb_cmn = hal_mem_alloc(hal_com, sizeof(struct bb_cmn_info)); if (!bb_cmn) { BB_WARNING("*bb_cmn = NULL\n"); return RTW_HAL_STATUS_BB_INIT_FAILURE; } bb_0->bb_cmn_hooker = bb_cmn; halbb_dbg_comp_init(bb_0); halbb_hw_init(bb_0); halbb_timer_init(bb_0); halbb_cr_cfg_init(bb_0); #ifdef HALBB_DBCC_SUPPORT BB_DBG(bb_0, DBG_INIT, "dbcc_support = %d\n", phl_com->dev_cap.dbcc_sup); hal_status = halbb_buffer_init_phy1(bb_0); #else BB_DBG(bb_0, DBG_INIT, "DBCC macro not enabled\n"); #endif BB_DBG(bb_0, DBG_INIT, "[%s]\n", __func__); BB_DBG(bb_0, DBG_INIT, " %-35s: %s\n", "Code Base:", HLABB_CODE_BASE); BB_DBG(bb_0, DBG_INIT, " %-35s: %s\n", "Code Release Date", HALBB_RELEASE_DATE); #ifdef BB_8852A_CAV_SUPPORT BB_DBG(bb_0, DBG_INIT, " %-35s: %d\n", "[CAV]52A BB_REG Ver", BB_REG_RELEASE_VERSION_8852A); BB_DBG(bb_0, DBG_INIT, " %-35s: %d\n", "[CAV]52A BB_REG Release Date", BB_REG_RELEASE_DATE_8852A); #endif #ifdef BB_8852A_2_SUPPORT BB_DBG(bb_0, DBG_INIT, " %-35s: %d\n", "[>CBV]52A BB_REG Ver", BB_REG_RELEASE_VERSION_8852A_2); BB_DBG(bb_0, DBG_INIT, " %-35s: %d\n", "[>CBV]52A BB_REG Release Date", BB_REG_RELEASE_DATE_8852A_2); #endif return (u32)hal_status; }