/****************************************************************************** * * Copyright(c) 2007 - 2020 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. * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * * Contact Information: * wlanfae * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, * Hsinchu 300, Taiwan. * * Larry Finger * *****************************************************************************/ #include "halbb_precomp.h" void halbb_cfg_bb_rpl_ofst(struct bb_info *bb, enum bb_band_t band, u8 path, u32 addr, u32 data) { struct bb_gain_info *gain = &bb->bb_gain_i; u8 i = 0; u8 bw = (u8)(addr & 0xf0) >> 4; u8 rxsc_start = (u8)(addr & 0xf); u8 rxsc = 0; s8 ofst = 0; if (bw == (u8)CHANNEL_WIDTH_20) { gain->rpl_ofst_20[band][path] = (s8)data; BB_DBG(bb, DBG_INIT, "RPL[Band:%d][path=%d][%dM][rxsc=%d]=%d\n", band, path, (20 << bw), rxsc, gain->rpl_ofst_20[band][path]); } else if (bw == (u8)CHANNEL_WIDTH_40){ if (rxsc_start == BB_RXSC_START_IDX_FULL) { gain->rpl_ofst_40[band][path][0] = (s8)data; BB_DBG(bb, DBG_INIT, "RPL[Band:%d][path=%d][%dM][rxsc=%d]=%d\n", band, path, (20 << bw), rxsc, gain->rpl_ofst_40[band][path][0]); } else if (rxsc_start == BB_RXSC_START_IDX_20) { for (i = 0; i < 2; i++) { rxsc = BB_RXSC_START_IDX_20 + i; ofst = (s8)((data >> (8 * i)) & 0xff); gain->rpl_ofst_40[band][path][rxsc] = ofst; BB_DBG(bb, DBG_INIT, "RPL[Band:%d][path=%d][%dM][rxsc=%d]=%d\n", band, path, (20 << bw), rxsc, gain->rpl_ofst_40[band][path][rxsc]); } } } else if (bw == (u8)CHANNEL_WIDTH_80){ if (rxsc_start == BB_RXSC_START_IDX_FULL) { gain->rpl_ofst_80[band][path][0] = (s8)data; BB_DBG(bb, DBG_INIT, "RPL[Band:%d][path=%d][%dM][rxsc=%d]=%d\n", band, path, (20 << bw), rxsc, gain->rpl_ofst_80[band][path][0]); } else if (rxsc_start == BB_RXSC_START_IDX_20) { for (i = 0; i < 4; i++) { rxsc = BB_RXSC_START_IDX_20 + i; ofst = (s8)((data >> (8 * i)) & 0xff); gain->rpl_ofst_80[band][path][rxsc] = ofst; BB_DBG(bb, DBG_INIT, "RPL[Band:%d][path=%d][%dM][rxsc=%d]=%d\n", band, path, (20 << bw), rxsc, gain->rpl_ofst_80[band][path][rxsc]); } } else if (rxsc_start == BB_RXSC_START_IDX_40) { for (i = 0; i < 2; i++) { rxsc = BB_RXSC_START_IDX_40 + i; ofst = (s8)((data >> (8 * i)) & 0xff); gain->rpl_ofst_80[band][path][rxsc] = ofst; BB_DBG(bb, DBG_INIT, "RPL[Band:%d][path=%d][%dM][rxsc=%d]=%d\n", band, path, (20 << bw), rxsc, gain->rpl_ofst_80[band][path][rxsc]); } } } } bool halbb_init_cr_default(struct bb_info *bb, bool is_form_folder, u32 folder_len, u32 *folder_array, enum phl_phy_idx phy_idx) { bool result = true; if (!bb->bb_cmn_info_init_ready) { BB_WARNING("bb_cmn_info_init_ready = false"); return false; } if (is_form_folder) { if (!folder_array) { BB_WARNING("[%s] folder_array=NULL\n", __func__); return false; } if (folder_len == 0) { BB_WARNING("[%s] folder_len=0\n", __func__); return false; } } #ifdef HALBB_DBCC_SUPPORT if (phy_idx == HW_PHY_1 && !bb->hal_com->dbcc_en) { BB_WARNING("[%s]\n",__func__); if (!bb->bb_dbg_i.cr_dbg_mode_en) return false; } #endif BB_DBG(bb, DBG_INIT, "[%s] ic=%d\n", __func__, bb->hal_com->chip_id); switch (bb->ic_type) { case BB_RTL8852AA: #ifdef BB_8852A_CAV_SUPPORT result = halbb_cfg_bbcr_ax_8852a(bb, is_form_folder, folder_len, folder_array, phy_idx); #else BB_WARNING("[%s] NOT Support 8852AA\n", __func__); result = false; #endif break; #ifdef BB_8852A_2_SUPPORT case BB_RTL8852A: result = halbb_cfg_bbcr_ax_8852a_2(bb, is_form_folder, folder_len, folder_array, phy_idx); halbb_tpu_mac_cr_init(bb, phy_idx); break; #endif #ifdef BB_8852B_SUPPORT case BB_RTL8852B: result = halbb_cfg_bbcr_ax_8852b(bb, is_form_folder, folder_len, folder_array, phy_idx); halbb_tpu_mac_cr_init(bb, phy_idx); break; #endif #ifdef BB_8852C_SUPPORT case BB_RTL8852C: result = halbb_cfg_bbcr_ax_8852c(bb, is_form_folder, folder_len, folder_array, phy_idx); halbb_tpu_mac_cr_init(bb, phy_idx); break; #endif default: BB_WARNING("[%s] ic=%d\n", __func__, bb->hal_com->chip_id); break; } BB_DBG(bb, DBG_INIT, "BB_CR_init_success = %d\n", result); return result; } bool halbb_init_gain_table(struct bb_info *bb, bool is_form_folder, u32 folder_len, u32 *folder_array, enum phl_phy_idx phy_idx) { bool result = true; if (!bb->bb_cmn_info_init_ready) { BB_WARNING("bb_cmn_info_init_ready = false"); return false; } if (is_form_folder) { if (!folder_array) { BB_WARNING("[%s] folder_array=NULL\n", __func__); return false; } if (folder_len == 0) { BB_WARNING("[%s] folder_len=0\n", __func__); return false; } } #ifdef HALBB_DBCC_SUPPORT if (phy_idx == HW_PHY_1 && !bb->hal_com->dbcc_en) { BB_WARNING("[%s]\n",__func__); if (!bb->bb_dbg_i.cr_dbg_mode_en) return false; } #endif BB_DBG(bb, DBG_INIT, "[%s] ic=%d\n", __func__, bb->hal_com->chip_id); switch (bb->ic_type) { #ifdef BB_8852A_2_SUPPORT case BB_RTL8852A: result &= halbb_cfg_bb_gain_ax_8852a_2(bb, is_form_folder, folder_len, folder_array); break; #endif #ifdef BB_8852B_SUPPORT case BB_RTL8852B: result &= halbb_cfg_bb_gain_ax_8852b(bb, is_form_folder, folder_len, folder_array); break; #endif #ifdef BB_8852C_SUPPORT case BB_RTL8852C: result &= halbb_cfg_bb_gain_ax_8852c(bb, is_form_folder, folder_len, folder_array); break; #endif default: BB_WARNING("[%s] ic=%d\n", __func__, bb->hal_com->chip_id); break; } BB_DBG(bb, DBG_INIT, "BB_Gain_table_init_success = %d\n", result); return result; } bool halbb_init_reg(struct bb_info *bb) { struct rtw_para_info_t *reg = NULL; bool rpt_0 = true, rpt_1 = true, rpt_gain = true; reg = &bb->phl_com->phy_sw_cap[HW_PHY_0].bb_phy_reg_info; rpt_0 = halbb_init_cr_default(bb, reg->para_src, reg->para_data_len, reg->para_data, HW_PHY_0); if (bb->hal_com->dbcc_en) { reg = &bb->phl_com->phy_sw_cap[HW_PHY_1].bb_phy_reg_info; rpt_1 = halbb_init_cr_default(bb, reg->para_src, reg->para_data_len, reg->para_data, HW_PHY_1); } reg = &bb->phl_com->phy_sw_cap[HW_PHY_0].bb_phy_reg_gain_info; rpt_gain = halbb_init_gain_table(bb, reg->para_src, reg->para_data_len, reg->para_data, HW_PHY_0); if (rpt_0 && rpt_1 && rpt_gain) return true; else return false; } void halbb_rx_gain_table_dbg(struct bb_info *bb, char input[][16], u32 *_used, char *output, u32 *_out_len) { struct bb_gain_info *gain = &bb->bb_gain_i; u32 val[10] = {0}; u8 i = 0, j = 0; if (_os_strcmp(input[1], "-h") == 0) { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "{show}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "set {lna, tia} band path idx val\n"); return; } if (_os_strcmp(input[1], "show") == 0) { for (i = 0; i < BB_GAIN_BAND_NUM; i++) { if (i == 0) { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "===[2G]===\n"); } else { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "===[5G-%s]===\n", (i == 1) ? ("Low") : ((i == 2) ? "Mid" : "High")); } for (j = 0; j < HALBB_MAX_PATH; j++) { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "LNA_gain[Path=%d] = {%d, %d, %d, %d, %d, %d, %d}\n", j, gain->lna_gain[i][j][0], gain->lna_gain[i][j][1], gain->lna_gain[i][j][2], gain->lna_gain[i][j][3], gain->lna_gain[i][j][4], gain->lna_gain[i][j][5], gain->lna_gain[i][j][6]); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "TIA_gain[Path=%d] = {%d, %d}\n", j, gain->tia_gain[i][j][0], gain->tia_gain[i][j][1]); } } } else if (_os_strcmp(input[1], "set") == 0) { HALBB_SCAN(input[3], DCMD_DECIMAL, &val[0]); HALBB_SCAN(input[4], DCMD_DECIMAL, &val[1]); HALBB_SCAN(input[5], DCMD_DECIMAL, &val[2]); HALBB_SCAN(input[6], DCMD_DECIMAL, &val[3]); if (_os_strcmp(input[2], "lna") == 0) { if (val[0] >= BB_GAIN_BAND_NUM || val[1] >= HALBB_MAX_PATH || val[2] >= IC_LNA_NUM) { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set Err\n"); return; } gain->lna_gain[val[0]][val[1]][val[2]] = (s8)val[3]; BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set lna_gain[%d][%d][%d] = %d\n", val[0], val[1], val[2], val[3]); } else if (_os_strcmp(input[2], "tia") == 0) { if (val[0] >= BB_GAIN_BAND_NUM || val[1] >= HALBB_MAX_PATH || val[2] >= IC_TIA_NUM) { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set Err\n"); return; } gain->tia_gain[val[0]][val[1]][val[2]] = (s8)val[3]; BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set tia_gain[%d][%d][%d] = %d\n", val[0], val[1], val[2], val[3]); } halbb_set_gain_error(bb, bb->hal_com->band[bb->bb_phy_idx].cur_chandef.center_ch); } else { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set Err\n"); } }