/*
|
* SPDX-License-Identifier: BSD-3-Clause
|
*
|
* Copyright (c) 2021, Realtek Semiconductor Corp. All rights reserved.
|
*
|
* Redistribution and use in source and binary forms, with or without modification,
|
* are permitted provided that the following conditions are met:
|
*
|
* * Redistributions of source code must retain the above copyright notice, this
|
* list of conditions and the following disclaimer.
|
*
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
* this list of conditions and the following disclaimer in the documentation
|
* and/or other materials provided with the distribution.
|
*
|
* * Neither the name of the Realtek nor the names of its contributors may
|
* be used to endorse or promote products derived from this software without
|
* specific prior written permission.
|
*
|
*
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
*/
|
|
#include "../halbb_precomp.h"
|
|
#ifdef BB_8852B_SUPPORT
|
|
|
u8 halbb_ex_cn_report_8852b(struct bb_info *bb)
|
{
|
struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i;
|
struct bb_pkt_cnt_su_info *pkt_cnt = &cmn_rpt->bb_pkt_cnt_su_i;
|
struct bb_physts_acc_info *acc = &cmn_rpt->bb_physts_acc_i;
|
struct bb_physts_avg_info *avg = &cmn_rpt->bb_physts_avg_i;
|
u8 cn_report = 0;
|
|
halbb_set_reg(bb, 0x42a0, BIT(23), 0x1);
|
avg->cn_avg = (u8)HALBB_DIV(acc->cn_avg_acc, acc->pkt_cnt_cn_valid);
|
cn_report = (avg->cn_avg >> 1);
|
BB_DBG(bb, DBG_DBG_API, "[CN_avg] = %d\n", (avg->cn_avg >> 1));
|
return cn_report;
|
|
}
|
|
u8 halbb_ex_evm_1ss_report_8852b(struct bb_info *bb)
|
{
|
struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i;
|
struct bb_pkt_cnt_su_info *pkt_cnt = &cmn_rpt->bb_pkt_cnt_su_i;
|
struct bb_physts_acc_info *acc = &cmn_rpt->bb_physts_acc_i;
|
struct bb_physts_avg_info *avg = &cmn_rpt->bb_physts_avg_i;
|
u8 evm_1ss_report = 0;
|
|
avg->evm_1ss = (u8)HALBB_DIV(acc->evm_1ss, (pkt_cnt->pkt_cnt_1ss + pkt_cnt->pkt_cnt_ofdm));
|
|
evm_1ss_report = (avg->evm_1ss >> 2);
|
|
BB_DBG(bb, DBG_DBG_API, "[EVM_1ss] = %d\n", evm_1ss_report);
|
|
|
return evm_1ss_report;
|
}
|
|
u8 halbb_ex_evm_max_report_8852b(struct bb_info *bb)
|
{
|
struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i;
|
struct bb_pkt_cnt_su_info *pkt_cnt = &cmn_rpt->bb_pkt_cnt_su_i;
|
struct bb_physts_acc_info *acc = &cmn_rpt->bb_physts_acc_i;
|
struct bb_physts_avg_info *avg = &cmn_rpt->bb_physts_avg_i;
|
u8 evm_max_report = 0;
|
|
avg->evm_max = (u8)HALBB_DIV(acc->evm_max_acc, pkt_cnt->pkt_cnt_2ss);
|
|
evm_max_report = (avg->evm_max >> 2);
|
|
BB_DBG(bb, DBG_DBG_API, "[EVM_max] = %d\n", evm_max_report);
|
|
return evm_max_report;
|
}
|
|
u8 halbb_ex_evm_min_report_8852b(struct bb_info *bb)
|
{
|
struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i;
|
struct bb_pkt_cnt_su_info *pkt_cnt = &cmn_rpt->bb_pkt_cnt_su_i;
|
struct bb_physts_acc_info *acc = &cmn_rpt->bb_physts_acc_i;
|
struct bb_physts_avg_info *avg = &cmn_rpt->bb_physts_avg_i;
|
u8 evm_min_report = 0;
|
|
avg->evm_min = (u8)HALBB_DIV(acc->evm_min_acc, pkt_cnt->pkt_cnt_2ss);
|
|
evm_min_report = (avg->evm_min >> 2);
|
|
BB_DBG(bb, DBG_DBG_API, "[EVM_min] = %d\n", evm_min_report);
|
|
return evm_min_report;
|
}
|
|
|
bool halbb_set_pwr_ul_tb_ofst_8852b(struct bb_info *bb,
|
s16 pw_ofst, enum phl_phy_idx phy_idx)
|
{
|
/*S(5,0) for 8852A/8852B*/
|
if (pw_ofst < -16 || pw_ofst > 15) {
|
BB_WARNING("[%s] ofst=%d\n", __func__, pw_ofst);
|
return false;
|
}
|
|
/*ECO en*/
|
rtw_hal_mac_write_msk_pwr_reg(bb->hal_com, (u8)phy_idx, 0xD288, BIT31, 1);
|
|
/*1 TX*/
|
rtw_hal_mac_write_msk_pwr_reg(bb->hal_com, (u8)phy_idx, 0xD28c, 0x1f, pw_ofst);
|
|
/*2 TX*/
|
if (pw_ofst < -13)
|
pw_ofst = -13;
|
rtw_hal_mac_write_msk_pwr_reg(bb->hal_com, (u8)phy_idx, 0xD290, 0x1f, pw_ofst - 3);
|
|
return true;
|
}
|
|
bool halbb_lps_info_8852b(struct bb_info *bb, u16 mac_id)
|
{
|
/*
|
struct bb_h2c_lps_info_8852b *lps_info;
|
u32 *bb_h2c;
|
u8 cmdlen = sizeof(struct bb_h2c_lps_info_8852b);
|
u16 lps_info_len = 0;
|
bool ret_val = true, h2c_done = false;
|
u8 i = 0;
|
|
lps_info = hal_mem_alloc(bb->hal_com, cmdlen);
|
|
bb_h2c = (u32 *)lps_info;
|
|
lps_info->central_ch = bb->phl_sta_info[mac_id]->chandef.center_ch;
|
lps_info->pri_ch = bb->phl_sta_info[mac_id]->chandef.chan;
|
lps_info->bw = (u8)bb->phl_sta_info[mac_id]->chandef.bw;
|
lps_info->band_type = (u8)bb->phl_sta_info[mac_id]->chandef.band;
|
|
ret_val = halbb_fill_h2c_cmd(bb, cmdlen, DM_H2C_FW_LPS_INFO,
|
HALBB_H2C_DM, bb_h2c);
|
|
BB_DBG(bb, DBG_FW_INFO, "LPS info=>h2c start\n");
|
|
while (!h2c_done) {
|
h2c_done = (bool)halbb_get_reg(bb, 0x1e0, BIT(0));
|
halbb_delay_us(bb, 50);
|
i++;
|
if (i > 100) {
|
ret_val = false;
|
break;
|
}
|
}
|
|
BB_DBG(bb, DBG_FW_INFO, "LPS info=>h2c[0]: %x, h2c_done: %d\n", bb_h2c[0], h2c_done);
|
|
// Return h2c_done flag to default
|
halbb_set_reg(bb, 0x1e0, BIT(0), 0);
|
|
BB_DBG(bb, DBG_FW_INFO, "LPS info=>h2c[0]: %x\n", bb_h2c[0]);
|
|
hal_mem_free(bb->hal_com, lps_info, cmdlen);
|
|
return ret_val;
|
*/
|
return true;
|
}
|
|
void halbb_digital_cfo_comp_8852b(struct bb_info *bb, s32 curr_cfo)
|
{
|
struct bb_cfo_trk_cr_info *cr = &bb->bb_cfo_trk_i.bb_cfo_trk_cr_i;
|
struct bb_link_info *bb_link = &bb->bb_link_i;
|
struct bb_cfo_trk_info *cfo_trk = &bb->bb_cfo_trk_i;
|
s32 cfo_avg_312; /*in unit of sub-carrier spacing*/
|
bool is_positive = IS_GREATER(curr_cfo, 0);
|
|
if (!bb_link->is_linked) {
|
BB_DBG(bb, DBG_CFO_TRK, "[%s] is_linked=%d\n", __func__,
|
bb_link->is_linked);
|
return;
|
}
|
|
if (curr_cfo == 0) {
|
BB_DBG(bb, DBG_CFO_TRK, "curr_cfo=0\n");
|
return;
|
}
|
|
BB_DBG(bb, DBG_CFO_TRK, "[%s]\n", __func__);
|
|
/*CR{S(12,11} = (CFO_avg{S(12,2)} << 9) / 312.5 = (CFO_avg{S(12,2)} << 10) / 625*/
|
if (is_positive) {
|
cfo_avg_312 = HALBB_DIV(curr_cfo, 625) + cfo_trk->dcfo_comp_offset;
|
} else {
|
cfo_avg_312 = HALBB_DIV(curr_cfo, 625) - cfo_trk->dcfo_comp_offset;
|
}
|
|
/*312.5KHz/(2^11) ~ 152Hz per step*/
|
BB_DBG(bb, DBG_CFO_TRK, "[52B] cfo_avg_312 = %d step\n", cfo_avg_312);
|
|
halbb_print_sign_frac_digit(bb, curr_cfo, 32, (cfo_trk->shift4dcfo+2), bb->dbg_buf, HALBB_SNPRINT_SIZE);
|
BB_DBG(bb, DBG_CFO_TRK, "[CFO_DBG] [Digital Comp] cfo: %s KHz\n", bb->dbg_buf);
|
|
halbb_print_sign_frac_digit(bb, cfo_avg_312, 32, 11, bb->dbg_buf, HALBB_SNPRINT_SIZE);
|
BB_DBG(bb, DBG_CFO_TRK, "[CFO_DBG] cfo_avg_312: %s * 312.5KHz\n", bb->dbg_buf);
|
|
halbb_set_reg(bb, cr->r_cfo_comp_seg0_312p5khz, cr->r_cfo_comp_seg0_312p5khz_m, cfo_avg_312);
|
}
|
|
void halbb_tx_triangular_shap_cfg_8852b(struct bb_info *bb, u8 shape_idx,
|
enum phl_phy_idx phy_idx) {
|
|
halbb_set_reg(bb, 0x4494, 0x3000000, shape_idx);
|
/*0:0dB 1:-4dB 2:-5dB 3:-6dB*/
|
|
if (bb->ic_sub_type == BB_IC_SUB_TYPE_8852B_8852BP){
|
halbb_set_reg(bb, 0x44ac, BIT(3), 0x0);
|
halbb_set_reg(bb, 0x140, BIT(0), 0x1);
|
}
|
}
|
|
void halbb_tx_dfir_shap_cck_8852b(struct bb_info *bb, u8 ch, u8 shape_idx,
|
enum phl_phy_idx phy_idx) {
|
|
u32 para_flat[8] = {0x023D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053,
|
0x00F86F9A, 0x06FAEF92, 0x00FE5FCC, 0x00FFDFF5};
|
u32 para_sharp[8] = {0x023D83FF, 0x002C636A, 0x0013F204, 0x00008090,
|
0x00F87FB0, 0x06F99F83, 0x00FDBFBA, 0x00003FF5};
|
u32 para_sharp_14[8] = {0x023B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E,
|
0x00FD8F92, 0x0602D011, 0x0001C02C, 0x00FFF00A};
|
u32 *para = NULL;
|
u8 i = 0;
|
|
BB_DBG(bb, DBG_DBG_API, "[%s] ch=%d, shape_idx=%d\n", __func__, ch, shape_idx);
|
|
if (ch > 14)
|
return;
|
|
if (ch == 14) {
|
para = para_sharp_14;
|
} else {
|
if (shape_idx == 0) {
|
/*flat CH1~14*/
|
para = para_flat;
|
} else {
|
/*Sharp( b mode tx dfir)*/
|
para = para_sharp;
|
}
|
}
|
|
for (i = 0; i < 8; i++) {
|
halbb_set_reg_cmn(bb, 0x2300 + (i << 2), MASKDWORD, para[i], phy_idx);
|
BB_DBG(bb, DBG_DBG_API, "Reg0x%08x = 0x%08x\n", 0x2300 + (i << 2), para[i]);
|
}
|
}
|
|
void halbb_bb_reset_8852b(struct bb_info *bb, enum phl_phy_idx phy_idx)
|
{
|
u8 val = 0;
|
BB_DBG(bb, DBG_DBG_API, "%s\n", __func__);
|
|
// === [TSSI protect on] === //
|
halbb_set_reg(bb, 0x58dc, BIT(30) | BIT(31), 0x1);
|
halbb_set_reg(bb, 0x5818, BIT(30), 0x1);
|
halbb_set_reg(bb, 0x78dc, BIT(30) | BIT(31), 0x1);
|
halbb_set_reg(bb, 0x7818, BIT(30), 0x1);
|
|
// === [PD Disable] === //
|
halbb_set_reg(bb,0x2344, BIT(31), 0x1);
|
halbb_set_reg(bb,0xc3c, BIT(9), 0x1);
|
|
// === [stop phy-sts update] === //
|
val = hal_read8(bb->hal_com, 0xce40);
|
val = val & ~(0x1);
|
hal_write8(bb->hal_com, 0xce40, val);
|
halbb_delay_us(bb, 2);
|
|
// === [BB reset] === //
|
halbb_set_reg_cmn(bb, 0x704, BIT(1), 1, phy_idx);
|
halbb_set_reg_cmn(bb, 0x704, BIT(1), 0, phy_idx);
|
halbb_set_reg_cmn(bb, 0x704, BIT(1), 1, phy_idx);
|
|
// === [start phy-sts update] === //
|
val = hal_read8(bb->hal_com, 0xce40);
|
val = val | 0x1;
|
hal_write8(bb->hal_com, 0xce40, val);
|
|
// === [PD Enable] === //
|
if(bb->hal_com->band[0].cur_chandef.band == BAND_ON_24G)
|
halbb_set_reg(bb,0x2344, BIT(31), 0x0);
|
halbb_set_reg(bb,0xc3c, BIT(9), 0x0);
|
|
// === [TSSI protect off] === //
|
halbb_set_reg(bb, 0x58dc, BIT(30) | BIT(31), 0x3);
|
halbb_set_reg(bb, 0x5818, BIT(30), 0x0);
|
halbb_set_reg(bb, 0x78dc, BIT(30) | BIT(31), 0x3);
|
halbb_set_reg(bb, 0x7818, BIT(30), 0x0);
|
}
|
|
void halbb_dfs_en_8852b(struct bb_info *bb, bool en)
|
{
|
BB_DBG(bb, DBG_DBG_API, "%s\n", __func__);
|
|
if (en)
|
halbb_set_reg(bb, 0x0, BIT(31), 1);
|
else
|
halbb_set_reg(bb, 0x0, BIT(31), 0);
|
}
|
|
void halbb_adc_en_8852b(struct bb_info *bb, bool en)
|
{
|
BB_DBG(bb, DBG_DBG_API, "%s\n", __func__);
|
|
if (en)
|
halbb_set_reg(bb, 0x20fc, 0xff000000, 0x0);
|
else
|
halbb_set_reg(bb, 0x20fc, 0xff000000, 0xf);
|
}
|
|
bool halbb_adc_cfg_8852bt(struct bb_info *bb, enum channel_width bw,
|
enum rf_path path)
|
{
|
u32 idac2[2] = {0xC0D4, 0xC1D4};
|
u32 idac2_1[2] = {0xC0D4, 0xC1D4};
|
u32 adc_sample_td[2] = {0xC0D4, 0xC1D4};
|
u32 adc_op5_bw_sel[2] = {0xC0D8, 0xC1D8};
|
u32 rck_offset[2] = {0xC0C4, 0xC1C4};
|
u32 rck_reset_count[2] = {0xC0E8, 0xC1E8};
|
u32 wbadc_sel[2] = {0xC0E4, 0xC1E4};
|
u32 rx_adc_clk[2] = {0x12A0, 0x32A0};
|
u32 decim_filter[2] = {0xC0EC, 0xC1EC};
|
u32 adc_rst_cycle[2] = {0xC0EC, 0xC1EC};
|
|
BB_DBG(bb, DBG_DBG_API, "%s\n", __func__);
|
|
halbb_set_reg(bb, idac2[path], 0x780, 0x8);
|
halbb_set_reg(bb, rck_reset_count[path], 0xFFFF0000, 0x9);
|
halbb_set_reg(bb, wbadc_sel[path], 0x30, 0x2);
|
halbb_set_reg(bb, rx_adc_clk[path], 0xFF800000, 0x49);
|
halbb_set_reg(bb, decim_filter[path], 0x6000, 0x0);
|
|
switch (bw) {
|
case CHANNEL_WIDTH_5:
|
case CHANNEL_WIDTH_10:
|
case CHANNEL_WIDTH_20:
|
case CHANNEL_WIDTH_40:/*ADC clock = 80M & WB ADC clock = 160M */
|
halbb_set_reg(bb, idac2_1[path], 0x7800, 0x2);
|
halbb_set_reg(bb, adc_sample_td[path], 0xC000000, 0x3);
|
halbb_set_reg(bb, adc_op5_bw_sel[path], 0x1E0, 0xf);
|
halbb_set_reg(bb, rck_offset[path], 0x3E0000, 0x0);
|
if (bb->phl_com->dev_cap.rfe_type >= 51)
|
halbb_set_reg(bb, adc_rst_cycle[path], 0xFF0000, 0x2);
|
else
|
halbb_set_reg(bb, adc_rst_cycle[path], 0xFF0000, 0x3);
|
break;
|
case CHANNEL_WIDTH_80:/*ADC clock = 160M & WB ADC clock = 160M */
|
halbb_set_reg(bb, idac2_1[path], 0x7800, 0x2);
|
halbb_set_reg(bb, adc_sample_td[path], 0xC000000, 0x2);
|
halbb_set_reg(bb, adc_op5_bw_sel[path], 0x1E0, 0x8);
|
halbb_set_reg(bb, rck_offset[path], 0x3E0000, 0x0);
|
halbb_set_reg(bb, adc_rst_cycle[path], 0xFF0000, 0x3);
|
break;
|
|
default:
|
BB_WARNING("Fail to set ADC\n");
|
return false;
|
}
|
|
return true;
|
}
|
|
|
void halbb_tssi_cont_en_8852b(struct bb_info *bb, bool en, enum rf_path path)
|
{
|
u32 tssi_trk_man[2] = {0x5818, 0x7818};
|
|
BB_DBG(bb, DBG_DBG_API, "%s\n", __func__);
|
|
if (en) {
|
halbb_set_reg(bb, tssi_trk_man[path], BIT(30), 0x0);
|
rtw_hal_rf_tssi_scan_ch(bb->hal_com, HW_PHY_0, path);
|
} else {
|
halbb_set_reg(bb, tssi_trk_man[path], BIT(30), 0x1);
|
}
|
}
|
void halbb_bb_reset_all_8852b(struct bb_info *bb, enum phl_phy_idx phy_idx)
|
{
|
u8 val = 0;
|
BB_DBG(bb, DBG_DBG_API, "%s\n", __func__);
|
|
//PD Disable
|
halbb_set_reg(bb,0x2344, BIT(31), 0x1);
|
halbb_set_reg(bb,0xc3c, BIT(9), 0x1);
|
|
//Protest SW-SI
|
halbb_set_reg_cmn(bb, 0x1200, BIT(28) | BIT(29) | BIT(30), 0x7, phy_idx);
|
halbb_set_reg_cmn(bb, 0x3200, BIT(28) | BIT(29) | BIT(30), 0x7, phy_idx);
|
halbb_delay_us(bb, 1);
|
|
// === [stop phy-sts update] === //
|
val = hal_read8(bb->hal_com, 0xce40);
|
val = val & ~(0x1);
|
hal_write8(bb->hal_com, 0xce40, val);
|
halbb_delay_us(bb, 2);
|
|
// === [BB reset] === //
|
halbb_set_reg_cmn(bb, 0x704, BIT(1), 1, phy_idx);
|
halbb_set_reg_cmn(bb, 0x704, BIT(1), 0, phy_idx);
|
|
halbb_set_reg_cmn(bb, 0x1200, BIT(28) | BIT(29) | BIT(30), 0x0, phy_idx);
|
halbb_set_reg_cmn(bb, 0x3200, BIT(28) | BIT(29) | BIT(30), 0x0, phy_idx);
|
halbb_set_reg_cmn(bb, 0x704, BIT(1), 1, phy_idx);
|
|
// === [start phy-sts update] === //
|
val = hal_read8(bb->hal_com, 0xce40);
|
val = val | 0x1;
|
hal_write8(bb->hal_com, 0xce40, val);
|
|
//PD Enable
|
if(bb->hal_com->band[0].cur_chandef.band == BAND_ON_24G)
|
halbb_set_reg(bb,0x2344, BIT(31), 0x0);
|
halbb_set_reg(bb,0xc3c, BIT(9), 0x0);
|
|
}
|
|
void halbb_bb_reset_en_8852b(struct bb_info *bb, bool en, enum phl_phy_idx phy_idx)
|
{
|
u8 val = 0, protect = 0;
|
BB_DBG(bb, DBG_DBG_API, "%s\n", __func__);
|
|
if (0x1 & hal_read8(bb->hal_com, 0xce40))
|
protect = 1;
|
|
if (en) {
|
halbb_set_reg_cmn(bb, 0x1200, BIT(28) | BIT(29) | BIT(30), 0x0, phy_idx);
|
halbb_set_reg_cmn(bb, 0x3200, BIT(28) | BIT(29) | BIT(30), 0x0, phy_idx);
|
|
if (protect) {
|
// === [stop phy-sts update] === //
|
val = hal_read8(bb->hal_com, 0xce40);
|
val = val & ~(0x1);
|
hal_write8(bb->hal_com, 0xce40, val);
|
halbb_delay_us(bb, 2);
|
halbb_set_reg_cmn(bb, 0x704, BIT(1), 1, phy_idx);
|
// === [start phy-sts update] === //
|
val = hal_read8(bb->hal_com, 0xce40);
|
val = val | 0x1;
|
hal_write8(bb->hal_com, 0xce40, val);
|
} else {
|
halbb_set_reg_cmn(bb, 0x704, BIT(1), 1, phy_idx);
|
}
|
|
//PD Enable
|
if(bb->hal_com->band[0].cur_chandef.band == BAND_ON_24G)
|
halbb_set_reg(bb,0x2344, BIT(31), 0x0);
|
halbb_set_reg(bb,0xc3c, BIT(9), 0x0);
|
} else {
|
//PD Disable
|
halbb_set_reg(bb,0x2344, BIT(31), 0x1);
|
halbb_set_reg(bb,0xc3c, BIT(9), 0x1);
|
//Protest SW-SI
|
halbb_set_reg_cmn(bb, 0x1200, BIT(28) | BIT(29) | BIT(30), 0x7, phy_idx);
|
halbb_set_reg_cmn(bb, 0x3200, BIT(28) | BIT(29) | BIT(30), 0x7, phy_idx);
|
halbb_delay_us(bb, 1);
|
|
if (protect) {
|
// === [stop phy-sts update] === //
|
val = hal_read8(bb->hal_com, 0xce40);
|
val = val & ~(0x1);
|
hal_write8(bb->hal_com, 0xce40, val);
|
halbb_delay_us(bb, 2);
|
halbb_set_reg_cmn(bb, 0x704, BIT(1), 0, phy_idx);
|
// === [start phy-sts update] === //
|
val = hal_read8(bb->hal_com, 0xce40);
|
val = val | 0x1;
|
hal_write8(bb->hal_com, 0xce40, val);
|
} else {
|
halbb_set_reg_cmn(bb, 0x704, BIT(1), 0, phy_idx);
|
}
|
}
|
}
|
|
u32 halbb_read_rf_reg_8852b_a(struct bb_info *bb, enum rf_path path,
|
u32 reg_addr, u32 bit_mask)
|
{
|
u8 path_tmp=0;
|
u32 i = 0, j = 0, readback_value = INVALID_RF_DATA, r_reg = 0;
|
u32 r_reg_done = 0, cnt = 500;
|
bool is_r_busy = true, is_w_busy = true, is_r_done = false, is_r_correct = false;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
/*==== Error handling ====*/
|
while (is_w_busy || is_r_busy) {
|
is_w_busy = (bool)halbb_get_reg(bb, 0x174c, BIT(24));
|
is_r_busy = (bool)halbb_get_reg(bb, 0x174c, BIT(25));
|
halbb_delay_us(bb, 1);
|
/*BB_WARNING("[%s] is_w_busy = %d, is_r_busy = %d\n",
|
__func__, is_w_busy, is_r_busy);*/
|
i++;
|
if (i > 500)
|
break;
|
}
|
if (is_w_busy || is_r_busy) {
|
BB_WARNING("[%s] is_w_busy = (%d), is_r_busy = (%d)\n",
|
__func__, is_w_busy, is_r_busy);
|
return INVALID_RF_DATA;
|
}
|
|
if (path > RF_PATH_B || path < RF_PATH_A) {
|
BB_WARNING("[%s] Unsupported path (%d)\n", __func__, path);
|
return INVALID_RF_DATA;
|
}
|
|
/*==== Calculate offset ====*/
|
path_tmp = (u8)path & 0x7;
|
reg_addr &= 0xff;
|
|
/*==== RF register only has 20bits ====*/
|
bit_mask &= RFREGOFFSETMASK;
|
|
r_reg = (path_tmp << 8 | reg_addr) & 0x7ff;
|
|
do {
|
halbb_set_reg(bb, 0x378, 0x7ff, r_reg);
|
halbb_delay_us(bb, 2);
|
r_reg_done = halbb_get_reg(bb, 0x378, 0x7ff);
|
is_r_correct = (r_reg == r_reg_done);
|
} while ((!is_r_correct) && ((cnt--) > 0));
|
|
if (cnt == 0) {
|
BB_WARNING("[%s] read fail path (%d) r_reg: %x r_reg_done: %x\n", __func__, path,r_reg, r_reg_done);
|
}
|
|
/*==== Read RF register ====*/
|
while (!is_r_done) {
|
is_r_done = (bool)halbb_get_reg(bb, 0x174c, BIT(26));
|
halbb_delay_us(bb, 5);
|
j++;
|
if (j > 500)
|
break;
|
}
|
|
if (is_r_done) {
|
readback_value = halbb_get_reg(bb, 0x174c, bit_mask);
|
} else {
|
BB_WARNING("[%s] is_r_done = (%d)\n", __func__, is_r_done);
|
return INVALID_RF_DATA;
|
}
|
BB_DBG(bb, DBG_PHY_CONFIG, "A die RF-%d 0x%x = 0x%x, bit mask = 0x%x, i=%x, j =%x\n",
|
path_tmp, reg_addr, readback_value, bit_mask,i,j);
|
return readback_value;
|
}
|
|
u32 halbb_read_rf_reg_8852b_d(struct bb_info *bb, enum rf_path path,
|
u32 reg_addr, u32 bit_mask)
|
{
|
u32 readback_value = 0, direct_addr = 0;
|
u32 offset_read_rf[2] = {0xe000, 0xf000};
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
/*==== Error handling ====*/
|
if (path > RF_PATH_B) {
|
BB_WARNING("[%s] Unsupported path (%d)\n", __func__, path);
|
return INVALID_RF_DATA;
|
}
|
|
/*==== Calculate offset ====*/
|
reg_addr &= 0xff;
|
direct_addr = offset_read_rf[path] + (reg_addr << 2);
|
|
/*==== RF register only has 20bits ====*/
|
bit_mask &= RFREGOFFSETMASK;
|
|
/*==== Read RF register directly ====*/
|
readback_value = halbb_get_reg(bb, direct_addr, bit_mask);
|
BB_DBG(bb, DBG_PHY_CONFIG, "D die RF-%d 0x100%x = 0x%x, bit mask = 0x%x\n",
|
path, reg_addr, readback_value, bit_mask);
|
return readback_value;
|
}
|
|
u32 halbb_read_rf_reg_8852b(struct bb_info *bb, enum rf_path path, u32 reg_addr,
|
u32 bit_mask)
|
{
|
u32 readback_value = INVALID_RF_DATA;
|
enum rtw_dv_sel ad_sel = (enum rtw_dv_sel)((reg_addr & 0x10000) >> 16);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
/*==== Error handling ====*/
|
if (path > RF_PATH_B) {
|
BB_WARNING("[%s] Unsupported path (%d)\n", __func__, path);
|
return INVALID_RF_DATA;
|
}
|
|
if (ad_sel == DAV) {
|
readback_value = halbb_read_rf_reg_8852b_a(bb, path, reg_addr,
|
bit_mask);
|
/*BB_DBG(bb, DBG_PHY_CONFIG, "A-die RF-%d 0x%x = 0x%x, bit mask = 0x%x\n",
|
path, reg_addr, readback_value, bit_mask);*/
|
} else if (ad_sel == DDV) {
|
readback_value = halbb_read_rf_reg_8852b_d(bb, path, reg_addr,
|
bit_mask);
|
/*BB_DBG(bb, DBG_PHY_CONFIG, "D-die RF-%d 0x%x = 0x%x, bit mask = 0x%x\n",
|
path, reg_addr, readback_value, bit_mask);*/
|
} else {
|
BB_DBG(bb, DBG_PHY_CONFIG, "Fail Read RF RF-%d 0x%x = 0x%x, bit mask = 0x%x\n",
|
path, reg_addr, readback_value, bit_mask);
|
return INVALID_RF_DATA;
|
}
|
return readback_value;
|
}
|
|
void halbb_5m_mask_8852b(struct bb_info *bb, u8 pri_ch_idx, enum channel_width bw,
|
enum phl_phy_idx phy_idx)
|
{
|
bool mask_5m_low = false;
|
bool mask_5m_en = false;
|
|
switch (bw) {
|
case CHANNEL_WIDTH_40:
|
/* Prich=1 : Mask 5M High
|
Prich=2 : Mask 5M Low */
|
mask_5m_en = true;
|
mask_5m_low = pri_ch_idx == 2 ? true : false;
|
break;
|
case CHANNEL_WIDTH_80:
|
/* Prich=3 : Mask 5M High
|
Prich=4 : Mask 5M Low
|
Else : Mask 5M Disable */
|
mask_5m_en = ((pri_ch_idx == 3) || (pri_ch_idx == 4)) ? true : false;
|
mask_5m_low = pri_ch_idx == 4 ? true : false;
|
break;
|
default:
|
mask_5m_en = false;
|
break;
|
}
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[5M Mask] pri_ch_idx = %d, bw = %d", pri_ch_idx, bw);
|
|
if (!mask_5m_en) {
|
halbb_set_reg(bb, 0x46f8, BIT(12), 0x0);
|
halbb_set_reg(bb, 0x47b8, BIT(12), 0x0);
|
halbb_set_reg_cmn(bb, 0x4440, BIT(31), 0x0, phy_idx);
|
} else {
|
if (mask_5m_low) {
|
halbb_set_reg(bb, 0x46f8, 0x3f, 0x4);
|
halbb_set_reg(bb, 0x46f8, BIT(12), 0x1);
|
halbb_set_reg(bb, 0x46f8, BIT(8), 0x0);
|
halbb_set_reg(bb, 0x46f8, BIT(6), 0x1);
|
halbb_set_reg(bb, 0x47b8, 0x3f, 0x4);
|
halbb_set_reg(bb, 0x47b8, BIT(12), 0x1);
|
halbb_set_reg(bb, 0x47b8, BIT(8), 0x0);
|
halbb_set_reg(bb, 0x47b8, BIT(6), 0x1);
|
} else {
|
halbb_set_reg(bb, 0x46f8, 0x3f, 0x4);
|
halbb_set_reg(bb, 0x46f8, BIT(12), 0x1);
|
halbb_set_reg(bb, 0x46f8, BIT(8), 0x1);
|
halbb_set_reg(bb, 0x46f8, BIT(6), 0x0);
|
halbb_set_reg(bb, 0x47b8, 0x3f, 0x4);
|
halbb_set_reg(bb, 0x47b8, BIT(12), 0x1);
|
halbb_set_reg(bb, 0x47b8, BIT(8), 0x1);
|
halbb_set_reg(bb, 0x47b8, BIT(6), 0x0);
|
}
|
halbb_set_reg_cmn(bb, 0x4440, BIT(31), 0x1, phy_idx);
|
}
|
}
|
|
bool halbb_ctrl_sco_cck_8852b(struct bb_info *bb, u8 pri_ch)
|
{
|
u32 sco_barker_threshold[14] = {0x1cfea, 0x1d0e1, 0x1d1d7, 0x1d2cd,
|
0x1d3c3, 0x1d4b9, 0x1d5b0, 0x1d6a6,
|
0x1d79c, 0x1d892, 0x1d988, 0x1da7f,
|
0x1db75, 0x1ddc4};
|
u32 sco_cck_threshold[14] = {0x27de3, 0x27f35, 0x28088, 0x281da,
|
0x2832d, 0x2847f, 0x285d2, 0x28724,
|
0x28877, 0x289c9, 0x28b1c, 0x28c6e,
|
0x28dc1, 0x290ed};
|
|
if (pri_ch > 14) {
|
BB_DBG(bb, DBG_PHY_CONFIG, "[CCK SCO Fail]");
|
return false;
|
}
|
|
halbb_set_reg(bb, 0x23b0, 0x7ffff, sco_barker_threshold[pri_ch - 1]);
|
halbb_set_reg(bb, 0x23b4, 0x7ffff, sco_cck_threshold[pri_ch - 1]);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[CCK SCO Success]");
|
return true;
|
}
|
|
bool halbb_write_rf_reg_8852b_a(struct bb_info *bb, enum rf_path path,
|
u32 reg_addr, u32 bit_mask, u32 data)
|
{
|
u8 path_tmp = 0, b_msk_en = 0, bit_shift = 0;
|
u32 i =0, w_reg = 0, w_reg_done = 0, cnt = 500;
|
bool is_r_busy = true, is_w_busy = true, is_w_correct = false;;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
/*==== Error handling ====*/
|
while (is_w_busy || is_r_busy) {
|
is_w_busy = (bool)halbb_get_reg(bb, 0x174c, BIT(24));
|
is_r_busy = (bool)halbb_get_reg(bb, 0x174c, BIT(25));
|
halbb_delay_us(bb, 1);
|
/*BB_WARNING("[%s] is_w_busy = %d, is_r_busy = %d\n",
|
__func__, is_w_busy, is_r_busy);*/
|
i++;
|
if (i > 500)
|
break;
|
}
|
if (is_w_busy || is_r_busy) {
|
BB_WARNING("[%s] is_w_busy = (%d), is_r_busy = (%d)\n",
|
__func__, is_w_busy, is_r_busy);
|
return false;
|
}
|
if (path > RF_PATH_B || path < RF_PATH_A) {
|
BB_WARNING("[%s] Unsupported path (%d)\n", __func__, path);
|
return false;
|
}
|
|
/*==== Calculate offset ====*/
|
path_tmp = (u8)path & 0x7;
|
reg_addr &= 0xff;
|
|
/*==== RF register only has 20bits ====*/
|
data &= RFREGOFFSETMASK;
|
bit_mask &= RFREGOFFSETMASK;
|
|
/*==== Check if mask needed ====*/
|
if (bit_mask != RFREGOFFSETMASK) {
|
b_msk_en = 1;
|
halbb_set_reg(bb, 0x374, RFREGOFFSETMASK, bit_mask);
|
for (bit_shift = 0; bit_shift <= 19; bit_shift++) {
|
if ((bit_mask >> bit_shift) & 0x1)
|
break;
|
}
|
data = (data << bit_shift) & RFREGOFFSETMASK;
|
}
|
|
w_reg = b_msk_en << 31 | path_tmp << 28 | reg_addr << 20 | data;
|
|
/*==== Write RF register ====*/
|
do {
|
halbb_set_reg(bb, 0x370, MASKDWORD, w_reg);
|
halbb_delay_us(bb, 5);
|
w_reg_done = halbb_get_reg(bb, 0x370, MASKDWORD);
|
is_w_correct = (w_reg == w_reg_done);
|
} while ((!is_w_correct) && (cnt-- > 0));
|
|
halbb_delay_us(bb, 5);
|
|
if(cnt == 0)
|
BB_WARNING("[%s] write fail path (%d) w_reg: %x w_reg_done:%x \n", __func__, path,w_reg, w_reg_done);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "A die RF-%d 0x%x = 0x%x , bit mask = 0x%x, i=%x\n",
|
path_tmp, reg_addr, data, bit_mask,i);
|
|
return true;
|
}
|
|
bool halbb_write_rf_reg_8852b_d(struct bb_info *bb, enum rf_path path,
|
u32 reg_addr, u32 bit_mask, u32 data)
|
{
|
u32 direct_addr = 0;
|
u32 offset_write_rf[2] = {0xe000, 0xf000};
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
/*==== Error handling ====*/
|
if (path > RF_PATH_B) {
|
BB_WARNING("[%s] Unsupported path (%d)\n", __func__, path);
|
return false;
|
}
|
|
/*==== Calculate offset ====*/
|
reg_addr &= 0xff;
|
direct_addr = offset_write_rf[path] + (reg_addr << 2);
|
|
/*==== RF register only has 20bits ====*/
|
bit_mask &= RFREGOFFSETMASK;
|
|
/*==== Write RF register directly ====*/
|
halbb_set_reg(bb, direct_addr, bit_mask, data);
|
|
halbb_delay_us(bb, 1);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "D die RF-%d 0x%x = 0x%x , bit mask = 0x%x\n",
|
path, reg_addr, data, bit_mask);
|
|
return true;
|
}
|
|
bool halbb_write_rf_reg_8852b(struct bb_info *bb, enum rf_path path,
|
u32 reg_addr, u32 bit_mask, u32 data)
|
{
|
u8 path_tmp = 0, b_msk_en = 0;
|
u32 w_reg = 0;
|
bool rpt = true;
|
enum rtw_dv_sel ad_sel = (enum rtw_dv_sel)((reg_addr & 0x10000) >> 16);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
/*==== Error handling ====*/
|
if (path > RF_PATH_B) {
|
BB_WARNING("[%s] Unsupported path (%d)\n", __func__, path);
|
return false;
|
}
|
|
if (ad_sel == DAV) {
|
rpt = halbb_write_rf_reg_8852b_a(bb, path, reg_addr, bit_mask,
|
data);
|
/*BB_DBG(bb, DBG_PHY_CONFIG, "A-die RF-%d 0x%x = 0x%x , bit mask = 0x%x\n",
|
path, reg_addr, data, bit_mask);*/
|
} else if (ad_sel == DDV) {
|
rpt = halbb_write_rf_reg_8852b_d(bb, path, reg_addr, bit_mask,
|
data);
|
/*BB_DBG(bb, DBG_PHY_CONFIG, "D-die RF-%d 0x%x = 0x%x , bit mask = 0x%x\n",
|
path, reg_addr, data, bit_mask);*/
|
} else {
|
rpt = false;
|
BB_DBG(bb, DBG_PHY_CONFIG, "Fail Write RF-%d 0x%x = 0x%x , bit mask = 0x%x\n",
|
path, reg_addr, data, bit_mask);
|
}
|
|
return rpt;
|
}
|
void halbb_ctrl_btg_8852b(struct bb_info *bb, bool btg)
|
{
|
struct rtw_phl_com_t *phl = bb->phl_com;
|
struct dev_cap_t *dev = &phl->dev_cap;
|
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
/*
|
if(bb->hal_com->band[0].cur_chandef.band != BAND_ON_24G)
|
return;
|
*/
|
if (btg) {
|
// Path A
|
halbb_set_reg(bb, 0x4738, BIT(19), 0x1);
|
halbb_set_reg(bb, 0x4738, BIT(22), 0x0);
|
// Path B
|
halbb_set_reg(bb, 0x476c, 0xFF000000, 0x20);
|
halbb_set_reg(bb, 0x4778, 0xFF, 0x30);
|
halbb_set_reg(bb, 0x4AA4, BIT(19), 0x1);
|
halbb_set_reg(bb, 0x4AA4, BIT(22), 0x1);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[BT] Apply BTG Setting\n");
|
// Apply Grant BT by TMAC Setting
|
halbb_set_reg(bb, 0x980, 0x1e0000, 0x0);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[BT] Apply Grant BT by TMAC Setting\n");
|
// Add BT share
|
halbb_set_reg(bb, 0x49C4, BIT(14), 0x1);
|
halbb_set_reg(bb, 0x49C0, 0x3c00000, 0x2);
|
/* To avoid abnormal 1R CCA without BT, set rtl only 0xc6c[21] = 0x1 */
|
halbb_set_reg(bb, 0x4420, BIT(31), 0x1);
|
halbb_set_reg(bb, 0xc6c, BIT(21), 0x1);
|
} else {
|
// Path A
|
halbb_set_reg(bb, 0x4738, BIT(19), 0x0);
|
halbb_set_reg(bb, 0x4738, BIT(22), 0x0);
|
// Path B
|
halbb_set_reg(bb, 0x476c, 0xFF000000, 0x1a);
|
halbb_set_reg(bb, 0x4778, 0xFF, 0x2a);
|
halbb_set_reg(bb, 0x4AA4, BIT(19), 0x0);
|
halbb_set_reg(bb, 0x4AA4, BIT(22), 0x0);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[BT] Disable BTG Setting\n");
|
// Ignore Grant BT by PMAC Setting
|
halbb_set_reg(bb, 0x980, 0x1e0000, 0xc);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[BT] Ignore Grant BT by PMAC Setting\n");
|
// Reset BT share
|
halbb_set_reg(bb, 0x49C4, BIT(14), 0x0);
|
halbb_set_reg(bb, 0x49C0, 0x3c00000, 0x0);
|
/* To avoid abnormal 1R CCA without BT, set rtl only 0xc6c[21] = 0x1 */
|
halbb_set_reg(bb, 0x4420, BIT(31), 0x1);
|
halbb_set_reg(bb, 0xc6c, BIT(21), 0x0);
|
}
|
}
|
|
void halbb_ctrl_btc_preagc_8852b(struct bb_info *bb, bool bt_en)
|
{
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
if (bt_en) {
|
// DFIR Corner
|
halbb_set_reg(bb, 0x46D0, BIT(1) | BIT(0), 0x3);
|
halbb_set_reg(bb, 0x4790, BIT(1) | BIT(0), 0x3);
|
|
// BT trakcing always on
|
halbb_set_reg(bb, 0x4ad4, MASKDWORD, 0xf);
|
halbb_set_reg(bb, 0x4ae0, MASKDWORD, 0xf);
|
|
// LNA6_OP1dB
|
halbb_set_reg(bb, 0x4688, MASKBYTE3, 0x80);
|
halbb_set_reg(bb, 0x476C, MASKBYTE3, 0x80);
|
|
// LNA6_TIA0_1_OP1dB
|
halbb_set_reg(bb, 0x4694, MASKBYTE0, 0x80);
|
halbb_set_reg(bb, 0x4694, MASKBYTE1, 0x80);
|
halbb_set_reg(bb, 0x4778, MASKBYTE0, 0x80);
|
halbb_set_reg(bb, 0x4778, MASKBYTE1, 0x80);
|
|
// LNA, TIA, ADC backoff at BT TX
|
|
if (bb->ic_sub_type == BB_IC_SUB_TYPE_8852B_8852BP) {
|
halbb_set_reg(bb, 0x4ae4, 0xffffff, 0x787D1E);
|
halbb_set_reg(bb, 0x4aec, 0xffffff, 0x787D1E);
|
} else {
|
halbb_set_reg(bb, 0x4ae4, 0xffffff, 0x780D1E);
|
halbb_set_reg(bb, 0x4aec, 0xffffff, 0x780D1E);
|
}
|
|
// IBADC backoff
|
halbb_set_reg(bb, 0x469c, 0xfc000000, 0x34);
|
halbb_set_reg(bb, 0x49f0, 0xfc000000, 0x34);
|
|
} else {
|
// DFIR Corner
|
halbb_set_reg(bb, 0x46D0, BIT(1) | BIT(0), 0x0);
|
halbb_set_reg(bb, 0x4790, BIT(1) | BIT(0), 0x0);
|
|
// BT trakcing always on
|
halbb_set_reg(bb, 0x4ad4, MASKDWORD, 0x60);
|
halbb_set_reg(bb, 0x4ae0, MASKDWORD, 0x60);
|
|
// LNA6_OP1dB
|
halbb_set_reg(bb, 0x4688, MASKBYTE3, 0x1a);
|
halbb_set_reg(bb, 0x476C, MASKBYTE3, 0x20);
|
|
// LNA6_TIA0_1_OP1dB
|
halbb_set_reg(bb, 0x4694, MASKBYTE0, 0x2a);
|
halbb_set_reg(bb, 0x4694, MASKBYTE1, 0x2a);
|
halbb_set_reg(bb, 0x4778, MASKBYTE0, 0x30);
|
halbb_set_reg(bb, 0x4778, MASKBYTE1, 0x2a);
|
|
// LNA, TIA, ADC backoff at BT TX
|
halbb_set_reg(bb, 0x4ae4, 0xffffff, 0x79E99E);
|
halbb_set_reg(bb, 0x4aec, 0xffffff, 0x79E99E);
|
|
// IBADC backoff
|
halbb_set_reg(bb, 0x469c, 0xfc000000, 0x26);
|
halbb_set_reg(bb, 0x49f0, 0xfc000000, 0x26);
|
|
}
|
}
|
bool halbb_bw_setting_8852b(struct bb_info *bb, enum channel_width bw,
|
enum rf_path path)
|
{
|
u32 rf_reg18 = 0;
|
u32 adc_sel[2] = {0xC0EC, 0xC1EC};
|
u32 wbadc_sel[2] = {0xC0E4, 0xC1E4};
|
|
//rf_reg18 = halbb_read_rf_reg_8852b(bb, path, 0x18, RFREGOFFSETMASK);
|
/*==== [Error handling] ====*/
|
//if (rf_reg18 == INVALID_RF_DATA) {
|
// BB_WARNING("Invalid RF_0x18 for Path-%d\n", path);
|
// return false;
|
//}
|
//rf_reg18 &= ~(BIT(11) | BIT(10));
|
/*==== [Switch bandwidth] ====*/
|
switch (bw) {
|
case CHANNEL_WIDTH_5:
|
case CHANNEL_WIDTH_10:
|
case CHANNEL_WIDTH_20:
|
if (bw == CHANNEL_WIDTH_5) {
|
/*ADC clock = 20M & WB ADC clock = 40M for BW5 */
|
halbb_set_reg(bb, adc_sel[path], 0x6000, 0x1);
|
halbb_set_reg(bb, wbadc_sel[path], 0x30, 0x0);
|
} else if (bw == CHANNEL_WIDTH_10) {
|
/*ADC clock = 40M & WB ADC clock = 80M for BW10 */
|
halbb_set_reg(bb, adc_sel[path], 0x6000, 0x2);
|
halbb_set_reg(bb, wbadc_sel[path], 0x30, 0x1);
|
} else if (bw == CHANNEL_WIDTH_20) {
|
/*ADC clock = 80M & WB ADC clock = 160M for BW20 */
|
halbb_set_reg(bb, adc_sel[path], 0x6000, 0x0);
|
halbb_set_reg(bb, wbadc_sel[path], 0x30, 0x2);
|
}
|
|
/*RF bandwidth */
|
//rf_reg18 |= (BIT(11) | BIT(10));
|
|
break;
|
case CHANNEL_WIDTH_40:
|
/*ADC clock = 80M & WB ADC clock = 160M for BW40 */
|
halbb_set_reg(bb, adc_sel[path], 0x6000, 0x0);
|
halbb_set_reg(bb, wbadc_sel[path], 0x30, 0x2);
|
|
/*RF bandwidth */
|
//rf_reg18 |= BIT(11);
|
|
break;
|
case CHANNEL_WIDTH_80:
|
/*ADC clock = 160M & WB ADC clock = 160M for BW40 */
|
halbb_set_reg(bb, adc_sel[path], 0x6000, 0x0);
|
halbb_set_reg(bb, wbadc_sel[path], 0x30, 0x2);
|
|
/*RF bandwidth */
|
//rf_reg18 |= BIT(10);
|
|
break;
|
default:
|
BB_WARNING("Fail to set ADC\n");
|
}
|
|
/*==== [Write RF register] ====*/
|
//Already Move to RF API
|
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success][bw_setting] ADC setting for Path-%d\n", path);
|
return true;
|
}
|
|
bool halbb_ctrl_bw_8852b(struct bb_info *bb, u8 pri_ch, enum channel_width bw,
|
enum phl_phy_idx phy_idx)
|
{
|
u32 rx_path_0 = 0x0;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
if (bb->is_disable_phy_api) {
|
BB_DBG(bb, DBG_PHY_CONFIG, "[%s] Disable PHY API\n", __func__);
|
return true;
|
}
|
|
/*==== Error handling ====*/
|
if (bw >= CHANNEL_WIDTH_MAX || (bw == CHANNEL_WIDTH_40 && pri_ch > 2) ||
|
(bw == CHANNEL_WIDTH_80 && pri_ch > 4)) {
|
BB_WARNING("Fail to switch bw(bw:%d, pri ch:%d)\n", bw,
|
pri_ch);
|
return false;
|
}
|
|
rx_path_0 = halbb_get_reg_cmn(bb, 0x49c4, 0xf,phy_idx);
|
|
/*==== Switch bandwidth ====*/
|
switch (bw) {
|
case CHANNEL_WIDTH_5:
|
case CHANNEL_WIDTH_10:
|
case CHANNEL_WIDTH_20:
|
if (bw == CHANNEL_WIDTH_5) {
|
/*RF_BW:[31:30]=0x0 */
|
halbb_set_reg_cmn(bb, 0x49C0, 0xC0000000, 0x0,
|
phy_idx);
|
/*small BW:[13:12]=0x1 */
|
halbb_set_reg_cmn(bb, 0x49C4, 0x3000, 0x1, phy_idx);
|
/*Pri ch:[11:8]=0x0 */
|
halbb_set_reg_cmn(bb, 0x49C4, 0xf00, 0x0, phy_idx);
|
/*Set RF mode at 3 */
|
halbb_set_reg_cmn(bb, 0x12ac, 0xfff000, 0x333, phy_idx);
|
halbb_set_reg_cmn(bb, 0x32ac, 0xfff000, 0x333, phy_idx);
|
/*ACI Detect:[16]=0x0 */
|
halbb_set_reg_cmn(bb, 0x4738, 0x10000, 0x0, phy_idx);
|
halbb_set_reg_cmn(bb, 0x4AA4, 0x10000, 0x0, phy_idx);
|
} else if (bw == CHANNEL_WIDTH_10) {
|
/*RF_BW:[31:30]=0x0 */
|
halbb_set_reg_cmn(bb, 0x49C0, 0xC0000000, 0x0,
|
phy_idx);
|
/*small BW:[13:12]=0x2 */
|
halbb_set_reg_cmn(bb, 0x49C4, 0x3000, 0x2, phy_idx);
|
/*Pri ch:[11:8]=0x0 */
|
halbb_set_reg_cmn(bb, 0x49C4, 0xf00, 0x0, phy_idx);
|
/*Set RF mode at 3 */
|
halbb_set_reg_cmn(bb, 0x12ac, 0xfff000, 0x333, phy_idx);
|
halbb_set_reg_cmn(bb, 0x32ac, 0xfff000, 0x333, phy_idx);
|
/*ACI Detect:[16]=0x0 */
|
halbb_set_reg_cmn(bb, 0x4738, 0x10000, 0x0, phy_idx);
|
halbb_set_reg_cmn(bb, 0x4AA4, 0x10000, 0x0, phy_idx);
|
} else if (bw == CHANNEL_WIDTH_20) {
|
/*RF_BW:[31:30]=0x0 */
|
halbb_set_reg_cmn(bb, 0x49C0, 0xC0000000, 0x0,
|
phy_idx);
|
/*small BW:[13:12]=0x0 */
|
halbb_set_reg_cmn(bb, 0x49C4, 0x3000, 0x0, phy_idx);
|
/*Pri ch:[11:8]=0x0 */
|
halbb_set_reg_cmn(bb, 0x49C4, 0xf00, 0x0, phy_idx);
|
/*Set RF mode at 3 */
|
halbb_set_reg_cmn(bb, 0x12ac, 0xfff000, 0x333, phy_idx);
|
halbb_set_reg_cmn(bb, 0x32ac, 0xfff000, 0x333, phy_idx);
|
/*ACI Detect:[16]=0x1 */
|
halbb_set_reg_cmn(bb, 0x4738, 0x10000, 0x1, phy_idx);
|
halbb_set_reg_cmn(bb, 0x4AA4, 0x10000, 0x1, phy_idx);
|
}
|
|
break;
|
case CHANNEL_WIDTH_40:
|
/*RF_BW:[31:30]=0x1 */
|
halbb_set_reg_cmn(bb, 0x49C0, 0xC0000000, 0x1, phy_idx);
|
/*small BW:[13:12]=0x0 */
|
halbb_set_reg_cmn(bb, 0x49C4, 0x3000, 0x0, phy_idx);
|
/*Pri ch:[11:8] */
|
halbb_set_reg_cmn(bb, 0x49C4, 0xf00, pri_ch, phy_idx);
|
/*Set RF mode at 3 */
|
halbb_set_reg_cmn(bb, 0x12ac, 0xfff000, 0x333, phy_idx);
|
halbb_set_reg_cmn(bb, 0x32ac, 0xfff000, 0x333, phy_idx);
|
/*CCK primary channel */
|
if (pri_ch == 1)
|
halbb_set_reg(bb, 0x237c, BIT(0), 1);
|
else
|
halbb_set_reg(bb, 0x237c, BIT(0), 0);
|
|
break;
|
case CHANNEL_WIDTH_80:
|
/*RF_BW:[31:30]=0x2 */
|
halbb_set_reg_cmn(bb, 0x49C0, 0xC0000000, 0x2, phy_idx);
|
/*small BW:[13:12]=0x0 */
|
halbb_set_reg_cmn(bb, 0x49C4, 0x3000, 0x0, phy_idx);
|
/*Pri ch:[11:8] */
|
halbb_set_reg_cmn(bb, 0x49C4, 0xf00, pri_ch, phy_idx);
|
/*Set RF mode at A */
|
if (bb->ic_sub_type == BB_IC_SUB_TYPE_8852B_8852BP){
|
halbb_set_reg_cmn(bb, 0x12ac, 0xfff000, 0x333, phy_idx);
|
halbb_set_reg_cmn(bb, 0x32ac, 0xfff000, 0x333, phy_idx);
|
} else {
|
halbb_set_reg_cmn(bb, 0x12ac, 0xfff000, 0xaaa, phy_idx);
|
halbb_set_reg_cmn(bb, 0x32ac, 0xfff000, 0xaaa, phy_idx);
|
}
|
|
break;
|
default:
|
BB_WARNING("Fail to switch bw (bw:%d, pri ch:%d)\n", bw,
|
pri_ch);
|
}
|
|
if (bb->ic_sub_type == BB_IC_SUB_TYPE_8852B_8852BT) {
|
/*============== [Path A] ==============*/
|
halbb_adc_cfg_8852bt(bb, bw, RF_PATH_A);
|
/*============== [Path B] ==============*/
|
halbb_adc_cfg_8852bt(bb, bw, RF_PATH_B);
|
} else {
|
/*============== [Path A] ==============*/
|
halbb_bw_setting_8852b(bb, bw, RF_PATH_A);
|
/*============== [Path B] ==============*/
|
halbb_bw_setting_8852b(bb, bw, RF_PATH_B);
|
}
|
|
/*============= RF mode (standby) setting for 1R chip =========== */
|
if (rx_path_0 == 0x1)
|
halbb_set_reg_cmn(bb, 0x32ac, 0xfff000, 0x111, phy_idx);
|
else if (rx_path_0 == 0x2)
|
halbb_set_reg_cmn(bb, 0x12ac, 0xfff000, 0x111, phy_idx);
|
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Switch BW Success] BW: %d for PHY%d\n", bw, phy_idx);
|
|
return true;
|
}
|
|
bool halbb_ch_setting_8852b(struct bb_info *bb, u8 central_ch, enum rf_path path,
|
bool *is_2g_ch)
|
{
|
u32 rf_reg18 = 0;
|
|
//*is_2g_ch = (central_ch <= 14) ? true : false;
|
//RF_18 R/W already move to RF API
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Success][ch_setting] CH: %d for Path-%d\n",
|
central_ch, path);
|
return true;
|
}
|
|
bool halbb_ctrl_ch_8852b(struct bb_info *bb, u8 central_ch, enum band_type band,
|
enum phl_phy_idx phy_idx)
|
{
|
u8 sco;
|
u16 central_freq;
|
bool is_2g_ch;
|
u8 ch_idx_encoded = 0;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
if (bb->is_disable_phy_api) {
|
BB_DBG(bb, DBG_PHY_CONFIG, "[%s] Disable PHY API\n", __func__);
|
return true;
|
}
|
/*==== Error handling ====*/
|
if (band != BAND_ON_6G) {
|
if ((central_ch > 14 && central_ch < 36) ||
|
(central_ch > 64 && central_ch < 100) ||
|
(central_ch > 144 && central_ch < 149) ||
|
central_ch > 177 ||
|
central_ch== 0) {
|
BB_WARNING("Invalid CH:%d for PHY%d\n", central_ch,
|
phy_idx);
|
return false;
|
}
|
} else {
|
if (central_ch > 253) {
|
BB_WARNING("Invalid 6G CH:%d for PHY%d\n", central_ch,
|
phy_idx);
|
return false;
|
}
|
}
|
|
is_2g_ch = (band == BAND_ON_24G) ? true : false;
|
|
/*============== [Path A] ==============*/
|
//halbb_ch_setting_8852b(bb, central_ch, RF_PATH_A, &is_2g_ch);
|
//------------- [Mode Sel - Path A] ------------//
|
if (is_2g_ch)
|
halbb_set_reg_cmn(bb, 0x4738, BIT(17), 1, phy_idx);
|
else
|
halbb_set_reg_cmn(bb, 0x4738, BIT(17), 0, phy_idx);
|
|
/*============== [Path B] ==============*/
|
|
//halbb_ch_setting_8852b(bb, central_ch, RF_PATH_B, &is_2g_ch);
|
//------------- [Mode Sel - Path B] ------------//
|
if (is_2g_ch)
|
halbb_set_reg_cmn(bb, 0x4AA4, BIT(17), 1, phy_idx);
|
else
|
halbb_set_reg_cmn(bb, 0x4AA4, BIT(17), 0, phy_idx);
|
|
/*==== [SCO compensate fc setting] ====*/
|
//sco_comp = halbb_sco_mapping_8852b(bb, central_ch);
|
central_freq = halbb_fc_mapping(bb, band, central_ch);
|
|
/*=== SCO compensate : (BIT(0) << 18) / central_ch ===*/
|
sco = (u8)HALBB_DIV((BIT(0) << 18) + (central_freq / 2), central_freq);
|
halbb_set_reg_cmn(bb, 0x49C0, 0x7f, sco, phy_idx);
|
|
/* === CCK Parameters === */
|
if (band != BAND_ON_6G) {
|
if (central_ch == 14) {
|
halbb_set_reg(bb, 0x2300, 0xffffff, 0x3b13ff);
|
halbb_set_reg(bb, 0x2304, 0xffffff, 0x1c42de);
|
halbb_set_reg(bb, 0x2308, 0xffffff, 0xfdb0ad);
|
halbb_set_reg(bb, 0x230c, 0xffffff, 0xf60f6e);
|
halbb_set_reg(bb, 0x2310, 0xffffff, 0xfd8f92);
|
halbb_set_reg(bb, 0x2314, 0xffffff, 0x2d011);
|
halbb_set_reg(bb, 0x2318, 0xffffff, 0x1c02c);
|
halbb_set_reg(bb, 0x231c, 0xffffff, 0xfff00a);
|
} else {
|
halbb_set_reg(bb, 0x2300, 0xffffff, 0x3d23ff);
|
halbb_set_reg(bb, 0x2304, 0xffffff, 0x29b354);
|
halbb_set_reg(bb, 0x2308, 0xffffff, 0xfc1c8);
|
halbb_set_reg(bb, 0x230c, 0xffffff, 0xfdb053);
|
halbb_set_reg(bb, 0x2310, 0xffffff, 0xf86f9a);
|
halbb_set_reg(bb, 0x2314, 0xffffff, 0xfaef92);
|
halbb_set_reg(bb, 0x2318, 0xffffff, 0xfe5fcc);
|
halbb_set_reg(bb, 0x231c, 0xffffff, 0xffdff5);
|
}
|
}
|
/* === Set Gain Error === */
|
halbb_set_gain_error_8852b(bb, central_ch);
|
/* === Set Efuse === */
|
halbb_set_efuse_8852b(bb, central_ch, HW_PHY_0);
|
/* === Set RXSC RPL Comp === */
|
halbb_set_rxsc_rpl_comp_8852b(bb, central_ch);
|
/* === Set Ch idx report in phy-sts === */
|
halbb_ch_idx_encode(bb, central_ch, band, &ch_idx_encoded);
|
halbb_set_reg_cmn(bb, 0x0734, 0x0ff0000, ch_idx_encoded, phy_idx);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Switch CH Success] CH: %d for PHY%d\n",
|
central_ch, phy_idx);
|
return true;
|
}
|
|
void halbb_ctrl_cck_en_8852b(struct bb_info *bb, bool cck_en,
|
enum phl_phy_idx phy_idx)
|
{
|
if (cck_en) {
|
//halbb_set_reg(bb, 0x2300, BIT(27), 0);
|
halbb_set_reg(bb, 0x700, BIT(5), 1);
|
halbb_set_reg(bb, 0x2344, BIT(31), 0);
|
} else {
|
//halbb_set_reg(bb, 0x2300, BIT(27), 1);
|
halbb_set_reg(bb, 0x700, BIT(5), 0);
|
halbb_set_reg(bb, 0x2344, BIT(31), 1);
|
}
|
BB_DBG(bb, DBG_PHY_CONFIG, "[CCK Enable for PHY%d]\n", phy_idx);
|
}
|
|
bool halbb_ctrl_bw_ch_8852b(struct bb_info *bb, u8 pri_ch, u8 central_ch,
|
enum channel_width bw, enum band_type band,
|
enum phl_phy_idx phy_idx)
|
{
|
bool rpt = true;
|
bool cck_en = false;
|
u8 pri_ch_idx = 0;
|
bool is_2g_ch;
|
|
is_2g_ch = (band == BAND_ON_24G) ? true : false;
|
/*==== [Set pri_ch idx] ====*/
|
if (band == BAND_ON_24G) {
|
#ifdef BANDEDGE_FILTER_CFG_FOR_ULOFDMA
|
/*==== [UL-OFDMA 2x 1p6 Tx WA] ====*/
|
halbb_set_reg(bb, 0x4498, BIT(30), 1);
|
#endif
|
// === 2G === //
|
switch (bw) {
|
case CHANNEL_WIDTH_20:
|
break;
|
|
case CHANNEL_WIDTH_40:
|
pri_ch_idx = pri_ch > central_ch ? 1 : 2;
|
break;
|
|
default:
|
break;
|
}
|
|
/*==== [CCK SCO Compesate] ====*/
|
rpt &= halbb_ctrl_sco_cck_8852b(bb, pri_ch);
|
|
cck_en = true;
|
} else {
|
// === 5G === //
|
switch (bw) {
|
case CHANNEL_WIDTH_20:
|
#ifdef BANDEDGE_FILTER_CFG_FOR_ULOFDMA
|
/*==== [UL-OFDMA 2x 1p6 Tx WA] ====*/
|
halbb_set_reg(bb, 0x4498, BIT(30), 1);
|
#endif
|
break;
|
|
case CHANNEL_WIDTH_40:
|
case CHANNEL_WIDTH_80:
|
if (pri_ch > central_ch)
|
pri_ch_idx = (pri_ch - central_ch) >> 1;
|
else
|
pri_ch_idx = ((central_ch - pri_ch) >> 1) + 1;
|
#ifdef BANDEDGE_FILTER_CFG_FOR_ULOFDMA
|
/*==== [UL-OFDMA 2x 1p6 Tx WA] ====*/
|
halbb_set_reg(bb, 0x4498, BIT(30), 0);
|
#endif
|
break;
|
|
default:
|
break;
|
}
|
cck_en = false;
|
}
|
|
/*==== [Switch CH] ====*/
|
rpt &= halbb_ctrl_ch_8852b(bb, central_ch, band, phy_idx);
|
/*==== [Switch BW] ====*/
|
rpt &= halbb_ctrl_bw_8852b(bb, pri_ch_idx, bw, phy_idx);
|
/*==== [CCK Enable / Disable] ====*/
|
halbb_ctrl_cck_en_8852b(bb, cck_en, phy_idx);
|
/*==== [Spur elimination] ====*/
|
//TBD
|
/*==== [BTG Ctrl] ====*/
|
if (phl_is_mp_mode(bb->phl_com)) {
|
if (is_2g_ch && ((bb->rx_path == RF_PATH_B) || (bb->rx_path == RF_PATH_AB)))
|
halbb_ctrl_btg_8852b(bb, true);
|
else
|
halbb_ctrl_btg_8852b(bb, false);
|
|
if (is_2g_ch)
|
halbb_ctrl_btc_preagc_8852b(bb, bb->bt_en);
|
else
|
halbb_ctrl_btc_preagc_8852b(bb, false);
|
}
|
|
/* Dynamic 5M Mask Setting */
|
halbb_5m_mask_8852b(bb, pri_ch_idx, bw, phy_idx);
|
|
/*==== [BB reset] ====*/
|
halbb_bb_reset_all_8852b(bb, phy_idx);
|
|
return rpt;
|
}
|
|
bool halbb_ctrl_rx_path_8852b(struct bb_info *bb, enum rf_path rx_path)
|
{
|
u32 ofdm_rx = 0x0;
|
|
ofdm_rx = (u32)rx_path;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
bb->rx_path = rx_path;
|
|
if (ofdm_rx == RF_PATH_A) {
|
halbb_set_reg(bb, 0x49C4, 0xf, 0x1);
|
/*==== 1rcca ====*/
|
halbb_set_reg(bb, 0x49C0, 0x3C000, 1);
|
halbb_set_reg(bb, 0x49C0, 0x3C0000, 1);
|
/*==== Rx HT nss_limit / mcs_limit ====*/
|
halbb_set_reg(bb, 0xd18, BIT(9) | BIT(8), 0);
|
halbb_set_reg(bb, 0xd18, BIT(22) | BIT(21), 0);
|
/*==== Rx HE n_user_max / tb_max_nss ====*/
|
halbb_set_reg(bb, 0xd80, 0x3fc0, 4);
|
halbb_set_reg(bb, 0xd80, BIT(16) | BIT(15) | BIT(14), 0);
|
halbb_set_reg(bb, 0xd80, BIT(25) | BIT(24) | BIT(23), 0);
|
|
} else if (ofdm_rx == RF_PATH_B) {
|
halbb_set_reg(bb, 0x49C4, 0xf, 0x2);
|
/*==== 1rcca ====*/
|
halbb_set_reg(bb, 0x49C0, 0x3C000, 0x2);
|
halbb_set_reg(bb, 0x49C0, 0x3C0000, 0x2);
|
/*==== Rx HT nss_limit / mcs_limit ====*/
|
halbb_set_reg(bb, 0xd18, BIT(9) | BIT(8), 0);
|
halbb_set_reg(bb, 0xd18, BIT(22) | BIT(21), 0);
|
/*==== Rx HE n_user_max / tb_max_nss ====*/
|
halbb_set_reg(bb, 0xd80, 0x3fc0, 4);
|
halbb_set_reg(bb, 0xd80, BIT(16) | BIT(15) | BIT(14), 0);
|
halbb_set_reg(bb, 0xd80, BIT(25) | BIT(24) | BIT(23), 0);
|
|
} else if (ofdm_rx == RF_PATH_AB) {
|
halbb_set_reg(bb, 0x49C4, 0xf, 0x3);
|
/*==== 1rcca ====*/
|
halbb_set_reg(bb, 0x49C0, 0x3C000, 0x3);
|
halbb_set_reg(bb, 0x49C0, 0x3C0000, 0x3);
|
/*==== Rx HT nss_limit / mcs_limit ====*/
|
halbb_set_reg(bb, 0xd18, BIT(9) | BIT(8), 1);
|
halbb_set_reg(bb, 0xd18, BIT(22) | BIT(21), 1);
|
/*==== Rx HE n_user_max / tb_max_nss ====*/
|
halbb_set_reg(bb, 0xd80, 0x3fc0, 4);
|
halbb_set_reg(bb, 0xd80, BIT(16) | BIT(15) | BIT(14), 1);
|
halbb_set_reg(bb, 0xd80, BIT(25) | BIT(24) | BIT(23), 1);
|
|
}
|
/*==== [Set Efuse] =====*/
|
halbb_set_efuse_8852b(bb, bb->hal_com->band[0].cur_chandef.center_ch, HW_PHY_0);
|
|
/* === [BTG setting] === */
|
if ((bb->hal_com->band[0].cur_chandef.band == BAND_ON_24G) && ((rx_path == RF_PATH_B) || (rx_path == RF_PATH_AB)))
|
halbb_ctrl_btg_8852b(bb, true);
|
else
|
halbb_ctrl_btg_8852b(bb, false);
|
|
/*==== [TSSI reset] ====*/
|
if (rx_path == RF_PATH_A) {
|
halbb_set_reg(bb, 0x58dc, BIT(31) | BIT(30), 0x1);
|
halbb_set_reg(bb, 0x58dc, BIT(31) | BIT(30), 0x3);
|
} else {
|
halbb_set_reg(bb, 0x78dc, BIT(31) | BIT(30), 0x1);
|
halbb_set_reg(bb, 0x78dc, BIT(31) | BIT(30), 0x3);
|
}
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Rx Success]RX_en=%x\n", rx_path);
|
return true;
|
|
}
|
|
bool halbb_ctrl_tx_path_8852b(struct bb_info *bb, enum rf_path tx_path)
|
{
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
/*==== [P-MAC] Path & Path_map Enable ====*/
|
halbb_set_reg_cmn(bb, 0x09a4, 0x1c, 0x7, HW_PHY_0);
|
halbb_set_reg_cmn(bb, 0x09a4, 0x1c, 0x7, HW_PHY_1);
|
|
|
if (tx_path == RF_PATH_A) {
|
halbb_set_reg(bb, 0x458C, 0xf0000000, 0x1);
|
halbb_set_reg(bb, 0x45B4, 0x1e0000, 0x0);
|
} else if (tx_path == RF_PATH_B) {
|
halbb_set_reg(bb, 0x458C, 0xf0000000, 0x2);
|
halbb_set_reg(bb, 0x45B4, 0x1e0000, 0x0);
|
} else if (tx_path == RF_PATH_AB) {
|
halbb_set_reg(bb, 0x458C, 0xf0000000, 0x3);
|
halbb_set_reg(bb, 0x45B4, 0x1e0000, 0x4);
|
} else {
|
BB_WARNING("Invalid Tx Path\n");
|
return false;
|
}
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Success] [P-MAC] Tx Path Config\n");
|
return true;
|
}
|
|
void halbb_ctrl_rf_mode_8852b(struct bb_info *bb, enum phl_rf_mode mode)
|
{
|
if (mode == RF_MODE_STANDBY) {
|
halbb_set_reg(bb, 0x12ac, 0xfffffff0, 0x1111111);
|
halbb_set_reg(bb, 0x12b0, 0xfff, 0x111);
|
halbb_set_reg(bb, 0x32ac, 0xfffffff0, 0x1111111);
|
halbb_set_reg(bb, 0x32b0, 0xfff, 0x111);
|
} else if (mode == RF_MODE_SHUTDOWN) {
|
halbb_set_reg(bb, 0x12ac, 0xfffffff0, 0x0);
|
halbb_set_reg(bb, 0x12b0, 0xfff, 0x0);
|
halbb_set_reg(bb, 0x32ac, 0xfffffff0, 0x0);
|
halbb_set_reg(bb, 0x32b0, 0xfff, 0x0);
|
} else {
|
halbb_set_reg(bb, 0x12ac, 0xfffffff0, 0x233302);
|
halbb_set_reg(bb, 0x12b0, 0xfff, 0x333);
|
halbb_set_reg(bb, 0x32ac, 0xfffffff0, 0x233302);
|
halbb_set_reg(bb, 0x32b0, 0xfff, 0x333);
|
}
|
BB_DBG(bb, DBG_PHY_CONFIG, "[RF Mode] Mode = %d", mode);
|
}
|
|
void halbb_ctrl_rf_mode_rx_path_8852b(struct bb_info *bb, enum rf_path rx_path)
|
{
|
|
// Rx RF mode config (1R & 2R)
|
if (rx_path == RF_PATH_A) {
|
halbb_set_reg(bb, 0x12ac, 0xfffffff0, 0x1233312);
|
halbb_set_reg(bb, 0x12b0, 0xfff, 0x333);
|
halbb_set_reg(bb, 0x32ac, 0xfffffff0, 0x1111111);
|
halbb_set_reg(bb, 0x32b0, 0xfff, 0x111);
|
} else if (rx_path == RF_PATH_B) {
|
halbb_set_reg(bb, 0x12ac, 0xfffffff0, 0x1111111);
|
halbb_set_reg(bb, 0x12b0, 0xfff, 0x111);
|
halbb_set_reg(bb, 0x32ac, 0xfffffff0, 0x1233312);
|
halbb_set_reg(bb, 0x32b0, 0xfff, 0x333);
|
} else if (rx_path == RF_PATH_AB) {
|
halbb_set_reg(bb, 0x12ac, 0xfffffff0, 0x1233312);
|
halbb_set_reg(bb, 0x12b0, 0xfff, 0x333);
|
halbb_set_reg(bb, 0x32ac, 0xfffffff0, 0x1233312);
|
halbb_set_reg(bb, 0x32b0, 0xfff, 0x333);
|
}
|
|
}
|
|
u16 halbb_cfg_cmac_tx_ant_8852b(struct bb_info *bb, enum rf_path tx_path)
|
{
|
// Return CMAC [OFST 20] Tx settings //
|
/* [19:16] path_en[3:0] ||
|
|| [21:20] map_a[1:0] ||
|
|| [23:22] map_b[1:0] ||
|
|| [25:24] map_c[1:0] ||
|
|| [27:26] map_d[1:0] ||
|
|| [28] ant_sel_a[0] ||
|
|| [29] ant_sel_b[0] ||
|
|| [30] ant_sel_c[0] ||
|
|| [31] ant_sel_d[0] */
|
u16 cmac_tx_info = 0;
|
|
if (tx_path == RF_PATH_A) {
|
cmac_tx_info = 0x1;
|
} else if (tx_path == RF_PATH_B) {
|
cmac_tx_info = 0x2;
|
} else if (tx_path == RF_PATH_AB) {
|
cmac_tx_info = 0x43;
|
} else {
|
cmac_tx_info = 0xffff;
|
BB_WARNING("Invalid Tx Path: %d\n", tx_path);
|
}
|
return cmac_tx_info;
|
|
}
|
|
void halbb_ctrl_trx_path_8852b(struct bb_info *bb, enum rf_path tx_path,
|
u8 tx_nss, enum rf_path rx_path, u8 rx_nss)
|
{
|
// Rx Config
|
halbb_ctrl_rx_path_8852b(bb, rx_path);
|
|
// RF mode config
|
halbb_ctrl_rf_mode_rx_path_8852b(bb, rx_path);
|
|
if ((rx_nss > 2) || (tx_nss > 2)) {
|
BB_WARNING("[Invalid Nss]Tx Nss: %d, Rx Nss: %d\n", tx_nss,
|
rx_nss);
|
return;
|
}
|
|
if (rx_nss == 1) {
|
/*==== [PHY0] Rx HT nss_limit / mcs_limit ====*/
|
halbb_set_reg(bb, 0xd18, BIT(9) | BIT(8), 0);
|
halbb_set_reg(bb, 0xd18, BIT(22) | BIT(21), 0);
|
/*==== [PHY0] Rx HE n_user_max / tb_max_nss ====*/
|
halbb_set_reg(bb, 0xd80, BIT(16) | BIT(15) | BIT(14), 0);
|
halbb_set_reg(bb, 0xd80, BIT(25) | BIT(24) | BIT(23), 0);
|
} else {
|
/*==== [PHY0] Rx HT nss_limit / mcs_limit ====*/
|
halbb_set_reg(bb, 0xd18, BIT(9) | BIT(8), 1);
|
halbb_set_reg(bb, 0xd18, BIT(22) | BIT(21), 1);
|
/*==== [PHY0] Rx HE n_user_max / tb_max_nss ====*/
|
halbb_set_reg(bb, 0xd80, BIT(16) | BIT(15) | BIT(14), 1);
|
halbb_set_reg(bb, 0xd80, BIT(25) | BIT(24) | BIT(23), 1);
|
}
|
|
// Tx Config (to do)
|
// Need to Add MP flag for Tx_path API since Normal Drv will also call this function
|
// ==== [T-MAC] Path & Path_map Enable ==== //
|
halbb_set_reg_cmn(bb, 0x09a4, 0x1c, 0x0, HW_PHY_0);
|
|
}
|
|
void halbb_ctrl_rx_cca_8852b(struct bb_info *bb, bool cca_en, enum phl_phy_idx phy_idx)
|
{
|
if (cca_en) {
|
halbb_set_reg_cmn(bb, 0xc3c, BIT(9), 0, phy_idx);
|
halbb_set_reg(bb, 0x2344, BIT(31), 0);
|
} else {
|
halbb_set_reg_cmn(bb, 0xc3c, BIT(9), 1, phy_idx);
|
halbb_set_reg(bb, 0x2344, BIT(31), 1);
|
}
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Rx CCA] CCA_EN = %d\n", cca_en);
|
}
|
|
void halbb_ctrl_ofdm_en_8852b(struct bb_info *bb, bool ofdm_en,
|
enum phl_phy_idx phy_idx)
|
{
|
if (ofdm_en)
|
halbb_set_reg_cmn(bb, 0x700, BIT(4), 1, phy_idx);
|
else
|
halbb_set_reg_cmn(bb, 0x700, BIT(4), 0, phy_idx);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[OFDM Enable for PHY%d]\n", phy_idx);
|
}
|
|
|
|
// =================== [Power Module] =================== //
|
bool halbb_set_txpwr_dbm_8852b(struct bb_info *bb, s16 power_dbm,
|
enum phl_phy_idx phy_idx)
|
{
|
bool tmp = false;
|
|
power_dbm &= 0x1ff;
|
halbb_set_reg_cmn(bb, 0x09a4, BIT(16), 1, phy_idx);
|
halbb_set_reg_cmn(bb, 0x4594, 0x7fc00000, power_dbm, phy_idx);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] Set Tx pwr(dBm) for [PHY-%d] : %d\n", phy_idx,
|
power_dbm);
|
tmp = true;
|
return tmp;
|
}
|
|
s16 halbb_get_txpwr_dbm_8852b(struct bb_info *bb, enum phl_phy_idx phy_idx)
|
{
|
u32 txpwr_dbm;
|
s16 output;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
txpwr_dbm = halbb_get_reg_cmn(bb, 0x4594, 0x7fc00000, phy_idx);
|
output = (s16)halbb_cnvrt_2_sign(txpwr_dbm, 9);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] Get Tx pwr(dBm) for [PHY-%d] : %d\n", phy_idx,
|
output);
|
return output;
|
}
|
|
s16 halbb_get_txinfo_txpwr_dbm_8852b(struct bb_info *bb)
|
{
|
u32 txpwr_dbm;
|
s16 output;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
txpwr_dbm = halbb_get_reg(bb, 0x1804, 0x7FC0000);
|
output = (s16)halbb_cnvrt_2_sign(txpwr_dbm, 9);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] Get TxInfo pwr(dBm) : %d\n", output);
|
return output;
|
}
|
|
bool halbb_set_cck_txpwr_idx_8852b(struct bb_info *bb, u16 power_idx,
|
enum rf_path tx_path)
|
{
|
u32 pwr_idx_addr[2] = {0x5808, 0x7808};
|
|
/*==== Power index Check ====*/
|
if ((power_idx & ~0x1ff) != 0) {
|
BB_WARNING("Power Idx: %x\n", power_idx);
|
return false;
|
}
|
/*==== Tx Path Check ====*/
|
if (tx_path > RF_PATH_B) {
|
BB_WARNING("Invalid Tx Path for CCK Txpwr_idx setting (52A)\n");
|
return false;
|
}
|
halbb_set_reg(bb, pwr_idx_addr[tx_path], 0x3fe00, power_idx);
|
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] [CCK] Set Tx pwr idx for [Path-%d] : %x\n",
|
tx_path, power_idx);
|
return true;
|
}
|
|
u16 halbb_get_cck_txpwr_idx_8852b(struct bb_info *bb, enum rf_path tx_path)
|
{
|
u16 cck_pwr_idx;
|
u32 pwr_idx_addr[2] = {0x5808, 0x7808};
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
cck_pwr_idx = (u16)halbb_get_reg(bb, pwr_idx_addr[tx_path], 0x3fe00);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] [CCK] Get Tx pwr idx for [Path-%d] : %x\n",
|
tx_path, cck_pwr_idx);
|
return cck_pwr_idx;
|
}
|
|
s16 halbb_get_cck_ref_dbm_8852b(struct bb_info *bb, enum rf_path tx_path)
|
{
|
u32 cck_ref_dbm;
|
u32 pwr_ref_addr[2] = {0x5808, 0x7808};
|
s16 output;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
cck_ref_dbm = halbb_get_reg(bb, pwr_ref_addr[tx_path], 0x1ff);
|
output = (s16)halbb_cnvrt_2_sign(cck_ref_dbm, 9);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] [CCK] Get Tx ref pwr(dBm) for [Path-%d] : %d\n",
|
tx_path, output);
|
return output;
|
}
|
|
bool halbb_set_ofdm_txpwr_idx_8852b(struct bb_info *bb, u16 power_idx,
|
enum rf_path tx_path)
|
{
|
u32 pwr_idx_addr[2] = {0x5804, 0x7804};
|
|
/*==== Power index Check ====*/
|
if ((power_idx & ~0x1ff) != 0) {
|
BB_WARNING("Power Idx: %x\n", power_idx);
|
return false;
|
}
|
/*==== Tx Path Check ====*/
|
if (tx_path > RF_PATH_B) {
|
BB_WARNING("Invalid Tx Path for CCK Txpwr_idx setting (52A)\n");
|
return false;
|
}
|
|
halbb_set_reg(bb, pwr_idx_addr[tx_path], 0x3fe00, power_idx);
|
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] [OFDM] Set Tx pwr idx for [Path-%d] : %x\n",
|
tx_path, power_idx);
|
return true;
|
}
|
|
u16 halbb_get_ofdm_txpwr_idx_8852b(struct bb_info *bb, enum rf_path tx_path)
|
{
|
u16 ofdm_pwr_idx;
|
u32 pwr_idx_addr[2] = {0x5804, 0x7804};
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
ofdm_pwr_idx = (u16)halbb_get_reg(bb, pwr_idx_addr[tx_path], 0x3fe00);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] [OFDM] Get Tx pwr idx for [Path-%d] : %x\n",
|
tx_path, ofdm_pwr_idx);
|
return ofdm_pwr_idx;
|
}
|
|
s16 halbb_get_ofdm_ref_dbm_8852b(struct bb_info *bb, enum rf_path tx_path)
|
{
|
u32 ofdm_ref_dbm;
|
u32 pwr_ref_addr[2] = {0x5804, 0x7804};
|
s16 output;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
ofdm_ref_dbm = halbb_get_reg(bb, pwr_ref_addr[tx_path], 0x1ff);
|
output = (s16)halbb_cnvrt_2_sign(ofdm_ref_dbm, 9);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] [OFDM] Get Tx ref pwr(dBm) for [Path-%d] : %d\n",
|
tx_path, output);
|
return output;
|
}
|
|
void halbb_reset_bb_hw_cnt_8852b(struct bb_info *bb)
|
{
|
|
/*@ Reset all counter*/
|
halbb_set_reg(bb, 0x730, BIT(0), 1);
|
halbb_set_reg(bb, 0x730, BIT(0), 0);
|
|
}
|
|
void halbb_backup_info_8852b(struct bb_info *bb, enum phl_phy_idx phy_idx)
|
{
|
/*==== This Backup info is for RF TSSI calibration =====*/
|
bb->bb_cmn_backup_i.cur_tx_path = (u8)halbb_get_reg_cmn(bb, 0x458c, 0xf0000000, phy_idx);
|
bb->bb_cmn_backup_i.cur_rx_path = (u8)halbb_get_reg_cmn(bb, 0x49c4, 0xf, phy_idx);
|
bb->bb_cmn_backup_i.cur_rfmode_a_12ac= (u32)halbb_get_reg_cmn(bb, 0x12ac, MASKDWORD, phy_idx);
|
bb->bb_cmn_backup_i.cur_rfmode_a_12b0= (u32)halbb_get_reg_cmn(bb, 0x12b0, MASKDWORD, phy_idx);
|
bb->bb_cmn_backup_i.cur_rfmode_b_32ac= (u32)halbb_get_reg_cmn(bb, 0x32ac, MASKDWORD, phy_idx);
|
bb->bb_cmn_backup_i.cur_rfmode_b_32b0= (u32)halbb_get_reg_cmn(bb, 0x32b0, MASKDWORD, phy_idx);
|
bb->bb_cmn_backup_i.cur_tx_pwr = halbb_get_txpwr_dbm_8852b(bb, phy_idx);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Backup Info] [PHY%d] Tx path = %x\n", phy_idx, bb->bb_cmn_backup_i.cur_tx_path);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Backup Info] [PHY%d] Tx pwr = %x\n", phy_idx, (u16)bb->bb_cmn_backup_i.cur_tx_pwr);
|
}
|
|
void halbb_restore_info_8852b(struct bb_info *bb, enum phl_phy_idx phy_idx)
|
{
|
/*==== This Restore info is for RF TSSI calibration =====*/
|
halbb_set_reg_cmn(bb, 0x458c, 0xf0000000, bb->bb_cmn_backup_i.cur_tx_path, phy_idx);
|
if (bb->bb_cmn_backup_i.cur_tx_path == 0x3) {
|
halbb_set_reg(bb, 0x45B4, 0x1e0000, 0x4);
|
} else {
|
halbb_set_reg(bb, 0x45B4, 0x1e0000, 0x0);
|
}
|
halbb_set_reg_cmn(bb, 0x49c4, 0xf, bb->bb_cmn_backup_i.cur_rx_path, phy_idx);
|
halbb_set_reg_cmn(bb, 0x12ac, MASKDWORD, bb->bb_cmn_backup_i.cur_rfmode_a_12ac, phy_idx);
|
halbb_set_reg_cmn(bb, 0x12b0, MASKDWORD, bb->bb_cmn_backup_i.cur_rfmode_a_12b0, phy_idx);
|
halbb_set_reg_cmn(bb, 0x32ac, MASKDWORD, bb->bb_cmn_backup_i.cur_rfmode_b_32ac, phy_idx);
|
halbb_set_reg_cmn(bb, 0x32b0, MASKDWORD, bb->bb_cmn_backup_i.cur_rfmode_b_32b0, phy_idx);
|
halbb_set_txpwr_dbm_8852b(bb, bb->bb_cmn_backup_i.cur_tx_pwr, phy_idx);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Restore Info] [PHY%d] Tx path = %x\n", phy_idx, bb->bb_cmn_backup_i.cur_tx_path);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Restore Info] [PHY%d] Tx pwr = %x\n", phy_idx, (u16)bb->bb_cmn_backup_i.cur_tx_pwr);
|
}
|
|
bool halbb_set_txsc_8852b(struct bb_info *bb, u8 txsc, enum phl_phy_idx phy_idx)
|
{
|
/*==== txsc Check ====*/
|
if ((txsc & ~0xf) != 0) {
|
BB_WARNING("TXSC: %x\n", txsc);
|
return false;
|
}
|
halbb_set_reg_cmn(bb, 0x45ac, 0x7800000, txsc, phy_idx);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] [P-MAC] TXSC for [PHY-%d] : %x\n", phy_idx,
|
txsc);
|
return true;
|
}
|
|
#if 0
|
void halbb_ctrl_btg_8852b(struct bb_info *bb, bool btg)
|
{
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
if (btg) {
|
// Path A
|
halbb_set_reg(bb, 0x466c, BIT(18) | BIT(17), 0x1);
|
// Path B
|
halbb_set_reg(bb, 0x4740, BIT(18) | BIT(17), 0x3);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[BT] Apply BTG Setting\n");
|
// Apply Grant BT by TMAC Setting
|
halbb_set_reg(bb, 0x980, 0x1e0000, 0x0);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[BT] Apply Grant BT by TMAC Setting\n");
|
} else {
|
// Path A
|
halbb_set_reg(bb, 0x466c, BIT(18) | BIT(17), 0x0);
|
// Path B
|
halbb_set_reg(bb, 0x4740, BIT(18) | BIT(17), 0x0);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[BT] Disable BTG Setting\n");
|
// Ignore Grant BT by PMAC Setting
|
halbb_set_reg(bb, 0x980, 0x1e0000, 0xf);
|
halbb_set_reg(bb, 0x980, 0x3c000000, 0x4);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[BT] Ignore Grant BT by PMAC Setting\n");
|
}
|
}
|
#endif
|
bool halbb_set_bss_color_8852b(struct bb_info *bb, u8 bss_color,
|
enum phl_phy_idx phy_idx)
|
{
|
/*==== BSS color Check ====*/
|
if ((bss_color & ~0x3f) != 0) {
|
BB_WARNING("BSS color: %x\n", bss_color);
|
return false;
|
}
|
//=== [Enable BSS color mapping] ===//
|
halbb_set_reg_cmn(bb, 0x43b0, BIT(28), 0x1, phy_idx);
|
halbb_set_reg_cmn(bb, 0x43b0, 0xfc00000, bss_color, phy_idx);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] [P-MAC] BSS Color for [PHY-%d] : %x\n", phy_idx,
|
bss_color);
|
return true;
|
}
|
|
bool halbb_set_sta_id_8852b(struct bb_info *bb, u16 sta_id,
|
enum phl_phy_idx phy_idx)
|
{
|
/*==== Station ID Check ====*/
|
if ((sta_id & ~0x7ff) != 0) {
|
BB_WARNING("Station ID: %x\n", sta_id);
|
return false;
|
}
|
//=== [Set Station ID] ===//
|
halbb_set_reg_cmn(bb, 0x43b0, 0x3ff800, sta_id, phy_idx);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Success] [P-MAC] Station ID for [PHY-%d] : %x\n", phy_idx,
|
sta_id);
|
|
return true;
|
}
|
|
void halbb_set_igi_8852b(struct bb_info *bb, u8 lna_idx, bool tia_idx,
|
u8 rxbb_idx, enum rf_path path)
|
{
|
u8 lna = 0;
|
bool tia = 0;
|
u8 rxbb = 0;
|
|
u32 lna_addr[2] = {0x472c, 0x4a80};
|
u32 tia_addr[2] = {0x473c, 0x4aa8};
|
u32 rxbb_addr[2] = {0x46a8, 0x4a5c};
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
halbb_set_reg(bb, lna_addr[path], 0x7000000, lna_idx);
|
halbb_set_reg(bb, tia_addr[path], BIT(9), tia_idx);
|
halbb_set_reg(bb, rxbb_addr[path], 0x7c00, rxbb_idx);
|
|
lna = (u8)halbb_get_reg(bb, lna_addr[path], BIT(26) | BIT(25) | BIT(24));
|
tia = (bool)halbb_get_reg(bb, tia_addr[path], BIT(9));
|
rxbb = (u8)halbb_get_reg(bb, rxbb_addr[path], 0x7c00);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[IGI] LNA for [Path-%d] : %d\n", path, lna);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[IGI] TIA for [Path-%d] : %d\n", path, tia);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[IGI] RxBB for [Path-%d] : %d\n", path, rxbb);
|
}
|
|
void halbb_set_tx_pow_ref_8852b(struct bb_info *bb, s16 pw_dbm_ofdm, /*s(9,2)*/
|
s16 pw_dbm_cck, s8 ofst,
|
u8 base_cw_0db, u16 tssi_16dBm_cw,
|
u16 *ofdm_cw, u16 *cck_cw,
|
enum phl_phy_idx phy_idx)
|
{
|
s16 rf_pw_cw = 0;
|
u32 pw_cw = 0;
|
u32 val = 0;
|
s16 pw_s10_3 = 0;
|
u32 tssi_ofst_cw = 0;
|
|
/*OFDM*/
|
pw_s10_3 = (pw_dbm_ofdm * 2) + (s16)(ofst) + (s16)(base_cw_0db * 8);
|
|
|
pw_cw = pw_s10_3;
|
rf_pw_cw = (pw_s10_3 & 0x1F8) >> 3;
|
|
if (rf_pw_cw > 63)
|
pw_cw = (63 << 3) | (pw_s10_3 & 0x7); /*upper bound (+24dBm)*/
|
else if (rf_pw_cw < 15)
|
pw_cw = (15 << 3) | (pw_s10_3 & 0x7); /*lower bound (-24dBm)*/
|
|
/* ===[Set TSSI Offset]===============================================*/
|
/*
|
172 = 300 - (55 - 39) * 8;
|
tssi_ofst_cw = tssi_16dBm_cw - (tx_pow_16dBm_ref_cw - tx_pow_ref_cw) * 8;
|
= tssi_16dBm_cw + tx_pow_ref * 8 - tx_pow_16dBm_ref * 8
|
*/
|
tssi_ofst_cw = (u32)((s16)tssi_16dBm_cw + (pw_dbm_ofdm * 2) - (16 * 8));
|
|
BB_DBG(bb, DBG_DBG_API, "[OFDM]tssi_ofst_cw=%d, rf_cw=0x%x, bb_cw=0x%x\n", tssi_ofst_cw, pw_cw >> 3, pw_cw & 0x7);
|
|
*ofdm_cw = (u16)pw_cw;
|
val = tssi_ofst_cw << 18 | pw_cw << 9 | (u32)(pw_dbm_ofdm & 0x1ff);
|
halbb_set_reg_cmn(bb, 0x5804, 0x7FFFFFF, val, phy_idx);
|
halbb_set_reg_cmn(bb, 0x7804, 0x7FFFFFF, val, phy_idx);
|
|
/*CCK*/
|
pw_s10_3 = (pw_dbm_cck * 2) + (s16)(ofst) + (s16)(base_cw_0db * 8);
|
|
pw_cw = pw_s10_3;
|
rf_pw_cw = (pw_s10_3 & 0x1F8) >> 3;
|
|
if (rf_pw_cw > 63)
|
pw_cw = (63 << 3) | (pw_s10_3 & 0x7); /*upper bound (+24dBm)*/
|
else if (rf_pw_cw < 15)
|
pw_cw = (15 << 3) | (pw_s10_3 & 0x7); /*lower bound (-24dBm)*/
|
|
/* ===[Set TSSI Offset]===============================================*/
|
/*
|
172 = 300 - (55 - 39) * 8;
|
tssi_ofst_cw = tssi_16dBm_cw - (tx_pow_16dBm_ref_cw - tx_pow_ref_cw) * 8;
|
= tssi_16dBm_cw + tx_pow_ref * 8 - tx_pow_16dBm_ref * 8
|
*/
|
tssi_ofst_cw = (u32)((s16)tssi_16dBm_cw + (pw_dbm_cck * 2) - (16 * 8));
|
|
BB_DBG(bb, DBG_DBG_API, "[CCK] tssi_ofst_cw=%d, rf_cw=0x%x, bb_cw=0x%x\n", tssi_ofst_cw, pw_cw >> 3, pw_cw & 0x7);
|
|
*cck_cw = (u16)pw_cw;
|
val = tssi_ofst_cw << 18 | pw_cw << 9 | (u32)(pw_dbm_cck & 0x1ff);
|
halbb_set_reg_cmn(bb, 0x5808, 0x7FFFFFF, val, phy_idx);
|
halbb_set_reg_cmn(bb, 0x7808, 0x7FFFFFF, val, phy_idx);
|
|
}
|
|
void halbb_dump_bb_reg_8852b(struct bb_info *bb, u32 *_used, char *output,
|
u32 *_out_len, bool dump_2_buff)
|
{
|
u32 i = 0, addr = 0;
|
u32 cr_start = 0, cr_end = 0;
|
u32 dump_cr_table[][2] = {{0x0000, 0x04FC},
|
{0x0600, 0x0DFC},
|
{0x1000, 0x10FC},
|
{0x1200, 0x13FC},
|
{0x1700, 0x20FC},
|
{0x2200, 0x24FC},
|
{0x3000, 0x30FC},
|
{0x3200, 0x33FC},
|
{0x3900, 0x4FFC},
|
{0x5600, 0x56FC},
|
{0x5800, 0x5CFC},
|
{0x7600, 0x76FC},
|
{0x7800, 0x7CFC},
|
{0xC000, 0xC1FC}};
|
u32 bb_wrapper_table[][2] = {{0xd200, 0xd6fc}};
|
u32 table_len = sizeof(dump_cr_table)/(sizeof(u32) * 2);
|
u32 bb_wrapper_len = sizeof(bb_wrapper_table)/(sizeof(u32) * 2);
|
u32 reg_val = 0;
|
|
BB_TRACE("BBCR: dump all ==>\n");
|
BB_TRACE("table_len=%d\n", table_len);
|
|
for (i = 0; i < table_len; i ++) {
|
if (dump_2_buff)
|
BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used,
|
"[%02d] Reg[0x%04x ~ 0x%04x]\n\n",
|
i, dump_cr_table[i][0], dump_cr_table[i][1]);
|
else
|
BB_TRACE("[%02d] Reg[0x%04x ~ 0x%04x]\n\n",
|
i, dump_cr_table[i][0], dump_cr_table[i][1]);
|
|
}
|
|
for (i = 0; i < table_len; i ++) {
|
cr_start = dump_cr_table[i][0];
|
cr_end = dump_cr_table[i][1];
|
for (addr = cr_start; addr <= cr_end; addr += 4) {
|
if (dump_2_buff)
|
BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used,
|
"0x%04x 0x%08x\n",
|
addr, halbb_get_reg(bb, addr, MASKDWORD));
|
else
|
BB_TRACE("0x%04x 0x%08x\n",
|
addr, halbb_get_reg(bb, addr, MASKDWORD));
|
}
|
}
|
|
BB_TRACE1(bb, "BB Wrapper[0]\n ======================================>");
|
|
for (i = 0; i < bb_wrapper_len; i ++) {
|
cr_start = bb_wrapper_table[i][0];
|
cr_end = bb_wrapper_table[i][1];
|
for (addr = cr_start; addr <= cr_end; addr += 4) {
|
rtw_hal_mac_get_pwr_reg(bb->hal_com, 0, addr, ®_val);
|
|
if (dump_2_buff)
|
BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used,
|
"0x%04x 0x%08x\n", addr, reg_val);
|
else
|
BB_TRACE1(bb, "0x%04x 0x%08x\n", addr, reg_val);
|
}
|
}
|
}
|
|
void halbb_dbgport_dump_all_8852b(struct bb_info *bb, u32 *_used, char *output,
|
u32 *_out_len)
|
{
|
const u32 dump_dbgport_table[][3] = {
|
{DBGPORT_IP_TD, 0x001, 0x026},
|
{DBGPORT_IP_TD, 0x200, 0x2ff},
|
{DBGPORT_IP_TD, 0xb01, 0xb27},
|
{DBGPORT_IP_RX_INNER, 0x0, 0x29},
|
{DBGPORT_IP_TX_INNER, 0x0, 0x8},
|
{DBGPORT_IP_OUTER, 0x0, 0xaa},
|
{DBGPORT_IP_OUTER, 0xc0, 0xc4},
|
{DBGPORT_IP_INTF, 0x0, 0x40},
|
{DBGPORT_IP_CCK, 0x0, 0x3e},
|
{DBGPORT_IP_BF, 0x0, 0x59},
|
{DBGPORT_IP_RX_OUTER, 0x00, 0x63},
|
{DBGPORT_IP_RX_OUTER, 0x90, 0x98},
|
{DBGPORT_IP_RX_OUTER, 0xc0, 0xc3},
|
{DBGPORT_IP_RX_OUTER, 0xe0, 0xe3}};
|
u32 table_len;
|
u32 dp = 0; /*debug port value*/
|
u8 i;
|
u32 j;
|
u32 dbg_start = 0, dbg_end = 0;
|
|
table_len = sizeof(dump_dbgport_table) / (sizeof(u32) * 3);
|
|
BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used,
|
"BB DBG Port: dump all ==>\n");
|
|
for (i = 0; i < table_len; i++) {
|
BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used,
|
"[%02d][IP=%02d] Dbgport[0x%03x ~ 0x%03x]\n",
|
i, dump_dbgport_table[i][0],
|
dump_dbgport_table[i][1], dump_dbgport_table[i][2]);
|
}
|
|
for (i = 0; i < table_len; i++) {
|
halbb_set_bb_dbg_port_ip(bb, dump_dbgport_table[i][0]);
|
dbg_start = dump_dbgport_table[i][1];
|
dbg_end = dump_dbgport_table[i][2];
|
for (j = dbg_start; j <= dbg_end; j ++) {
|
halbb_set_bb_dbg_port(bb, j);
|
dp = halbb_get_bb_dbg_port_val(bb);
|
BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used,
|
"[0x%02x, 0x%03x] = 0x%08x\n",
|
dump_dbgport_table[i][0], j, dp);
|
}
|
}
|
halbb_release_bb_dbg_port(bb);
|
}
|
|
void halbb_physts_brk_fail_pkt_rpt_8852b(struct bb_info *bb, bool enable,
|
enum phl_phy_idx phy_idx)
|
{
|
u32 val32 = (enable) ? 0 : 0x3;
|
|
halbb_set_reg_cmn(bb, 0x0738, 0xC, val32, phy_idx);
|
}
|
|
bool halbb_rf_write_bb_reg_8852b(struct bb_info *bb, u32 addr, u32 mask, u32 data)
|
{
|
u32 page = (addr & 0xff00) >> 8;
|
|
if (page != 0x0c && page != 0x20 && page != 0x2c &&
|
page != 0x58 && page != 0x78 &&
|
addr != 0x0700 && addr != 0x12a0 && addr != 0x12b8 &&
|
addr != 0x2320 && addr != 0x2700 &&
|
addr != 0x32a0 && addr != 0x32b8) {
|
return false;
|
}
|
|
halbb_set_reg(bb, addr, mask, data);
|
return true;
|
}
|
|
void halbb_pre_agc_en_8852b(struct bb_info *bb, bool enable)
|
{
|
u8 en = 0;
|
|
en = (enable == true) ? 1 : 0;
|
halbb_set_reg(bb, 0x4730, BIT(31), en);
|
halbb_set_reg(bb, 0x4A9C, BIT(31), en);
|
|
BB_DBG(bb, DBG_DBG_API, "PreAGC en: 0x4730C[31]=(0x%x),0x4A9C[31]=(0x%x)\n",
|
en, en);
|
}
|
|
s8 halbb_efuse_exchange_8852b(struct bb_info *bb, u8 value,
|
enum efuse_bit_mask mask)
|
{
|
s8 tmp = 0;
|
|
if (mask == LOW_MASK) {
|
tmp = value & 0xf;
|
|
if (tmp & BIT(3))
|
tmp = tmp | 0xf0;
|
} else {
|
tmp = (value & 0xf0) >> 4;
|
|
if (tmp & BIT(3))
|
tmp = tmp | 0xf0;
|
}
|
|
return tmp;
|
}
|
|
void halbb_ext_loss_avg_update_8852b(struct bb_info *bb)
|
{
|
struct bb_ch_info *ch = &bb->bb_ch_i;
|
struct bb_edcca_info *bb_edcca = &bb->bb_edcca_i;
|
struct bb_edcca_cr_info *cr = &bb->bb_edcca_i.bb_edcca_cr_i;
|
u64 tmp_linear = 0;
|
|
if (ch->ext_loss[0] == ch->ext_loss[1]) {
|
ch->ext_loss_avg = ch->ext_loss[0];
|
} else {
|
/* avg(a_db, b_db) = 10*log10((10^(a_db/10)+10^(b_db/10))/2) =*/
|
/* 10*log10((10^((a_db - b_db)/10)+1)/2)+b_db*/
|
/* a_db > b_db => a_db - b_db > 0*/
|
tmp_linear = halbb_db_2_linear((u32)DIFF_2(ch->ext_loss[0], ch->ext_loss[1])) + 1;
|
tmp_linear = tmp_linear >> 1;
|
tmp_linear = (tmp_linear + (1 << (FRAC_BITS - 1))) >> FRAC_BITS;
|
ch->ext_loss_avg = (s8)halbb_convert_to_db(tmp_linear);
|
ch->ext_loss_avg += MIN_2(ch->ext_loss[0], ch->ext_loss[1]);
|
}
|
|
/*edcca loss compensation*/
|
bb_edcca->pwrofst = MAX_2(((ch->ext_loss_avg + 2) / 4) + 16,
|
EDCCA_PWROFST_DEFAULT);
|
|
halbb_set_reg(bb, cr->r_pwrofst, cr->r_pwrofst_m, bb_edcca->pwrofst);
|
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Ext loss] path{avg, a, b}={%d, %d, %d}(0.25dB), edcca_pwrofst = %d dB\n",
|
ch->ext_loss_avg, bb->bb_ch_i.ext_loss[RF_PATH_A],
|
bb->bb_ch_i.ext_loss[RF_PATH_B], bb_edcca->pwrofst - 16);
|
}
|
|
void halbb_get_efuse_ofst_init_8852b(struct bb_info *bb)
|
{
|
struct bb_efuse_info *gain = &bb->bb_efuse_i;
|
u8 tmp_ofst;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
tmp_ofst = (u8)halbb_get_reg(bb, 0x49B0, 0xff);
|
bb->bb_efuse_i.efuse_ofst[HW_PHY_0] = (s8)halbb_cnvrt_2_sign(tmp_ofst, 8);
|
tmp_ofst = (u8)halbb_get_reg(bb, 0x4A00, 0xff);
|
bb->bb_efuse_i.efuse_ofst_tb[HW_PHY_0] = (s8)halbb_cnvrt_2_sign(tmp_ofst, 8);
|
}
|
|
void halbb_get_normal_efuse_init_8852b(struct bb_info *bb)
|
{
|
struct bb_efuse_info *gain = &bb->bb_efuse_i;
|
u8 tmp;
|
u32 check_tmp = 0, i, j;
|
u8 band_num = BB_EFUSE_BAND_NUM;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_2G_CCK, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][0] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][0] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_2G_OFMD, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][1] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][1] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_5GL, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][2] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][2] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_5GM, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][3] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][3] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_5GH, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][4] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][4] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
if (bb->ic_sub_type == BB_IC_SUB_TYPE_8852B_8852BP) {
|
band_num = BB_BAND_NUM_MAX + 1; // 6G
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_6GL1, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][5] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][5] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_6GL2, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][6] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][6] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_6GL3, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][7] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][7] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_6GM1, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][8] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][8] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_6GM2, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][9] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][9] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_6GM3, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][10] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][10] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_6GH1, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][11] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][11] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_efuse_get_info(bb, EFUSE_INFO_RF_RX_GAIN_K_A_6GH2, &tmp, 1);
|
gain->gain_offset[RF_PATH_A][12] = halbb_efuse_exchange_8852b(bb, tmp, HIGH_MASK);
|
gain->gain_offset[RF_PATH_B][12] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
}
|
|
for (i = 0; i < HALBB_MAX_PATH; i++) {
|
for (j = 0; j < band_num; j++) {
|
BB_DBG(bb, DBG_INIT, "[Efuse]gain->gain_offset[%d][%d]=0x%x\n", i, j, gain->gain_offset[i][j]);
|
if ((gain->gain_offset[i][j] & 0xf) == 0xf)
|
check_tmp++;
|
}
|
}
|
|
BB_DBG(bb, DBG_INIT, "[Efuse]check_tmp = %d\n", check_tmp);
|
BB_DBG(bb, DBG_INIT, "[Efuse]HALBB_MAX_PATH * BB_EFUSE_BAND_NUM = %d\n", HALBB_MAX_PATH * band_num);
|
|
if (check_tmp == HALBB_MAX_PATH * band_num)
|
bb->bb_efuse_i.normal_efuse_check = false;
|
else
|
bb->bb_efuse_i.normal_efuse_check = true;
|
/*
|
BB_DBG(bb, DBG_INIT,
|
"[Efuse][Gain 2G][CCK] Path-A: %d, Path-B: %d\n",
|
gain->gain_offset[RF_PATH_A][0], gain->gain_offset[RF_PATH_B][0]);
|
BB_DBG(bb, DBG_INIT,
|
"[Efuse][Gain 2G][OFDM] Path-A: %d, Path-B: %d\n",
|
gain->gain_offset[RF_PATH_A][1], gain->gain_offset[RF_PATH_B][1]);
|
BB_DBG(bb, DBG_INIT,
|
"[Efuse][Gain 5GL] Path-A: %d, Path-B: %d\n",
|
gain->gain_offset[RF_PATH_A][2], gain->gain_offset[RF_PATH_B][2]);
|
BB_DBG(bb, DBG_INIT,
|
"[Efuse][Gain 5GM] Path-A: %d, Path-B: %d\n",
|
gain->gain_offset[RF_PATH_A][3], gain->gain_offset[RF_PATH_B][3]);
|
BB_DBG(bb, DBG_INIT,
|
"[Efuse][Gain 5GH] Path-A: %d, Path-B: %d\n",
|
gain->gain_offset[RF_PATH_A][4], gain->gain_offset[RF_PATH_B][4]);
|
*/
|
}
|
|
void halbb_get_hide_efuse_init_8852b(struct bb_info *bb)
|
{
|
struct bb_efuse_info *gain = &bb->bb_efuse_i;
|
u8 tmp;
|
u8 band_num = BB_EFUSE_BAND_NUM;
|
u32 check_tmp = 0, i , j;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_2G_8852B, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][0] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_5GL_8852B, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][1] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_5GM_8852B, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][2] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_5GH_8852B, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][3] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_2G_8852B, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][0] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_5GL_8852B, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][1] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_5GM_8852B, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][2] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_5GH_8852B, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][3] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
if (bb->ic_sub_type == BB_IC_SUB_TYPE_8852B_8852BP) {
|
band_num = BB_BAND_NUM_MAX;
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_6GH_0_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][4] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_6GH_1_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][5] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_6GH_2_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][6] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_6GH_3_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][7] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_6GH_4_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][8] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_6GH_5_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][9] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_6GH_6_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][10] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_A_6GH_7_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_A][11] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_6GH_0_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][4] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_6GH_1_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][5] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_6GH_2_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][6] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_6GH_3_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][7] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_6GH_4_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][8] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_6GH_5_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][9] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_6GH_6_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][10] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
halbb_phy_efuse_get_info(bb, GAIN_HIDE_EFUSE_B_6GH_7_8852BP, 1, &tmp);
|
gain->gain_cs[RF_PATH_B][11] = halbb_efuse_exchange_8852b(bb, tmp, LOW_MASK);
|
|
}
|
|
|
for (i = 0; i < HALBB_MAX_PATH; i++) {
|
for (j = 0; j < band_num; j++) {
|
BB_DBG(bb, DBG_INIT, "[Efuse]gain->gain_cs[%d][%d]=0x%x\n", i, j, gain->gain_cs[i][j]);
|
if ((gain->gain_cs[i][j] & 0xf) == 0xf)
|
check_tmp++;
|
}
|
}
|
|
BB_DBG(bb, DBG_INIT, "[Efuse]check_tmp = %d\n", check_tmp);
|
BB_DBG(bb, DBG_INIT, "[Efuse]HALBB_MAX_PATH * BB_GAIN_BAND_NUM = %d\n", HALBB_MAX_PATH * band_num);
|
|
if (check_tmp == HALBB_MAX_PATH * band_num)
|
bb->bb_efuse_i.hidden_efuse_check = false;
|
else
|
bb->bb_efuse_i.hidden_efuse_check = true;
|
|
|
/*
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Hidden Efuse][Gain 2G][Path-A] CS: %d , %d, %x\n",
|
gain->gain_cs[RF_PATH_A][0],gain->gain_cs[RF_PATH_A][0]<<2,gain->gain_cs[RF_PATH_A][0]<<2);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Hidden Efuse][Gain 5GL][Path-A] CS: %d, %d, %x\n",
|
gain->gain_cs[RF_PATH_A][1],gain->gain_cs[RF_PATH_A][1]<<2,gain->gain_cs[RF_PATH_A][1]<<2);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Hidden Efuse][Gain 5GM][Path-A] CS: %d, %d, %x\n",
|
gain->gain_cs[RF_PATH_A][2],gain->gain_cs[RF_PATH_A][2]<<2,gain->gain_cs[RF_PATH_A][2]<<2);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Hidden Efuse][Gain 5GH][Path-A] CS: %d, %d, %x\n",
|
gain->gain_cs[RF_PATH_A][3],gain->gain_cs[RF_PATH_A][3]<<2,gain->gain_cs[RF_PATH_A][3]<<2);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Hidden Efuse][Gain 2G][Path-B] CS: %d\n",
|
gain->gain_cs[RF_PATH_B][0]);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Hidden Efuse][Gain 5GL][Path-B] CS: %d\n",
|
gain->gain_cs[RF_PATH_B][1]);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Hidden Efuse][Gain 5GM][Path-B] CS: %d\n",
|
gain->gain_cs[RF_PATH_B][2]);
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Hidden Efuse][Gain 5GH][Path-B] CS: %d\n",
|
gain->gain_cs[RF_PATH_B][3]);
|
*/
|
|
}
|
|
void halbb_set_efuse_8852b(struct bb_info *bb, u8 central_ch, enum phl_phy_idx phy_idx)
|
{
|
u8 band;
|
u8 gain_val = 0;
|
s32 hidden_efuse = 0, normal_efuse = 0, normal_efuse_cck = 0;
|
s32 normal_efuse_a = 0, normal_efuse_b = 0;
|
s32 tmp = 0;
|
u8 path = 0;
|
u32 gain_err_addr[2] = {0x4ACC, 0x4AD8}; //Wait for Bcut Def
|
u32 rssi_ofst_addr[2] = {0x4694, 0x4778};
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
// 2G Band: (0)
|
// 5G Band: (1):Low, (2): Mid, (3):High
|
if (bb->hal_com->band[0].cur_chandef.band != BAND_ON_6G) {
|
if (central_ch >= 0 && central_ch <= 14)
|
band = 0;
|
else if (central_ch >= 36 && central_ch <= 64)
|
band = 1;
|
else if (central_ch >= 100 && central_ch <= 144)
|
band = 2;
|
else if (central_ch >= 149 && central_ch <= 177)
|
band = 3;
|
else
|
band = 0;
|
} else {
|
/* 6G Band:
|
/ (4):BW160_0, (5):BW160_1 --> Low
|
/ (6):BW160_2, (7):BW160_3 --> Mid
|
/ (8):BW160_4, (9):BW160_5 --> High
|
/ (10):BW160_6, (11):BW160_7 --> Ultra-high
|
*/
|
if (central_ch >= 1 && central_ch <= 29)
|
band = 4;
|
else if (central_ch >= 33 && central_ch <= 61)
|
band = 5;
|
else if (central_ch >= 65 && central_ch <= 93)
|
band = 6;
|
else if (central_ch >= 97 && central_ch <= 125)
|
band = 7;
|
else if (central_ch >= 129 && central_ch <= 157)
|
band = 8;
|
else if (central_ch >= 161 && central_ch <= 189)
|
band = 9;
|
else if (central_ch >= 193 && central_ch <= 221)
|
band = 10;
|
else if (central_ch >= 225 && central_ch <= 253)
|
band = 11;
|
else
|
band = 4;
|
}
|
|
// === [Set hidden efuse] === //
|
if (bb->bb_efuse_i.hidden_efuse_check) {
|
for (path = RF_PATH_A; path < BB_PATH_MAX_8852B; path++) {
|
gain_val = bb->bb_efuse_i.gain_cs[path][band] << 2;
|
halbb_set_reg(bb, gain_err_addr[path], 0xff, gain_val);
|
|
}
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Efuse] Hidden efuse dynamic setting!!\n");
|
|
} else {
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Efuse] Values of hidden efuse are all 0xff, bypass dynamic setting!!\n");
|
}
|
|
// === [Set normal efuse] === //
|
if (bb->bb_efuse_i.normal_efuse_check) {
|
/*r_g_offset*/
|
normal_efuse_a = (-1) * bb->bb_efuse_i.gain_offset[RF_PATH_A][band + 1];
|
normal_efuse_b = (-1) * bb->bb_efuse_i.gain_offset[RF_PATH_B][band + 1];
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[Normal Efuse] normal_efuse_a=0x%x, normal_efuse_b=0x%x, efuse_ofst0x%x\n",
|
normal_efuse_a, normal_efuse_b,
|
bb->bb_efuse_i.efuse_ofst[HW_PHY_0]);
|
tmp = (-1) * ((normal_efuse_a << 2) + (bb->bb_efuse_i.efuse_ofst[HW_PHY_0] >> 2));
|
halbb_set_reg(bb, rssi_ofst_addr[RF_PATH_A], 0xff0000, (tmp & 0xff));
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[RSSI] addr=0x%x, bitmask=0xff0000, val=0x%x\n",
|
rssi_ofst_addr[RF_PATH_A], tmp);
|
tmp = (-1) * ((normal_efuse_b << 2) + (bb->bb_efuse_i.efuse_ofst[HW_PHY_0] >> 2));
|
halbb_set_reg(bb, rssi_ofst_addr[RF_PATH_B], 0xff0000, (tmp & 0xff));
|
BB_DBG(bb, DBG_PHY_CONFIG,
|
"[RSSI] addr=0x%x, bitmask=0xff0000, val=0x%x\n",
|
rssi_ofst_addr[RF_PATH_B], tmp);
|
|
if ((bb->rx_path == RF_PATH_A) || (bb->rx_path == RF_PATH_AB)) {
|
normal_efuse = bb->bb_efuse_i.gain_offset[RF_PATH_A][band + 1];
|
normal_efuse_cck = bb->bb_efuse_i.gain_offset[RF_PATH_A][0];
|
} else if (bb->rx_path == RF_PATH_B) {
|
normal_efuse = bb->bb_efuse_i.gain_offset[RF_PATH_B][band + 1];
|
normal_efuse_cck = bb->bb_efuse_i.gain_offset[RF_PATH_B][0];
|
}
|
normal_efuse *= (-1);
|
normal_efuse_cck *= (-1);
|
|
// OFDM normal efuse
|
// r_1_rpl_bias_comp
|
tmp = (normal_efuse << 4) + bb->bb_efuse_i.efuse_ofst[HW_PHY_0];
|
halbb_set_reg_cmn(bb, 0x49B0, 0xff, (tmp & 0xff), phy_idx);
|
// r_tb_rssi_bias_comp
|
tmp = (normal_efuse << 4) + bb->bb_efuse_i.efuse_ofst_tb[HW_PHY_0];
|
halbb_set_reg_cmn(bb, 0x4A00, 0xff, (tmp & 0xff), phy_idx);
|
// CCK normal efuse
|
if (band == 0) {
|
tmp = (normal_efuse_cck << 3) + (bb->bb_efuse_i.efuse_ofst[HW_PHY_0] >>1);
|
halbb_set_reg(bb, 0x23ac, 0x7f, (tmp & 0x7f));
|
}
|
|
/*ext_loss*/
|
bb->bb_ch_i.ext_loss[RF_PATH_A] = (s8)((normal_efuse_a << 2) +
|
(bb->bb_efuse_i.efuse_ofst[HW_PHY_0] >> 2));
|
bb->bb_ch_i.ext_loss[RF_PATH_B] = (s8)((normal_efuse_b << 2) +
|
(bb->bb_efuse_i.efuse_ofst[HW_PHY_0] >> 2));
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Efuse] Normal efuse dynamic setting!!\n");
|
} else {
|
/*ext_loss*/
|
bb->bb_ch_i.ext_loss[RF_PATH_A] = 0;
|
bb->bb_ch_i.ext_loss[RF_PATH_B] = 0;
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Efuse] Values of normal efuse are all 0xff, bypass dynamic setting!!\n");
|
}
|
|
halbb_ext_loss_avg_update_8852b(bb);
|
}
|
|
void halbb_set_gain_error_8852b(struct bb_info *bb, u8 central_ch)
|
{
|
struct bb_gain_info *gain = &bb->bb_gain_i;
|
|
u8 band;
|
u8 path = 0, lna_idx = 0, tia_idx = 0;
|
s32 tmp = 0;
|
u32 lna_gain_g[BB_PATH_MAX_8852B][7] = {{0x4678, 0x4678, 0x467C,
|
0x467C, 0x467C, 0x467C,
|
0x4680}, {0x475C, 0x475C,
|
0x4760, 0x4760, 0x4760,
|
0x4760, 0x4764}};
|
u32 lna_gain_a[BB_PATH_MAX_8852B][7] = {{0x45DC, 0x45DC, 0x4660,
|
0x4660, 0x4660, 0x4660,
|
0x4664}, {0x4740, 0x4740,
|
0x4744, 0x4744, 0x4744,
|
0x4744, 0x4748}};
|
u32 lna_gain_mask[7] = {0x00ff0000, 0xff000000, 0x000000ff,
|
0x0000ff00, 0x00ff0000, 0xff000000,
|
0x000000ff};
|
u32 tia_gain_g[BB_PATH_MAX_8852B][2] = {{0x4680, 0x4680}, {0x4764,
|
0x4764}};
|
u32 tia_gain_a[BB_PATH_MAX_8852B][2] = {{0x4664, 0x4664}, {0x4748,
|
0x4748}};
|
u32 tia_gain_mask[2] = {0x00ff0000, 0xff000000};
|
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
// 2G Band: (0)
|
// 5G Band: (1):Low, (2): Mid, (3):High
|
// 6G Band: (4):Low, (5): Mid, (6):High 7:(Ultra_High)
|
if (bb->hal_com->band[0].cur_chandef.band != BAND_ON_6G) {
|
if (central_ch >= 0 && central_ch <= 14)
|
band = 0;
|
else if (central_ch >= 36 && central_ch <= 64)
|
band = 1;
|
else if (central_ch >= 100 && central_ch <= 144)
|
band = 2;
|
else if (central_ch >= 149 && central_ch <= 177)
|
band = 3;
|
else
|
band = 0;
|
} else {
|
if (central_ch >=1 && central_ch <= 61)
|
band = 4;
|
else if (central_ch >= 65 && central_ch <= 125)
|
band = 5;
|
else if (central_ch >= 129 && central_ch <= 189)
|
band = 6;
|
else if (central_ch >= 193 && central_ch <= 233)
|
band = 7;
|
else
|
band = 4;
|
}
|
|
for (path = RF_PATH_A; path < BB_PATH_MAX_8852B; path++) {
|
for (lna_idx = 0; lna_idx < 7; lna_idx++) {
|
if (band == 0) {
|
tmp = gain->lna_gain[band][path][lna_idx];
|
halbb_set_reg(bb, lna_gain_g[path][lna_idx], lna_gain_mask[lna_idx], tmp);
|
} else {
|
tmp = gain->lna_gain[band][path][lna_idx];
|
halbb_set_reg(bb, lna_gain_a[path][lna_idx], lna_gain_mask[lna_idx], tmp);
|
}
|
}
|
|
for (tia_idx = 0; tia_idx < 2; tia_idx++) {
|
if (band == 0) {
|
tmp = gain->tia_gain[band][path][tia_idx];
|
halbb_set_reg(bb, tia_gain_g[path][tia_idx], tia_gain_mask[tia_idx], tmp);
|
} else {
|
tmp = gain->tia_gain[band][path][tia_idx];
|
halbb_set_reg(bb, tia_gain_a[path][tia_idx], tia_gain_mask[tia_idx], tmp);
|
}
|
}
|
}
|
|
}
|
|
void halbb_set_rxsc_rpl_comp_8852b(struct bb_info *bb, u8 central_ch)
|
{
|
struct bb_gain_info *gain = &bb->bb_gain_i;
|
u8 band;
|
u8 path = 0;
|
u8 i = 0;
|
u8 rxsc = 0;
|
s8 ofst = 0;
|
s8 bw20_avg = 0;
|
s8 bw40_avg = 0, bw40_avg_1 = 0, bw40_avg_2 = 0;
|
s8 bw80_avg = 0;
|
s8 bw80_avg_1 = 0, bw80_avg_2 = 0, bw80_avg_3 = 0, bw80_avg_4 = 0;
|
s8 bw80_avg_9 = 0, bw80_avg_10 = 0;
|
u32 tmp_val1 = 0, tmp_val2 = 0, tmp_val3 = 0;
|
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
if (bb->hal_com->band[0].cur_chandef.band != BAND_ON_6G) {
|
if (central_ch >= 0 && central_ch <= 14)
|
band = 0;
|
else if (central_ch >= 36 && central_ch <= 64)
|
band = 1;
|
else if (central_ch >= 100 && central_ch <= 144)
|
band = 2;
|
else if (central_ch >= 149 && central_ch <= 177)
|
band = 3;
|
else
|
band = 0;
|
} else {
|
if (central_ch >=1 && central_ch <= 61)
|
band = 4;
|
else if (central_ch >= 65 && central_ch <= 125)
|
band = 5;
|
else if (central_ch >= 129 && central_ch <= 189)
|
band = 6;
|
else if (central_ch >= 193 && central_ch <= 233)
|
band = 7;
|
else
|
band = 4;
|
}
|
//20M RPL
|
bw20_avg = (gain->rpl_ofst_20[band][RF_PATH_A] +
|
gain->rpl_ofst_20[band][RF_PATH_B]) >> 1;
|
tmp_val1 |= (((u32)bw20_avg & 0xff) << 8);
|
//40M RPL
|
bw40_avg = (gain->rpl_ofst_40[band][RF_PATH_A][0] +
|
gain->rpl_ofst_40[band][RF_PATH_B][0]) >> 1;
|
tmp_val1 |= (((u32)bw40_avg & 0xff) << 16);
|
bw40_avg_1 = (gain->rpl_ofst_40[band][RF_PATH_A][1] +
|
gain->rpl_ofst_40[band][RF_PATH_B][1]) >> 1;
|
tmp_val1 |= (((u32)bw40_avg_1 & 0xff) << 24);
|
|
bw40_avg_2 = (gain->rpl_ofst_40[band][RF_PATH_A][2] +
|
gain->rpl_ofst_40[band][RF_PATH_B][2]) >> 1;
|
tmp_val2 |= ((u32)bw40_avg_2 & 0xff);
|
//80M RPL
|
bw80_avg = (gain->rpl_ofst_80[band][RF_PATH_A][0] +
|
gain->rpl_ofst_80[band][RF_PATH_B][0]) >> 1;
|
tmp_val2 |= ((u32)(bw80_avg & 0xff) << 8);
|
bw80_avg_1 = (gain->rpl_ofst_80[band][RF_PATH_A][1] +
|
gain->rpl_ofst_80[band][RF_PATH_B][1]) >> 1;
|
tmp_val2 |= (((u32)bw80_avg_1 & 0xff) << 16);
|
bw80_avg_10 = (gain->rpl_ofst_80[band][RF_PATH_A][10] +
|
gain->rpl_ofst_80[band][RF_PATH_B][10]) >> 1;
|
tmp_val2 |= (((u32)bw80_avg_10 & 0xff) << 24);
|
|
bw80_avg_2 = (gain->rpl_ofst_80[band][RF_PATH_A][2] +
|
gain->rpl_ofst_80[band][RF_PATH_B][2]) >> 1;
|
tmp_val3 |= ((u32)bw80_avg_2 & 0xff);
|
bw80_avg_3 = (gain->rpl_ofst_80[band][RF_PATH_A][3] +
|
gain->rpl_ofst_80[band][RF_PATH_B][3]) >> 1;
|
tmp_val3 |= (((u32)bw80_avg_3 & 0xff) << 8);
|
bw80_avg_4 = (gain->rpl_ofst_80[band][RF_PATH_A][4] +
|
gain->rpl_ofst_80[band][RF_PATH_B][4]) >> 1;
|
tmp_val3 |= (((u32)bw80_avg_4 & 0xff) << 16);
|
bw80_avg_9 = (gain->rpl_ofst_80[band][RF_PATH_A][9] +
|
gain->rpl_ofst_80[band][RF_PATH_B][9]) >> 1;
|
tmp_val3 |= (((u32)bw80_avg_9 & 0xff) << 24);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[20M RPL] gain ofst = 0x%2x\n",
|
bw20_avg&0xff);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[40M RPL] gain ofst = 0x%2x, 0x%2x, 0x%2x\n",
|
bw40_avg&0xff, bw40_avg_1&0xff, bw40_avg_2&0xff);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[80M RPL] gain ofst = 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x, 0x%2x\n",
|
bw80_avg&0xff,bw80_avg_1&0xff,bw80_avg_2&0xff,bw80_avg_3&0xff,bw80_avg_4&0xff,bw80_avg_9&0xff,bw80_avg_10&0xff);
|
BB_DBG(bb, DBG_PHY_CONFIG, "tmp1 = 0x%x, tmp2 = 0x%x, tmp3 = 0x%x\n",
|
tmp_val1, tmp_val2, tmp_val3);
|
|
halbb_set_reg(bb, 0x49b0, 0xffffff00, tmp_val1 >> 8);
|
halbb_set_reg(bb, 0x4a00, 0xffffff00, tmp_val1 >> 8);
|
halbb_set_reg(bb, 0x49b4, MASKDWORD, tmp_val2);
|
halbb_set_reg(bb, 0x4a04, MASKDWORD, tmp_val2);
|
halbb_set_reg(bb, 0x49b8, MASKDWORD, tmp_val3);
|
halbb_set_reg(bb, 0x4a08, MASKDWORD, tmp_val3);
|
}
|
|
void halbb_normal_efuse_verify_8852b(struct bb_info *bb, s8 rx_gain_offset,
|
enum rf_path rx_path,
|
enum phl_phy_idx phy_idx)
|
{
|
s32 normal_efuse = 0;
|
s32 tmp = 0;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Normal Efuse] rx_gain_offset = %d\n",
|
rx_gain_offset);
|
|
rx_gain_offset *= (-1);
|
|
// === [Set normal efuse] === //
|
// r_1_rpl_bias_comp
|
tmp = (rx_gain_offset << 4) + bb->bb_efuse_i.efuse_ofst[HW_PHY_0];
|
halbb_set_reg_cmn(bb, 0x49B0, 0xff, (tmp & 0xff), phy_idx);
|
// r_tb_rssi_bias_comp
|
tmp = (rx_gain_offset << 4) + bb->bb_efuse_i.efuse_ofst_tb[HW_PHY_0];
|
halbb_set_reg_cmn(bb, 0x4A00, 0xff, (bb->bb_efuse_i.efuse_ofst_tb[HW_PHY_0] & 0xff), phy_idx);
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Normal Efuse] 0x49B0[7:0] = 0x%x\n",
|
halbb_get_reg(bb, 0x49B0, 0xff));
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Normal Efuse] 0x4A00[7:0] = 0x%x\n",
|
halbb_get_reg(bb, 0x4A00, 0xff));
|
|
}
|
|
void halbb_normal_efuse_verify_cck_8852b(struct bb_info *bb, s8 rx_gain_offset,
|
enum rf_path rx_path,
|
enum phl_phy_idx phy_idx)
|
{
|
s32 tmp = 0;
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "<====== %s ======>\n", __func__);
|
|
rx_gain_offset *= (-1);
|
tmp = (rx_gain_offset << 3) + (bb->bb_efuse_i.efuse_ofst[HW_PHY_0] >>1);
|
halbb_set_reg(bb, 0x23ac, 0x7f, (tmp & 0x7f));
|
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Normal Efuse] gain ofst = 0x%x\n",
|
rx_gain_offset);
|
BB_DBG(bb, DBG_PHY_CONFIG, "[Normal Efuse] 0x23ac[6:0] = 0x%x\n",
|
halbb_get_reg(bb, 0x23ac, 0x7f));
|
}
|
#endif
|