/****************************************************************************** * * 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" #ifdef HALBB_ANT_DIV_SUPPORT void halbb_antdiv_reset_training_stat(struct bb_info *bb) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_antdiv_rate_info *bb_rate_i = &bb_ant_div->bb_rate_i; struct bb_antdiv_evm_info *bb_evm_i = &bb_ant_div->bb_evm_i; struct bb_antdiv_rssi_info *bb_rssi_i = &bb_ant_div->bb_rssi_i; struct bb_antdiv_cn_info *bb_cn_i = &bb_ant_div->bb_cn_i; halbb_mem_set(bb, bb_rate_i, 0, sizeof(struct bb_antdiv_rate_info)); halbb_mem_set(bb, bb_cn_i, 0, sizeof(struct bb_antdiv_cn_info)); halbb_mem_set(bb, bb_evm_i, 0, sizeof(struct bb_antdiv_evm_info)); halbb_mem_set(bb, bb_rssi_i, 0, sizeof(struct bb_antdiv_rssi_info)); } void halbb_antdiv_reset(struct bb_info *bb) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_antdiv_rate_info *bb_rate_i = &bb_ant_div->bb_rate_i; struct bb_antdiv_evm_info *bb_evm_i = &bb_ant_div->bb_evm_i; /* Reset stat */ halbb_antdiv_reset_training_stat(bb); } void halbb_antdiv_reg_init(struct bb_info *bb) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_link_info *bb_link = &bb->bb_link_i; struct bb_antdiv_cr_info *cr = &bb->bb_ant_div_i.bb_antdiv_cr_i; /* dis r_ant_train_en */ halbb_set_reg_cmn(bb, cr->path0_r_ant_train_en, cr->path0_r_ant_train_en_m, 0x0, HW_PHY_0); /* force r_tx_ant_sel instead of from FW CMAC table */ halbb_set_reg_cmn(bb, cr->path0_r_antsel, BIT(1), 0x0, HW_PHY_0); #ifdef BB_8852A_CAV_SUPPORT /* r_trsw_tx_extend = 0us */ halbb_set_reg_cmn(bb, 0x828, 0xf, 0x0, HW_PHY_0); // CAV:0x8; CBV:0x27 JOE /* dis r_hw_antsw_dis_by_gnt_bt */ halbb_set_reg_cmn(bb, 0x828, BIT(12), 0x0, HW_PHY_0); // CAV:0x8; CBV:0x27 JOE #endif #ifdef HALBB_COMPILE_AP_SERIES /* r_trsw_tx_extend = 0us */ halbb_set_reg_cmn(bb, 0x2728, 0xf, 0x0, HW_PHY_0); // CAV:0x8; CBV:0x27 JOE /* dis r_hw_antsw_dis_by_gnt_bt */ halbb_set_reg_cmn(bb, 0x2728, BIT(12), 0x0, HW_PHY_0); // CAV:0x8; CBV:0x27 JOE #endif /* dis r_bt_force_en */ halbb_set_reg_cmn(bb, cr->path0_r_bt_force_antidx_en, cr->path0_r_bt_force_antidx_en_m, 0x0, HW_PHY_0); /* r_rfsw_ctrl_antenna (Antenna mapping) */ halbb_set_reg_cmn(bb, cr->path0_r_rfsw_ant_31_0, 0xFFFF, 0x0100, HW_PHY_0); /* dis r_BB_SEL_BTG_TRX_S */ halbb_set_reg_cmn(bb, cr->path0_r_antsel, BIT(21), 0x1, HW_PHY_0); /* "antsel" is controlled by HWs*/ halbb_set_reg_cmn(bb, cr->path0_r_antsel, BIT(16), 0x0, HW_PHY_0); /* r_ANT_DIV_SW_2G_S, 2G "CS/CG switching" is controlled by HWs */ halbb_set_reg_cmn(bb, cr->path0_r_antsel, BIT(23), 0x0, HW_PHY_0); /* r_ANT_DIV_SW_5G_S, 5G "CS/CG switching" is controlled by HWs */ halbb_set_reg_cmn(bb, cr->path0_r_antsel, BIT(25), 0x0, HW_PHY_0); } void halbb_antdiv_init(struct bb_info *bb) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_link_info *bb_link = &bb->bb_link_i; struct rtw_phl_com_t *phl = bb->phl_com; struct dev_cap_t *dev = &phl->dev_cap; if (dev->rfe_type != 50) return; /* HW reg. init to set mux & ctrler for antdiv */ halbb_antdiv_reg_init(bb); /* Mode setting*/ bb_ant_div->antdiv_mode = AUTO_ANT; bb_ant_div->pre_antdiv_mode = AUTO_ANT; bb_ant_div->antdiv_method = EVM_BASED_ANTDIV; bb_ant_div->tp_decision_method = TP_HIGHEST_DOMINATION; bb_ant_div->evm_decision_method = EVM_LINEAR_AVG; /* Algorithm parameter setting */ bb_ant_div->antdiv_period = ANTDIV_PERIOD; bb_ant_div->antdiv_train_num = ANTDIV_TRAINING_NUM; bb_ant_div->antdiv_delay = ANTDIV_DELAY; bb_ant_div->antdiv_intvl = ANTDIV_INTVL; bb_ant_div->tp_diff_th_high = ANTDIV_DEC_TP_HIGH; bb_ant_div->tp_diff_th_low = ANTDIV_DEC_TP_LOW; bb_ant_div->evm_diff_th = ANTDIV_DEC_EVM; bb_ant_div->tp_lb = TP_LOWER_BOUND; /* variable init */ bb_ant_div->antdiv_wd_cnt = 0; bb_ant_div->antdiv_training_state_cnt = 0; bb_ant_div->get_stats = false; bb_ant_div->antdiv_use_ctrl_frame = true; bb_ant_div->target_ant = ANTDIV_INIT; bb_ant_div->target_ant_evm = ANTDIV_INIT; bb_ant_div->target_ant_tp = ANTDIV_INIT; bb_ant_div->training_ant = ANTDIV_INIT; bb_ant_div->pre_target_ant = MAIN_ANT; halbb_antdiv_reset(bb); BB_DBG(bb, DBG_INIT, "Init ant_diversity timer"); } void halbb_antdiv_deinit(struct bb_info *bb) { #if 0 struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_antdiv_rate_info *bb_rate_i = &bb_ant_div->bb_rate_i; struct bb_antdiv_evm_info *bb_evm_i = &bb_ant_div->bb_evm_i; struct bb_antdiv_rssi_info *bb_rssi_i = &bb_ant_div->bb_rssi_i; struct bb_antdiv_cn_info *bb_cn_i = &bb_ant_div->bb_cn_i; if (&bb_rate_i) halbb_mem_free(bb, bb_rate_i, sizeof(struct bb_antdiv_rate_info)); if (&bb_cn_i) halbb_mem_free(bb, bb_cn_i, sizeof(struct bb_antdiv_cn_info)); if (&bb_evm_i) halbb_mem_free(bb, bb_evm_i, sizeof(struct bb_antdiv_evm_info)); if (&bb_rssi_i) halbb_mem_free(bb, bb_rssi_i, sizeof(struct bb_antdiv_rssi_info)); #endif } void halbb_antdiv_set_ant(struct bb_info *bb, u8 ant) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_link_info *bb_link = &bb->bb_link_i; struct bb_antdiv_cr_info *cr = &bb->bb_ant_div_i.bb_antdiv_cr_i; u8 band = bb->hal_com->band[0].cur_chandef.band; u8 default_ant, optional_ant; struct rtw_hal_com_t *hal = bb->hal_com; if ((bb_ant_div->pre_target_ant != ant) || (bb_ant_div->training_ant != ant) ) { BB_DBG(bb, DBG_ANT_DIV, "Set Antenna =%s\n", (ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"); if(ant == MAIN_ANT) { default_ant = ANT1_2G; optional_ant = ANT2_2G; } else { default_ant = ANT2_2G; optional_ant = ANT1_2G; } /* Original Rx antenna */ halbb_set_reg_cmn(bb, cr->path0_r_antsel, 0x20000, default_ant, HW_PHY_0); halbb_set_reg_cmn(bb, cr->path0_r_antsel, 0xf0, default_ant, HW_PHY_0); /* Alternative Rx antenna */ halbb_set_reg_cmn(bb, cr->path0_r_antsel, 0xf00, optional_ant, HW_PHY_0); /* Tx antenna, same as orig. rx ant. */ halbb_set_reg_cmn(bb, cr->path0_r_antsel, 0xf000, default_ant, HW_PHY_0); rtw_hal_rf_rx_ant(hal, ant); } else { BB_DBG(bb, DBG_ANT_DIV, "Stay in Ori-ant\n"); } } void halbb_antdiv_get_rssi(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_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_antdiv_rssi_info *rssi = &bb_ant_div->bb_rssi_i; struct bb_rate_info *rate_i = &cmn_rpt->bb_rate_i; rssi->rssi_cck_avg = (u8)HALBB_DIV(rssi->rssi_cck_avg_acc, rssi->pkt_cnt_cck); rssi->rssi_ofdm_avg = (u8)HALBB_DIV(rssi->rssi_ofdm_avg_acc, rssi->pkt_cnt_ofdm); rssi->rssi_t_avg = (u8)HALBB_DIV(rssi->rssi_t_avg_acc, rssi->pkt_cnt_t); if (rate_i->mode == BB_LEGACY_MODE) { if (cmn_rpt->is_cck_rate) { rssi->rssi_final = rssi->rssi_cck_avg; } else { rssi->rssi_final = rssi->rssi_ofdm_avg; } } else { rssi->rssi_final = rssi->rssi_t_avg; } } void halbb_antdiv_get_cn_target_ant(struct bb_info *bb) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_link_info *bb_link = &bb->bb_link_i; struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i; struct bb_rate_info *rate_i = &cmn_rpt->bb_rate_i; struct bb_antdiv_cn_info *bb_cn_i = &bb_ant_div->bb_cn_i; struct bb_antdiv_rate_info *bb_rate_i = &bb_ant_div->bb_rate_i; u32 main_cn, aux_cn; u8 target_ant_cn; /* CN */ main_cn = (u8)HALBB_DIV(bb_cn_i->main_cn_avg_acc, (bb_rate_i->main_pkt_cnt_t + bb_rate_i->main_pkt_cnt_ofdm)); aux_cn = (u8)HALBB_DIV(bb_cn_i->aux_cn_avg_acc, (bb_rate_i->aux_pkt_cnt_t+ bb_rate_i->aux_pkt_cnt_ofdm)); if (aux_cn == 0) target_ant_cn = MAIN_ANT; else if (main_cn == 0) target_ant_cn = AUX_ANT; else target_ant_cn = (main_cn == aux_cn) ? (bb_ant_div->pre_target_ant) : ((main_cn >= aux_cn) ? AUX_ANT : MAIN_ANT); BB_DBG(bb, DBG_ANT_DIV, "%-9s (%02d.%03d)\n", "[Main-Ant CN_avg]", (main_cn >> 1), halbb_show_fraction_num(main_cn & 0x1, 1)); BB_DBG(bb, DBG_ANT_DIV, "%-9s (%02d.%03d)\n", "[Aux-Ant CN_avg]", (aux_cn >> 1), halbb_show_fraction_num(aux_cn & 0x1, 1)); bb_ant_div->target_ant_cn = target_ant_cn; BB_DBG(bb, DBG_ANT_DIV, "CN based TargetAnt= [%s]\n", (bb_ant_div->target_ant_cn == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"); } void halbb_antdiv_get_highest_mcs(struct bb_info *bb) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_link_info *bb_link = &bb->bb_link_i; struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i; struct bb_rate_info *rate_i = &cmn_rpt->bb_rate_i; struct bb_antdiv_rate_info *bb_rate_i = &bb_ant_div->bb_rate_i; u16 main_max_cnt = 0; u16 aux_max_cnt = 0; u16 main_max_idx = 0; u16 aux_max_idx = 0; u8 ss_ofst = 0; u8 i; BB_DBG(bb, DBG_ANT_DIV, "*Main-Ant CCK cnt:{%d, %d, %d, %d}\n", bb_rate_i->main_pkt_cnt_legacy[0], bb_rate_i->main_pkt_cnt_legacy[1], bb_rate_i->main_pkt_cnt_legacy[2], bb_rate_i->main_pkt_cnt_legacy[3]); BB_DBG(bb, DBG_ANT_DIV, "*Aux-Ant CCK cnt:{%d, %d, %d, %d}\n", bb_rate_i->aux_pkt_cnt_legacy[0], bb_rate_i->aux_pkt_cnt_legacy[1], bb_rate_i->aux_pkt_cnt_legacy[2], bb_rate_i->aux_pkt_cnt_legacy[3]); BB_DBG(bb, DBG_ANT_DIV, "*Main-Ant OFDM cnt:{%d, %d, %d, %d, %d, %d, %d, %d}\n", bb_rate_i->main_pkt_cnt_legacy[4], bb_rate_i->main_pkt_cnt_legacy[5], bb_rate_i->main_pkt_cnt_legacy[6], bb_rate_i->main_pkt_cnt_legacy[7], bb_rate_i->main_pkt_cnt_legacy[8], bb_rate_i->main_pkt_cnt_legacy[9], bb_rate_i->main_pkt_cnt_legacy[10], bb_rate_i->main_pkt_cnt_legacy[11]); BB_DBG(bb, DBG_ANT_DIV, "*Aux-Ant OFDM cnt:{%d, %d, %d, %d, %d, %d, %d, %d}\n", bb_rate_i->aux_pkt_cnt_legacy[4], bb_rate_i->aux_pkt_cnt_legacy[5], bb_rate_i->aux_pkt_cnt_legacy[6], bb_rate_i->aux_pkt_cnt_legacy[7], bb_rate_i->aux_pkt_cnt_legacy[8], bb_rate_i->aux_pkt_cnt_legacy[9], bb_rate_i->aux_pkt_cnt_legacy[10], bb_rate_i->aux_pkt_cnt_legacy[11]); if ((bb_rate_i->main_he_pkt_not_zero == true) || (bb_rate_i->aux_he_pkt_not_zero == true)) { for (i = 0; i < HE_RATE_NUM; i++) { if (bb_ant_div->tp_decision_method == TP_MAX_DOMINATION) { if (bb_rate_i->main_pkt_cnt_he[i] >= main_max_cnt) { main_max_cnt = bb_rate_i->main_pkt_cnt_he[i]; main_max_idx = i; } if (bb_rate_i->aux_pkt_cnt_he[i] >= aux_max_cnt) { aux_max_cnt = bb_rate_i->aux_pkt_cnt_he[i]; aux_max_idx = i; } } else if (bb_ant_div->tp_decision_method == TP_HIGHEST_DOMINATION) { if (bb_rate_i->main_pkt_cnt_he[i] > 0) { main_max_cnt = bb_rate_i->main_pkt_cnt_he[i]; main_max_idx = i; } if (bb_rate_i->aux_pkt_cnt_he[i] > 0) { aux_max_cnt = bb_rate_i->aux_pkt_cnt_he[i]; aux_max_idx = i; } } } for (i = 0; i < bb->num_rf_path; i++) { ss_ofst = HE_VHT_NUM_MCS * i; BB_DBG(bb, DBG_ANT_DIV, "*Main-Ant HE %d-SS cnt:{%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n", (i + 1), bb_rate_i->main_pkt_cnt_he[ss_ofst + 0], bb_rate_i->main_pkt_cnt_he[ss_ofst + 1], bb_rate_i->main_pkt_cnt_he[ss_ofst + 2], bb_rate_i->main_pkt_cnt_he[ss_ofst + 3], bb_rate_i->main_pkt_cnt_he[ss_ofst + 4], bb_rate_i->main_pkt_cnt_he[ss_ofst + 5], bb_rate_i->main_pkt_cnt_he[ss_ofst + 6], bb_rate_i->main_pkt_cnt_he[ss_ofst + 7], bb_rate_i->main_pkt_cnt_he[ss_ofst + 8], bb_rate_i->main_pkt_cnt_he[ss_ofst + 9], bb_rate_i->main_pkt_cnt_he[ss_ofst + 10], bb_rate_i->main_pkt_cnt_he[ss_ofst + 11]); BB_DBG(bb, DBG_ANT_DIV, "*Aux-Ant HE %d-SS cnt:{%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n", (i + 1), bb_rate_i->aux_pkt_cnt_he[ss_ofst + 0], bb_rate_i->aux_pkt_cnt_he[ss_ofst + 1], bb_rate_i->aux_pkt_cnt_he[ss_ofst + 2], bb_rate_i->aux_pkt_cnt_he[ss_ofst + 3], bb_rate_i->aux_pkt_cnt_he[ss_ofst + 4], bb_rate_i->aux_pkt_cnt_he[ss_ofst + 5], bb_rate_i->aux_pkt_cnt_he[ss_ofst + 6], bb_rate_i->aux_pkt_cnt_he[ss_ofst + 7], bb_rate_i->aux_pkt_cnt_he[ss_ofst + 8], bb_rate_i->aux_pkt_cnt_he[ss_ofst + 9], bb_rate_i->aux_pkt_cnt_he[ss_ofst + 10], bb_rate_i->aux_pkt_cnt_he[ss_ofst + 11]); } } else if ((bb_rate_i->main_vht_pkt_not_zero == true) || (bb_rate_i->aux_vht_pkt_not_zero == true)) { for (i = 0; i < VHT_RATE_NUM; i++) { if (bb_ant_div->tp_decision_method == TP_MAX_DOMINATION) { if (bb_rate_i->main_pkt_cnt_vht[i] >= main_max_cnt) { main_max_cnt = bb_rate_i->main_pkt_cnt_vht[i]; main_max_idx = i; } if (bb_rate_i->aux_pkt_cnt_vht[i] >= aux_max_cnt) { aux_max_cnt = bb_rate_i->aux_pkt_cnt_vht[i]; aux_max_idx = i; } } else if (bb_ant_div->tp_decision_method == TP_HIGHEST_DOMINATION) { if (bb_rate_i->main_pkt_cnt_vht[i] > 0) { main_max_cnt = bb_rate_i->main_pkt_cnt_vht[i]; main_max_idx = i; } if (bb_rate_i->aux_pkt_cnt_vht[i] > 0) { aux_max_cnt = bb_rate_i->aux_pkt_cnt_vht[i]; aux_max_idx = i; } } } for (i = 0; i < bb->num_rf_path; i++) { ss_ofst = HE_VHT_NUM_MCS * i; BB_DBG(bb, DBG_ANT_DIV, "*Main-Ant VHT %d-SS cnt:{%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n", (i + 1), bb_rate_i->main_pkt_cnt_vht[ss_ofst + 0], bb_rate_i->main_pkt_cnt_vht[ss_ofst + 1], bb_rate_i->main_pkt_cnt_vht[ss_ofst + 2], bb_rate_i->main_pkt_cnt_vht[ss_ofst + 3], bb_rate_i->main_pkt_cnt_vht[ss_ofst + 4], bb_rate_i->main_pkt_cnt_vht[ss_ofst + 5], bb_rate_i->main_pkt_cnt_vht[ss_ofst + 6], bb_rate_i->main_pkt_cnt_vht[ss_ofst + 7], bb_rate_i->main_pkt_cnt_vht[ss_ofst + 8], bb_rate_i->main_pkt_cnt_vht[ss_ofst + 9], bb_rate_i->main_pkt_cnt_vht[ss_ofst + 10], bb_rate_i->main_pkt_cnt_vht[ss_ofst + 11]); BB_DBG(bb, DBG_ANT_DIV, "*Aux-Ant VHT %d-SS cnt:{%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d}\n", (i + 1), bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 0], bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 1], bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 2], bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 3], bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 4], bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 5], bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 6], bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 7], bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 8], bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 9], bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 10], bb_rate_i->aux_pkt_cnt_vht[ss_ofst + 11]); } } else if ((bb_rate_i->main_ht_pkt_not_zero == true) || (bb_rate_i->aux_ht_pkt_not_zero == true)) { for (i = 0; i < HT_RATE_NUM; i++) { if (bb_ant_div->tp_decision_method == TP_MAX_DOMINATION) { if (bb_rate_i->main_pkt_cnt_ht[i] >= main_max_cnt) { main_max_cnt = bb_rate_i->main_pkt_cnt_ht[i]; main_max_idx = i; } if (bb_rate_i->aux_pkt_cnt_ht[i] >= aux_max_cnt) { aux_max_cnt = bb_rate_i->aux_pkt_cnt_ht[i]; aux_max_idx = i; } } else if (bb_ant_div->tp_decision_method == TP_HIGHEST_DOMINATION) { if (bb_rate_i->main_pkt_cnt_ht[i] > 0) { main_max_cnt = bb_rate_i->main_pkt_cnt_ht[i]; main_max_idx = i; } if (bb_rate_i->aux_pkt_cnt_ht[i] > 0) { aux_max_cnt = bb_rate_i->aux_pkt_cnt_ht[i]; aux_max_idx = i; } } } for (i = 0; i < bb->num_rf_path; i++) { ss_ofst = (i << 3); BB_DBG(bb, DBG_ANT_DIV, "*HT%02d:%02d cnt:{%d, %d, %d, %d, %d, %d, %d, %d}\n", (ss_ofst), (ss_ofst + 7), bb_rate_i->main_pkt_cnt_ht[ss_ofst + 0], bb_rate_i->main_pkt_cnt_ht[ss_ofst + 1], bb_rate_i->main_pkt_cnt_ht[ss_ofst + 2], bb_rate_i->main_pkt_cnt_ht[ss_ofst + 3], bb_rate_i->main_pkt_cnt_ht[ss_ofst + 4], bb_rate_i->main_pkt_cnt_ht[ss_ofst + 5], bb_rate_i->main_pkt_cnt_ht[ss_ofst + 6], bb_rate_i->main_pkt_cnt_ht[ss_ofst + 7]); BB_DBG(bb, DBG_ANT_DIV, "*HT%02d:%02d cnt:{%d, %d, %d, %d, %d, %d, %d, %d}\n", (ss_ofst), (ss_ofst + 7), bb_rate_i->aux_pkt_cnt_ht[ss_ofst + 0], bb_rate_i->aux_pkt_cnt_ht[ss_ofst + 1], bb_rate_i->aux_pkt_cnt_ht[ss_ofst + 2], bb_rate_i->aux_pkt_cnt_ht[ss_ofst + 3], bb_rate_i->aux_pkt_cnt_ht[ss_ofst + 4], bb_rate_i->aux_pkt_cnt_ht[ss_ofst + 5], bb_rate_i->aux_pkt_cnt_ht[ss_ofst + 6], bb_rate_i->aux_pkt_cnt_ht[ss_ofst + 7]); } } /* Compute all throughput*/ if (bb_ant_div->tp_decision_method == TP_AVG_DOMINATION) { BB_DBG(bb, DBG_ANT_DIV, "Main_tp = %lld, Aux_tp = %lld\n", bb_rate_i->main_tp, bb_rate_i->aux_tp); if (bb_rate_i->main_tp > bb_rate_i->aux_tp) { bb_ant_div->target_ant_tp = MAIN_ANT; bb_rate_i->tp_diff = bb_rate_i->main_tp - bb_rate_i->aux_tp; } else if (bb_rate_i->main_tp < bb_rate_i->aux_tp) { bb_ant_div->target_ant_tp = AUX_ANT; bb_rate_i->tp_diff = bb_rate_i->aux_tp - bb_rate_i->main_tp; } else { bb_ant_div->target_ant_tp = bb_ant_div->pre_target_ant; bb_rate_i->no_change_flag = true; BB_DBG(bb, DBG_ANT_DIV, "TP based TargetAnt= Pre-TargetAnt\n"); } BB_DBG(bb, DBG_ANT_DIV, "MCS based TargetAnt= [%s]\n", (bb_ant_div->target_ant_tp == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"); BB_DBG(bb, DBG_ANT_DIV, "TP Confidence= [%lld]\n", bb_rate_i->tp_diff); return; } bb_rate_i->main_max_cnt = main_max_cnt; bb_rate_i->main_max_idx = main_max_idx; bb_rate_i->aux_max_cnt = aux_max_cnt; bb_rate_i->aux_max_idx = aux_max_idx; /* Decision Tput based target ant using MCS rate instead of phy data rate */ if ((main_max_cnt > bb_ant_div->tp_lb) || (aux_max_cnt > bb_ant_div->tp_lb)) { if (main_max_idx > aux_max_idx) { bb_ant_div->target_ant_tp = MAIN_ANT; bb_rate_i->tp_diff = 100; } else if (main_max_idx < aux_max_idx) { bb_ant_div->target_ant_tp = AUX_ANT; bb_rate_i->tp_diff = 100; } else { if (main_max_cnt > aux_max_cnt) bb_ant_div->target_ant_tp = MAIN_ANT; else if (main_max_cnt < aux_max_cnt) bb_ant_div->target_ant_tp = AUX_ANT; else { bb_ant_div->target_ant_tp = bb_ant_div->pre_target_ant; bb_rate_i->no_change_flag = true; } /* Calc. TP confidence*/ bb_rate_i->tp_diff = DIFF_2(main_max_cnt, aux_max_cnt); } } else { bb_ant_div->target_ant_tp = bb_ant_div->pre_target_ant; bb_rate_i->no_change_flag = true; BB_DBG(bb, DBG_ANT_DIV, "MCS based TargetAnt= Pre-TargetAnt\n"); } if (bb_rate_i->no_change_flag == true) bb_rate_i->tp_diff = 0; if (bb_rate_i->tp_diff > 100) bb_rate_i->tp_diff = 100; BB_DBG(bb, DBG_ANT_DIV, "MCS based TargetAnt= [%s]\n", (bb_ant_div->target_ant_tp == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"); BB_DBG(bb, DBG_ANT_DIV, "TP Confidence= [%lld]\n", bb_rate_i->tp_diff); } void halbb_antdiv_get_evm_target_ant(struct bb_info *bb) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_link_info *bb_link = &bb->bb_link_i; struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i; struct bb_rate_info *rate_i = &cmn_rpt->bb_rate_i; struct bb_antdiv_evm_info *bb_evm_i = &bb_ant_div->bb_evm_i; struct bb_antdiv_rate_info *bb_rate_i = &bb_ant_div->bb_rate_i; u8 main_2ss_evm_min = 0; u8 aux_2ss_evm_min = 0; //u8 main_2ss_evm_avg, aux_2ss_evm_avg; u8 main_1ss_evm = 0; u8 aux_1ss_evm = 0; u8 target_ant_evm_1ss, target_ant_evm_2ss; u8 decision_evm_ss; u8 evm_diff_1ss, evm_diff_2ss; bool no_change_flag_1ss = false; bool no_change_flag_2ss = false; /* 1ss EVM */ if (bb_ant_div->evm_decision_method == EVM_LINEAR_AVG) { /* Modify db to linear (*10)*/ bb_evm_i->main_evm_1ss = HALBB_DIV(bb_evm_i->main_evm_1ss, 10); bb_evm_i->aux_evm_1ss = HALBB_DIV(bb_evm_i->aux_evm_1ss, 10); main_1ss_evm = (u8)halbb_convert_to_db(HALBB_DIV(bb_evm_i->main_evm_1ss, (u64)(bb_rate_i->main_pkt_cnt_1ss + bb_rate_i->main_pkt_cnt_ofdm))); aux_1ss_evm = (u8)halbb_convert_to_db(HALBB_DIV(bb_evm_i->aux_evm_1ss, (u64)(bb_rate_i->aux_pkt_cnt_1ss + bb_rate_i->aux_pkt_cnt_ofdm))); main_1ss_evm = main_1ss_evm << 2; aux_1ss_evm = aux_1ss_evm << 2; } else { main_1ss_evm = (u8)HALBB_DIV(bb_evm_i->main_evm_1ss, (u64)(bb_rate_i->main_pkt_cnt_1ss + bb_rate_i->main_pkt_cnt_ofdm)); aux_1ss_evm = (u8)HALBB_DIV(bb_evm_i->aux_evm_1ss, (u64)(bb_rate_i->aux_pkt_cnt_1ss + bb_rate_i->aux_pkt_cnt_ofdm)); } target_ant_evm_1ss = (main_1ss_evm == aux_1ss_evm) ? (bb_ant_div->pre_target_ant) : ((main_1ss_evm >= aux_1ss_evm) ? MAIN_ANT : AUX_ANT); if (main_1ss_evm == aux_1ss_evm) { target_ant_evm_1ss = bb_ant_div->pre_target_ant; no_change_flag_1ss = true; } else if (main_1ss_evm > aux_1ss_evm) { target_ant_evm_1ss = MAIN_ANT; } else { target_ant_evm_1ss = AUX_ANT; } /* Calc. EVM confindece*/ evm_diff_1ss = DIFF_2(main_1ss_evm, aux_1ss_evm); BB_DBG(bb, DBG_ANT_DIV, "%-9s (%02d.%03d)\n", "[Main-Ant 1ss-EVM_avg]", (main_1ss_evm >> 2), halbb_show_fraction_num(main_1ss_evm & 0x3, 2)); BB_DBG(bb, DBG_ANT_DIV, "%-9s (%02d.%03d)\n", "[Aux-Ant 1ss-EVM_avg]", (aux_1ss_evm >> 2), halbb_show_fraction_num(aux_1ss_evm & 0x3, 2)); /* 2ss EVM */ if ((bb_rate_i->main_pkt_cnt_2ss + bb_rate_i->aux_pkt_cnt_2ss) != 0) { if (bb_ant_div->evm_decision_method == EVM_LINEAR_AVG) { bb_evm_i->main_evm_min_acc = HALBB_DIV(bb_evm_i->main_evm_min_acc, 10); bb_evm_i->aux_evm_min_acc = HALBB_DIV(bb_evm_i->aux_evm_min_acc, 10); main_2ss_evm_min = (u8)halbb_convert_to_db(HALBB_DIV(bb_evm_i->main_evm_min_acc, (u64)bb_rate_i->main_pkt_cnt_2ss)); aux_2ss_evm_min = (u8)halbb_convert_to_db(HALBB_DIV(bb_evm_i->aux_evm_min_acc, (u64)bb_rate_i->aux_pkt_cnt_2ss)); main_2ss_evm_min = main_2ss_evm_min << 2; aux_2ss_evm_min = aux_2ss_evm_min << 2; } else { main_2ss_evm_min = (u8)HALBB_DIV(bb_evm_i->main_evm_min_acc, (u64)bb_rate_i->main_pkt_cnt_2ss); aux_2ss_evm_min = (u8)HALBB_DIV(bb_evm_i->aux_evm_min_acc, (u64)bb_rate_i->aux_pkt_cnt_2ss); } if (main_2ss_evm_min == aux_2ss_evm_min) { target_ant_evm_2ss = bb_ant_div->pre_target_ant; no_change_flag_2ss = true; } else if (main_2ss_evm_min > aux_2ss_evm_min) { target_ant_evm_2ss = MAIN_ANT; } else { target_ant_evm_2ss = AUX_ANT; } /* Calc. EVM confindece*/ evm_diff_2ss = DIFF_2(main_2ss_evm_min, aux_2ss_evm_min); } /*-----For Debug-----*/ BB_DBG(bb, DBG_ANT_DIV, "%-9s (%02d.%03d) (%d)\n", "[Main-Ant 2ss-EVM_avg]", (main_2ss_evm_min >> 2), halbb_show_fraction_num(main_2ss_evm_min & 0x3, 2),main_2ss_evm_min); BB_DBG(bb, DBG_ANT_DIV, "%-9s (%02d.%03d) (%d)\n", "[Aux-Ant 2ss-EVM_avg]", (aux_2ss_evm_min >> 2), halbb_show_fraction_num(aux_2ss_evm_min & 0x3, 2), aux_2ss_evm_min); /*-------------------*/ if ((bb_rate_i->main_pkt_cnt_2ss + bb_rate_i->aux_pkt_cnt_2ss) != 0) { decision_evm_ss = 2; bb_evm_i->evm_diff = evm_diff_2ss; bb_ant_div->target_ant_evm = target_ant_evm_2ss; bb_evm_i->no_change_flag = no_change_flag_2ss; } else { decision_evm_ss = 1; bb_evm_i->evm_diff = evm_diff_1ss; bb_ant_div->target_ant_evm = target_ant_evm_1ss; bb_evm_i->no_change_flag = no_change_flag_1ss; } if (bb_evm_i->no_change_flag == true) { bb_evm_i->evm_diff = 0; BB_DBG(bb, DBG_ANT_DIV, "EVM based TargetAnt= Pre-TargetAnt\n"); } if (bb_evm_i->evm_diff > 100) bb_evm_i->evm_diff = 100; BB_DBG(bb, DBG_ANT_DIV, "%d-ss EVM based TargetAnt= [%s]\n", decision_evm_ss, (bb_ant_div->target_ant_evm == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"); BB_DBG(bb, DBG_ANT_DIV, "EVM Confidence= [%d]\n", bb_evm_i->evm_diff); } void halbb_antdiv_training_state(struct bb_info *bb) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_link_info *bb_link = &bb->bb_link_i; u8 next_ant; if (bb_ant_div->antdiv_training_state_cnt == 0) { bb_ant_div->get_stats = false; halbb_antdiv_reset_training_stat(bb); bb_ant_div->training_ant = bb_ant_div->pre_target_ant; next_ant = (bb_ant_div->training_ant == MAIN_ANT) ? MAIN_ANT : AUX_ANT; BB_DBG(bb, DBG_ANT_DIV, "Next training ant =%s\n", (next_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"); halbb_antdiv_set_ant(bb, next_ant); bb_ant_div->training_ant = next_ant; //bb_ant_div->pre_target_ant = next_ant; bb_ant_div->antdiv_training_state_cnt++; BB_DBG(bb, DBG_ANT_DIV, "%s Statistics Interval=%d ms\n", ((next_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"), bb_ant_div->antdiv_intvl); bb_ant_div->get_stats = true; bb_ant_div->antdiv_timer_ms = bb_ant_div->antdiv_intvl; halbb_antdiv_timers(bb, BB_SET_TIMER); } else if ((bb_ant_div->antdiv_training_state_cnt % 2) == 0) { bb_ant_div->antdiv_training_state_cnt++; next_ant = bb_ant_div->training_ant; BB_DBG(bb, DBG_ANT_DIV, "%s Statistics Interval=%d ms\n", ((next_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"), bb_ant_div->antdiv_intvl); bb_ant_div->get_stats = true; bb_ant_div->antdiv_timer_ms = bb_ant_div->antdiv_intvl; halbb_antdiv_timers(bb, BB_SET_TIMER); } else if ((bb_ant_div->antdiv_training_state_cnt % 2) != 0) { bb_ant_div->get_stats = false; next_ant = (bb_ant_div->training_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT; BB_DBG(bb, DBG_ANT_DIV, "Next training ant =%s\n", (next_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"); halbb_antdiv_set_ant(bb, next_ant); bb_ant_div->training_ant = next_ant; bb_ant_div->antdiv_training_state_cnt++; BB_DBG(bb, DBG_ANT_DIV, "%s Delay=%d ms\n", ((next_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"), bb_ant_div->antdiv_delay); bb_ant_div->antdiv_timer_ms = bb_ant_div->antdiv_delay; halbb_antdiv_timers(bb, BB_SET_TIMER); } } void halbb_antdiv_decision_state(struct bb_info *bb) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_link_info *bb_link = &bb->bb_link_i; struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i; struct bb_rate_info *rate_i = &cmn_rpt->bb_rate_i; struct bb_antdiv_rate_info *bb_rate_i = &bb_ant_div->bb_rate_i; struct bb_antdiv_evm_info *bb_evm_i = &bb_ant_div->bb_evm_i; BB_DBG(bb, DBG_ANT_DIV, "[Decisoin state]\n"); bb_ant_div->get_stats = false; bb_ant_div->antdiv_training_state_cnt = 0; /* Check highest MCS idx of main & aux antenna*/ halbb_antdiv_get_highest_mcs(bb); /* EVM based antenna diversity */ halbb_antdiv_get_evm_target_ant(bb); /* Final Decision */ if ((bb_rate_i->main_cnt_all + bb_rate_i->aux_cnt_all) == 0) { BB_DBG(bb, DBG_ANT_DIV, "Not enough count, remain previous antenna\n"); bb_ant_div->target_ant = bb_ant_div->pre_target_ant; BB_DBG(bb, DBG_ANT_DIV, "Make decision again ASAP\n"); bb_ant_div->antdiv_wd_cnt = bb_ant_div->antdiv_period; return; } if (bb_rate_i->no_change_flag && bb_evm_i->no_change_flag) { BB_DBG(bb, DBG_ANT_DIV, "No Decision, remain previous antenna\n"); bb_ant_div->target_ant = bb_ant_div->pre_target_ant; BB_DBG(bb, DBG_ANT_DIV, "Make decision again ASAP\n"); bb_ant_div->antdiv_wd_cnt = bb_ant_div->antdiv_period; return; } if ((bb_ant_div->target_ant_evm == bb_ant_div->target_ant_tp) && (!bb_rate_i->no_change_flag) && (!bb_evm_i->no_change_flag)) { BB_DBG(bb, DBG_ANT_DIV, "Decision confidence is enough\n"); bb_ant_div->target_ant = bb_ant_div->target_ant_evm; } else { if (bb_rate_i->tp_diff >= bb_ant_div->tp_diff_th_high) { BB_DBG(bb, DBG_ANT_DIV, "TP confidence is %lld > %d, Decided by MCS based\n" ,bb_rate_i->tp_diff, bb_ant_div->tp_diff_th_low); bb_ant_div->target_ant = bb_ant_div->target_ant_tp; } else if (bb_evm_i->evm_diff >= bb_ant_div->evm_diff_th) { BB_DBG(bb, DBG_ANT_DIV, "EVM confidence is more than %d, Decided by EVM based\n" ,bb_ant_div->evm_diff_th); bb_ant_div->target_ant = bb_ant_div->target_ant_evm; } else if (bb_rate_i->tp_diff >= bb_ant_div->tp_diff_th_low) { BB_DBG(bb, DBG_ANT_DIV, "TP confidence is %lld > %d, Decided by MCS based\n" ,bb_rate_i->tp_diff, bb_ant_div->tp_diff_th_low); bb_ant_div->target_ant = bb_ant_div->target_ant_tp; } else { BB_DBG(bb, DBG_ANT_DIV, "Decision confidence is not enough, remain previous antenna\n"); bb_ant_div->target_ant = bb_ant_div->pre_target_ant; BB_DBG(bb, DBG_ANT_DIV, "Make decision again ASAP\n"); bb_ant_div->antdiv_wd_cnt = bb_ant_div->antdiv_period; } } BB_DBG(bb, DBG_ANT_DIV, "TargetAnt= [%s]\n", (bb_ant_div->target_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"); } void halbb_evm_based_antdiv(struct bb_info *bb) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_link_info *bb_link = &bb->bb_link_i; struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i; struct bb_rssi_su_avg_info *avg = &cmn_rpt->bb_rssi_su_avg_i; struct bb_rate_info *rate_i = &cmn_rpt->bb_rate_i; /* Main function */ if (bb_ant_div->antdiv_training_state_cnt <= ((bb_ant_div->antdiv_train_num << 1) - 2)) { BB_DBG(bb, DBG_ANT_DIV, "Ant_diversity training state = %d \n", bb_ant_div->antdiv_training_state_cnt); halbb_antdiv_training_state(bb); return; } else { halbb_antdiv_decision_state(bb); halbb_antdiv_reset_training_stat(bb); } /* Set new target antenna */ BB_DBG(bb, DBG_ANT_DIV, "Ant_diversity done\n"); halbb_antdiv_set_ant(bb, bb_ant_div->target_ant); /* Re-assign to next step reqired variable */ bb_ant_div->target_ant_evm = bb_ant_div->target_ant; bb_ant_div->target_ant_tp = bb_ant_div->target_ant; bb_ant_div->target_ant_cn = bb_ant_div->target_ant; bb_ant_div->pre_target_ant = bb_ant_div->target_ant; } void halbb_antenna_diversity(struct bb_info *bb) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_link_info *bb_link = &bb->bb_link_i; struct bb_antdiv_rssi_info *rssi_stat = &bb_ant_div->bb_rssi_i; struct rtw_phl_com_t *phl = bb->phl_com; struct dev_cap_t *dev = &phl->dev_cap; u8 rssi; halbb_antdiv_get_rssi(bb); rssi = rssi_stat->rssi_final; BB_DBG(bb, DBG_ANT_DIV, "%s ======>\n", __func__); /* Early return */ if(phl_is_mp_mode(bb->phl_com)) { BB_DBG(bb, DBG_ANT_DIV, "Early return - MP mode\n"); return; } if (dev->rfe_type != 50) return; if (!(bb->support_ability & BB_ANT_DIV)) { BB_DBG(bb, DBG_ANT_DIV, "Early return - Not support antenna diversity\n"); return; } if (!(bb_link->is_linked) && !(bb_link->is_one_entry_only)) { BB_DBG(bb, DBG_ANT_DIV, "Early return - is_linked=%d, one_entry_only=%d\n", bb_link->is_linked, bb_link->is_one_entry_only); return; } if (rssi < ANTDIV_RSSI_TH_HIGH) { BB_DBG(bb, DBG_ANT_DIV, "RSSI=%d is too low to do Ant_diveristy\n", rssi >> 1); return; } if (bb_link->one_entry_tp_active_occur) { // if TP > th., do antdiv per watchdog BB_DBG(bb, DBG_ANT_DIV, "TP occur, do antdv immediately\n"); bb_ant_div->antdiv_wd_cnt = bb_ant_div->antdiv_period; } if (bb_ant_div->antdiv_wd_cnt < bb_ant_div->antdiv_period) { // else, do antdiv after specific watchdog BB_DBG(bb, DBG_ANT_DIV, "Ant-div period = %d, watchdog count = %d\n", bb_ant_div->antdiv_period, bb_ant_div->antdiv_wd_cnt); bb_ant_div->antdiv_wd_cnt++; return; } else { bb_ant_div->antdiv_wd_cnt = 0; } /* Fixed-antenna diversity mode */ if (bb_ant_div->antdiv_mode != AUTO_ANT) { BB_DBG(bb, DBG_ANT_DIV, "Fix Antenna at (( %s ))\n", (bb_ant_div->antdiv_mode == FIX_MAIN_ANT) ? "MAIN" : "AUX"); if (bb_ant_div->antdiv_mode != bb_ant_div->pre_antdiv_mode) { if (bb_ant_div->antdiv_mode == FIX_MAIN_ANT) { halbb_antdiv_set_ant(bb, MAIN_ANT); } else if (bb_ant_div->antdiv_mode == FIX_AUX_ANT) { halbb_antdiv_set_ant(bb, AUX_ANT); } } bb_ant_div->pre_antdiv_mode = bb_ant_div->antdiv_mode; return; } /* Main section of EVM/TP based antenna diversity*/ BB_DBG(bb, DBG_ANT_DIV, "RSSI=%d, Ant_diversity start\n", rssi >> 1); halbb_evm_based_antdiv(bb); } void halbb_antdiv_get_rssi_stat(struct bb_info *bb) { struct bb_physts_rslt_hdr_info *psts_h = &bb->bb_physts_i.bb_physts_rslt_hdr_i; struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i; struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_antdiv_rssi_info *rssi = &bb_ant_div->bb_rssi_i; struct bb_rate_info *rate_i = &cmn_rpt->bb_rate_i; u8 i = 0; if (rate_i->mode == BB_LEGACY_MODE) { if (cmn_rpt->is_cck_rate) { rssi->rssi_cck_avg_acc += psts_h->rssi_avg; rssi->pkt_cnt_cck++; } else { rssi->rssi_ofdm_avg_acc += psts_h->rssi_avg; rssi->pkt_cnt_ofdm++; } } else { rssi->rssi_t_avg_acc+= psts_h->rssi_avg; rssi->pkt_cnt_t++; } } void halbb_antdiv_get_evm_stat(struct bb_info *bb) { struct bb_physts_rslt_1_info *psts_1 = &bb->bb_physts_i.bb_physts_rslt_1_i; struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i; struct bb_rate_info *rate_i = &cmn_rpt->bb_rate_i; struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_antdiv_evm_info *bb_evm_i = &bb_ant_div->bb_evm_i; struct bb_link_info *bb_link = &bb->bb_link_i; /* Only get stats @ training period */ if (!bb_ant_div->get_stats) return; /* No EVM info. @ cck rate */ if (cmn_rpt->is_cck_rate) return; if (bb_ant_div->evm_decision_method == EVM_LINEAR_AVG) { if(bb_ant_div->training_ant == MAIN_ANT) { if (rate_i->ss == 1) { bb_evm_i->main_evm_1ss += halbb_db_2_linear((psts_1->evm_min >> 2)); } else { bb_evm_i->main_evm_min_acc += halbb_db_2_linear((psts_1->evm_min>> 2)); bb_evm_i->main_evm_max_acc += halbb_db_2_linear((psts_1->evm_max >> 2)); } } else if(bb_ant_div->training_ant == AUX_ANT) { if (rate_i->ss == 1) { bb_evm_i->aux_evm_1ss += halbb_db_2_linear((psts_1->evm_min >> 2)); } else { bb_evm_i->aux_evm_min_acc += halbb_db_2_linear((psts_1->evm_min >> 2)); bb_evm_i->aux_evm_max_acc += halbb_db_2_linear((psts_1->evm_max >> 2)); } } } else { if(bb_ant_div->training_ant == MAIN_ANT) { if (rate_i->ss == 1) { bb_evm_i->main_evm_1ss += psts_1->evm_min; } else { bb_evm_i->main_evm_min_acc += psts_1->evm_min; bb_evm_i->main_evm_max_acc += psts_1->evm_max; } } else if(bb_ant_div->training_ant == AUX_ANT) { if (rate_i->ss == 1) { bb_evm_i->aux_evm_1ss += psts_1->evm_min; } else { bb_evm_i->aux_evm_min_acc += psts_1->evm_min; bb_evm_i->aux_evm_max_acc += psts_1->evm_max; } } } } void halbb_antdiv_get_cn_stat(struct bb_info *bb) { struct bb_physts_rslt_1_info *psts_1 = &bb->bb_physts_i.bb_physts_rslt_1_i; struct bb_cmn_rpt_info *cmn_rpt = &bb->bb_cmn_rpt_i; struct bb_rate_info *rate_i = &cmn_rpt->bb_rate_i; struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_antdiv_cn_info *bb_cn_i = &bb_ant_div->bb_cn_i; struct bb_link_info *bb_link = &bb->bb_link_i; /* Only get stats @ training period */ if (!bb_ant_div->get_stats) return; /* Data frame only */ #if 0 if (bb_ant_div->antdiv_use_ctrl_frame) { if (!bb_link->is_match_bssid) return; } #endif /* No CN info. @ cck rate */ if (cmn_rpt->is_cck_rate) return; if (rate_i->ss == 0) return; if(bb_ant_div->training_ant == MAIN_ANT) { bb_cn_i->main_cn_avg_acc += psts_1->cn_avg; } else if(bb_ant_div->training_ant == AUX_ANT) { bb_cn_i->aux_cn_avg_acc += psts_1->cn_avg; } } void halbb_antdiv_get_rate_stat(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_rate_info *rate_i = &cmn_rpt->bb_rate_i; struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_antdiv_rate_info *bb_rate_i = &bb_ant_div->bb_rate_i; struct bb_link_info *bb_link = &bb->bb_link_i; u8 ofst = rate_i->idx; /* Only get stats @ training period */ if (!bb_ant_div->get_stats) return; /* Data frame only */ #if 0 if (bb_ant_div->antdiv_use_ctrl_frame) { if (!bb_link->is_match_bssid) return; } #endif //BB_DBG(bb, DBG_ANT_DIV, "Rate mode= %d\n", rate_i->mode); //BB_DBG(bb, DBG_ANT_DIV, "Training antenna= %d\n", bb_ant_div->training_ant); if(bb_ant_div->training_ant == MAIN_ANT) { /* pkt_cnt acc */ //BB_DBG(bb, DBG_ANT_DIV, "MAIN_ANT rate!\n"); bb_rate_i->main_cnt_all++; if (rate_i->mode == BB_LEGACY_MODE) { if (cmn_rpt->is_cck_rate) bb_rate_i->main_pkt_cnt_cck++; else bb_rate_i->main_pkt_cnt_ofdm++; } else { bb_rate_i->main_pkt_cnt_t++; if (rate_i->ss == 1) bb_rate_i->main_pkt_cnt_1ss++; else if (rate_i->ss == 2) bb_rate_i->main_pkt_cnt_2ss++; } /* rate cnt acc*/ if (rate_i->mode == BB_LEGACY_MODE) { bb_rate_i->main_pkt_cnt_legacy[ofst]++; return; } if (rate_i->ss >= 2 && rate_i->mode >= BB_VHT_MODE) ofst += (HE_VHT_NUM_MCS * (rate_i->ss - 1)); if (rate_i->mode == BB_HT_MODE) { bb_rate_i->main_ht_pkt_not_zero = true; ofst = NOT_GREATER(ofst, HT_RATE_NUM - 1); bb_rate_i->main_pkt_cnt_ht[ofst]++; /* shift ofst due to mismatch of HT/VHT rate num*/ ofst += ((ofst << 3) >> 2); bb_rate_i->main_tp += bb_phy_rate_table[ofst + LEGACY_RATE_NUM]; } else if (rate_i->mode == BB_VHT_MODE) { bb_rate_i->main_vht_pkt_not_zero = true; ofst = NOT_GREATER(ofst, VHT_RATE_NUM - 1); bb_rate_i->main_pkt_cnt_vht[ofst]++; bb_rate_i->main_tp += bb_phy_rate_table[ofst + LEGACY_RATE_NUM]; } else if (rate_i->mode == BB_HE_MODE) { bb_rate_i->main_he_pkt_not_zero = true; ofst = NOT_GREATER(ofst, HE_RATE_NUM - 1); bb_rate_i->main_pkt_cnt_he[ofst]++; bb_rate_i->main_tp += bb_phy_rate_table[ofst + LEGACY_RATE_NUM]; } } else if(bb_ant_div->training_ant == AUX_ANT) { bb_rate_i->aux_cnt_all++; //BB_DBG(bb, DBG_ANT_DIV, "Aux_ANT rate!\n"); /* pkt_cnt acc */ if (rate_i->mode == BB_LEGACY_MODE) { if (cmn_rpt->is_cck_rate) bb_rate_i->aux_pkt_cnt_cck++; else bb_rate_i->aux_pkt_cnt_ofdm++; } else { bb_rate_i->aux_pkt_cnt_t++; if (rate_i->ss == 1) bb_rate_i->aux_pkt_cnt_1ss++; else if (rate_i->ss == 2) bb_rate_i->aux_pkt_cnt_2ss++; } if (rate_i->mode == BB_LEGACY_MODE) { bb_rate_i->aux_pkt_cnt_legacy[ofst]++; return; } if (rate_i->ss >= 2 && rate_i->mode >= BB_VHT_MODE) ofst += (HE_VHT_NUM_MCS * (rate_i->ss - 1)); if (rate_i->mode == BB_HT_MODE) { bb_rate_i->aux_ht_pkt_not_zero = true; ofst = NOT_GREATER(ofst, HT_RATE_NUM - 1); bb_rate_i->aux_pkt_cnt_ht[ofst]++; /* shift ofst due to mismatch of HT/VHT rate num*/ ofst += ((ofst >> 3) << 2); bb_rate_i->aux_tp += bb_phy_rate_table[ofst + LEGACY_RATE_NUM]; } else if (rate_i->mode == BB_VHT_MODE) { bb_rate_i->aux_vht_pkt_not_zero = true; ofst = NOT_GREATER(ofst, VHT_RATE_NUM - 1); bb_rate_i->aux_pkt_cnt_vht[ofst]++; bb_rate_i->aux_tp += bb_phy_rate_table[ofst + LEGACY_RATE_NUM]; } else if (rate_i->mode == BB_HE_MODE) { bb_rate_i->aux_he_pkt_not_zero = true; ofst = NOT_GREATER(ofst, HE_RATE_NUM - 1); bb_rate_i->aux_pkt_cnt_he[ofst]++; bb_rate_i->aux_tp += bb_phy_rate_table[ofst + LEGACY_RATE_NUM]; } } } void halbb_antdiv_phy_sts(struct bb_info *bb) { halbb_antdiv_get_rssi_stat(bb); halbb_antdiv_get_rate_stat(bb); halbb_antdiv_get_evm_stat(bb); halbb_antdiv_get_cn_stat(bb); } void halbb_antdiv_dbg(struct bb_info *bb, char input[][16], u32 *_used, char *output, u32 *_out_len) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_antdiv_cr_info *cr = &bb->bb_ant_div_i.bb_antdiv_cr_i; char help[] = "-h"; u32 var[10] = {0}; u32 used = *_used; u32 out_len = *_out_len; if ((_os_strcmp(input[1], help) == 0)) { BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Set Antenna Diversity Mode: {1} {0}: Auto-mode {1}: Fix main ant. {2}: Fix aux ant.\n"); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Set Antenna Diversity Method: {2} {0}: EVM based {1}: CN based\n"); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Set training period: {3} {num of watchdog} (How much watchdog to do one ant-div)\n"); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Set training state number: {4} {num}\n"); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Set training interval: {5} {ms} (how long for one training state)\n"); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Set training delay: {6} {ms} (how long to wait RA stable)\n"); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Set decision threshold: {7} {TP high th.} {TP low th.} {EVM th.}\n"); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "TP lower bound: {8} {th.}\n"); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "TP decision method: {9} {0}: Max cnt domination {1}: highest rate domination {2}: Avg. TP domination\n"); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "EVM decision method: {10} {0}:Linear avg. {1}: dB avg.\n"); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Show all parameter: {100}\n"); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "[ONLY DEBUG] {101} 0x586c[16]={0,1}\n"); } else { HALBB_SCAN(input[1], DCMD_DECIMAL, &var[0]); if (var[0] == 1) { HALBB_SCAN(input[2], DCMD_DECIMAL, &var[1]); bb_ant_div->antdiv_mode = (u8)var[1]; BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div Mode=%d\n", bb_ant_div->antdiv_mode); if (bb_ant_div->antdiv_mode == FIX_MAIN_ANT) { halbb_antdiv_set_ant(bb, MAIN_ANT); bb_ant_div->pre_target_ant = MAIN_ANT; } else if (bb_ant_div->antdiv_mode == FIX_AUX_ANT) { halbb_antdiv_set_ant(bb, AUX_ANT); bb_ant_div->pre_target_ant = AUX_ANT; } else if (bb_ant_div->antdiv_mode == AUTO_ANT) halbb_antdiv_set_ant(bb, bb_ant_div->pre_target_ant); } else if (var[0] == 2) { HALBB_SCAN(input[2], DCMD_DECIMAL, &var[1]); bb_ant_div->antdiv_method = var[1]; BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div training method=%d\n", bb_ant_div->antdiv_method); } else if (var[0] == 3) { HALBB_SCAN(input[2], DCMD_DECIMAL, &var[1]); bb_ant_div->antdiv_period = (u8)var[1]; BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div period=%d watchdog\n", bb_ant_div->antdiv_period); } else if (var[0] == 4) { HALBB_SCAN(input[2], DCMD_DECIMAL, &var[1]); bb_ant_div->antdiv_train_num = var[1]; BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div training state num=%d\n", bb_ant_div->antdiv_train_num); } else if (var[0] == 5) { HALBB_SCAN(input[2], DCMD_DECIMAL, &var[1]); bb_ant_div->antdiv_intvl = var[1]; BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div training interval=%d\n", bb_ant_div->antdiv_intvl); } else if (var[0] == 6) { HALBB_SCAN(input[2], DCMD_DECIMAL, &var[1]); bb_ant_div->antdiv_delay = var[1]; BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div training delay=%d\n", bb_ant_div->antdiv_delay); } else if (var[0] == 7) { HALBB_SCAN(input[2], DCMD_DECIMAL, &var[1]); HALBB_SCAN(input[3], DCMD_DECIMAL, &var[2]); HALBB_SCAN(input[4], DCMD_DECIMAL, &var[3]); bb_ant_div->tp_diff_th_high = (u16)var[1]; bb_ant_div->tp_diff_th_low = (u16)var[2]; bb_ant_div->evm_diff_th = (u8)var[3]; BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Decision threshold: {TP high = %d} {TP low = %d} {EVM = %d}\n", bb_ant_div->tp_diff_th_high, bb_ant_div->tp_diff_th_low, bb_ant_div->evm_diff_th); } else if (var[0] == 8) { HALBB_SCAN(input[2], DCMD_DECIMAL, &var[1]); bb_ant_div->tp_lb = (u8)var[1]; BB_DBG_CNSL(out_len, used, output + used, out_len - used, "TP lower bound=%d\n", bb_ant_div->tp_lb); } else if (var[0] == 9) { HALBB_SCAN(input[2], DCMD_DECIMAL, &var[1]); bb_ant_div->tp_decision_method = (u8)var[1]; BB_DBG(bb, DBG_ANT_DIV, "TP decision method=(( %d ))\n", bb_ant_div->tp_decision_method); } else if (var[0] == 10) { HALBB_SCAN(input[2], DCMD_DECIMAL, &var[1]); bb_ant_div->evm_decision_method = (u8)var[1]; BB_DBG(bb, DBG_ANT_DIV, "EVM decision method=(( %d ))\n", bb_ant_div->evm_decision_method); } else if (var[0] == 100) { BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div Mode = {%d}\n", bb_ant_div->antdiv_mode); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div training method = {%d}\n", bb_ant_div->antdiv_method); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "TP decision method = {%d}\n", bb_ant_div->tp_decision_method); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "EVM decision method = {%d}\n", bb_ant_div->evm_decision_method); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div period = {#%d-watchdog}\n", bb_ant_div->antdiv_period); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div training state num = {%d}\n", bb_ant_div->antdiv_train_num); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div training interval = {%d}\n", bb_ant_div->antdiv_intvl); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Ant-Div training delay = {%d}\n", bb_ant_div->antdiv_delay); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "Decision threshold: {TP high = %d} {TP low = %d} {EVM = %d}\n", bb_ant_div->tp_diff_th_high, bb_ant_div->tp_diff_th_low, bb_ant_div->evm_diff_th); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "TP lower bound = {%d}\n", bb_ant_div->tp_lb); } else if (var[0] == 101) { HALBB_SCAN(input[2], DCMD_DECIMAL, &var[1]); halbb_set_reg_cmn(bb, cr->path0_r_antsel, BIT(16), var[1], HW_PHY_0); BB_DBG_CNSL(out_len, used, output + used, out_len - used, "[ONLY DEBUG] 0x1586c[16] = %d\n", var[1]); } } *_used = used; *_out_len = out_len; } void halbb_antdiv_callback(void *context) { struct bb_info *bb = (struct bb_info *)context; struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; struct bb_link_info *bb_link = &bb->bb_link_i; halbb_evm_based_antdiv(bb); } void halbb_antdiv_timers(struct bb_info *bb, enum bb_timer_cfg_t bb_antdiv_timer_state) { struct bb_antdiv_info *bb_ant_div = &bb->bb_ant_div_i; u8 state = bb_antdiv_timer_state; if (state == BB_SET_TIMER) { halbb_set_timer(bb, &bb->antdiv_timer, bb_ant_div->antdiv_timer_ms); } else if (state == BB_INIT_TIMER) { halbb_init_timer(bb, &bb->antdiv_timer, halbb_antdiv_callback, bb, "halbb_antdiv_timers"); } else if (state == BB_CANCEL_TIMER) { halbb_cancel_timer(bb, &bb->antdiv_timer); } else if (state == BB_RELEASE_TIMER) { halbb_release_timer(bb, &bb->antdiv_timer); } } void halbb_cr_cfg_antdiv_init(struct bb_info *bb) { struct bb_antdiv_cr_info *cr = &bb->bb_ant_div_i.bb_antdiv_cr_i; switch (bb->cr_type) { #ifdef BB_8852A_CAV_SUPPORT case BB_52AA: cr->path0_r_ant_train_en = PATH0_R_ANT_TRAIN_EN_52AA; cr->path0_r_ant_train_en_m = PATH0_R_ANT_TRAIN_EN_52AA_M; cr->path0_r_tx_ant_sel = PATH0_R_TX_ANT_SEL_52AA; cr->path0_r_tx_ant_sel_m = PATH0_R_TX_ANT_SEL_52AA_M; cr->path0_r_rfe_buf_en = PATH0_R_RFE_BUF_EN_52AA; cr->path0_r_rfe_buf_en_m = PATH0_R_RFE_BUF_EN_52AA_M; cr->path0_r_lnaon_agc = PATH0_R_LNAON_AGC_52AA; cr->path0_r_lnaon_agc_m = PATH0_R_LNAON_AGC_52AA_M; cr->path0_r_trsw_bit_bt = PATH0_R_TRSW_BIT_BT_52AA; cr->path0_r_trsw_bit_bt_m = PATH0_R_TRSW_BIT_BT_52AA_M; cr->path0_r_trsw_s = PATH0_R_TRSW_S_52AA; cr->path0_r_trsw_s_m = PATH0_R_TRSW_S_52AA_M; cr->path0_r_trsw_o = PATH0_R_TRSW_O_52AA; cr->path0_r_trsw_o_m = PATH0_R_TRSW_O_52AA_M; cr->path0_r_trswb_o = PATH0_R_TRSWB_O_52AA; cr->path0_r_trswb_o_m = PATH0_R_TRSWB_O_52AA_M; cr->path0_r_bt_force_antidx = PATH0_R_BT_FORCE_ANTIDX_52AA; cr->path0_r_bt_force_antidx_m = PATH0_R_BT_FORCE_ANTIDX_52AA_M; cr->path0_r_bt_force_antidx_en = PATH0_R_BT_FORCE_ANTIDX_EN_52AA; cr->path0_r_bt_force_antidx_en_m = PATH0_R_BT_FORCE_ANTIDX_EN_52AA_M; cr->path0_r_ant_module_rfe_opt = PATH0_R_ANT_MODULE_RFE_OPT_52AA; cr->path0_r_ant_module_rfe_opt_m = PATH0_R_ANT_MODULE_RFE_OPT_52AA_M; cr->path0_r_rfsw_tr = PATH0_R_RFSW_TR_52AA; cr->path0_r_rfsw_tr_m = PATH0_R_RFSW_TR_52AA_M; cr->path0_r_antsel = PATH0_R_ANTSEL_52AA; cr->path0_r_antsel_m = PATH0_R_ANTSEL_52AA_M; cr->path0_r_rfsw_ant_31_0 = PATH0_R_RFSW_ANT_31_0__52AA; cr->path0_r_rfsw_ant_31_0_m = PATH0_R_RFSW_ANT_31_0__52AA_M; cr->path0_r_rfsw_ant_63_32 = PATH0_R_RFSW_ANT_63_32__52AA; cr->path0_r_rfsw_ant_63_32_m = PATH0_R_RFSW_ANT_63_32__52AA_M; cr->path0_r_rfsw_ant_95_64 = PATH0_R_RFSW_ANT_95_64__52AA; cr->path0_r_rfsw_ant_95_64_m = PATH0_R_RFSW_ANT_95_64__52AA_M; cr->path0_r_rfsw_ant_127_96 = PATH0_R_RFSW_ANT_127_96__52AA; cr->path0_r_rfsw_ant_127_96_m = PATH0_R_RFSW_ANT_127_96__52AA_M; break; #endif #ifdef HALBB_COMPILE_AP_SERIES case BB_AP: cr->path0_r_ant_train_en = PATH0_R_ANT_TRAIN_EN_A; cr->path0_r_ant_train_en_m = PATH0_R_ANT_TRAIN_EN_A_M; cr->path0_r_tx_ant_sel = PATH0_R_TX_ANT_SEL_A; cr->path0_r_tx_ant_sel_m = PATH0_R_TX_ANT_SEL_A_M; cr->path0_r_rfe_buf_en = PATH0_R_RFE_BUF_EN_A; cr->path0_r_rfe_buf_en_m = PATH0_R_RFE_BUF_EN_A_M; cr->path0_r_lnaon_agc = PATH0_R_LNAON_AGC_A; cr->path0_r_lnaon_agc_m = PATH0_R_LNAON_AGC_A_M; cr->path0_r_trsw_bit_bt = PATH0_R_TRSW_BIT_BT_A; cr->path0_r_trsw_bit_bt_m = PATH0_R_TRSW_BIT_BT_A_M; cr->path0_r_trsw_s = PATH0_R_TRSW_S_A; cr->path0_r_trsw_s_m = PATH0_R_TRSW_S_A_M; cr->path0_r_trsw_o = PATH0_R_TRSW_O_A; cr->path0_r_trsw_o_m = PATH0_R_TRSW_O_A_M; cr->path0_r_trswb_o = PATH0_R_TRSWB_O_A; cr->path0_r_trswb_o_m = PATH0_R_TRSWB_O_A_M; cr->path0_r_bt_force_antidx = PATH0_R_BT_FORCE_ANTIDX_A; cr->path0_r_bt_force_antidx_m = PATH0_R_BT_FORCE_ANTIDX_A_M; cr->path0_r_bt_force_antidx_en = PATH0_R_BT_FORCE_ANTIDX_EN_A; cr->path0_r_bt_force_antidx_en_m = PATH0_R_BT_FORCE_ANTIDX_EN_A_M; cr->path0_r_ant_module_rfe_opt = PATH0_R_ANT_MODULE_RFE_OPT_A; cr->path0_r_ant_module_rfe_opt_m = PATH0_R_ANT_MODULE_RFE_OPT_A_M; cr->path0_r_rfsw_tr = PATH0_R_RFSW_TR_A; cr->path0_r_rfsw_tr_m = PATH0_R_RFSW_TR_A_M; cr->path0_r_antsel = PATH0_R_ANTSEL_A; cr->path0_r_antsel_m = PATH0_R_ANTSEL_A_M; cr->path0_r_rfsw_ant_31_0 = PATH0_R_RFSW_ANT_31_0__A; cr->path0_r_rfsw_ant_31_0_m = PATH0_R_RFSW_ANT_31_0__A_M; cr->path0_r_rfsw_ant_63_32 = PATH0_R_RFSW_ANT_63_32__A; cr->path0_r_rfsw_ant_63_32_m = PATH0_R_RFSW_ANT_63_32__A_M; cr->path0_r_rfsw_ant_95_64 = PATH0_R_RFSW_ANT_95_64__A; cr->path0_r_rfsw_ant_95_64_m = PATH0_R_RFSW_ANT_95_64__A_M; cr->path0_r_rfsw_ant_127_96 = PATH0_R_RFSW_ANT_127_96__A; cr->path0_r_rfsw_ant_127_96_m = PATH0_R_RFSW_ANT_127_96__A_M; break; #endif #ifdef HALBB_COMPILE_CLIENT_SERIES case BB_CLIENT: cr->path0_r_ant_train_en = PATH0_R_ANT_TRAIN_EN_C; cr->path0_r_ant_train_en_m = PATH0_R_ANT_TRAIN_EN_C_M; cr->path0_r_tx_ant_sel = PATH0_R_TX_ANT_SEL_C; cr->path0_r_tx_ant_sel_m = PATH0_R_TX_ANT_SEL_C_M; cr->path0_r_rfe_buf_en = PATH0_R_RFE_BUF_EN_C; cr->path0_r_rfe_buf_en_m = PATH0_R_RFE_BUF_EN_C_M; cr->path0_r_lnaon_agc = PATH0_R_LNAON_AGC_C; cr->path0_r_lnaon_agc_m = PATH0_R_LNAON_AGC_C_M; cr->path0_r_trsw_bit_bt = PATH0_R_TRSW_BIT_BT_C; cr->path0_r_trsw_bit_bt_m = PATH0_R_TRSW_BIT_BT_C_M; cr->path0_r_trsw_s = PATH0_R_TRSW_S_C; cr->path0_r_trsw_s_m = PATH0_R_TRSW_S_C_M; cr->path0_r_trsw_o = PATH0_R_TRSW_O_C; cr->path0_r_trsw_o_m = PATH0_R_TRSW_O_C_M; cr->path0_r_trswb_o = PATH0_R_TRSWB_O_C; cr->path0_r_trswb_o_m = PATH0_R_TRSWB_O_C_M; cr->path0_r_bt_force_antidx = PATH0_R_BT_FORCE_ANTIDX_C; cr->path0_r_bt_force_antidx_m = PATH0_R_BT_FORCE_ANTIDX_C_M; cr->path0_r_bt_force_antidx_en = PATH0_R_BT_FORCE_ANTIDX_EN_C; cr->path0_r_bt_force_antidx_en_m = PATH0_R_BT_FORCE_ANTIDX_EN_C_M; cr->path0_r_ant_module_rfe_opt = PATH0_R_ANT_MODULE_RFE_OPT_C; cr->path0_r_ant_module_rfe_opt_m = PATH0_R_ANT_MODULE_RFE_OPT_C_M; cr->path0_r_rfsw_tr = PATH0_R_RFSW_TR_C; cr->path0_r_rfsw_tr_m = PATH0_R_RFSW_TR_C_M; cr->path0_r_antsel = PATH0_R_ANTSEL_C; cr->path0_r_antsel_m = PATH0_R_ANTSEL_C_M; cr->path0_r_rfsw_ant_31_0 = PATH0_R_RFSW_ANT_31_0__C; cr->path0_r_rfsw_ant_31_0_m = PATH0_R_RFSW_ANT_31_0__C_M; cr->path0_r_rfsw_ant_63_32 = PATH0_R_RFSW_ANT_63_32__C; cr->path0_r_rfsw_ant_63_32_m = PATH0_R_RFSW_ANT_63_32__C_M; cr->path0_r_rfsw_ant_95_64 = PATH0_R_RFSW_ANT_95_64__C; cr->path0_r_rfsw_ant_95_64_m = PATH0_R_RFSW_ANT_95_64__C_M; cr->path0_r_rfsw_ant_127_96 = PATH0_R_RFSW_ANT_127_96__C; cr->path0_r_rfsw_ant_127_96_m = PATH0_R_RFSW_ANT_127_96__C_M; break; #endif default: break; } } #endif