/****************************************************************************** * * 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_PWR_CTRL_SUPPORT /* @ Dynamic CCA TH part */ void halbb_set_ccath_macid(struct bb_info *bb, u16 macid, s8 cca_th, bool cca_th_en) { u32 ret_v = 0; u32 mask_ccath = 0xff0000; u32 mask_en = BIT(26); struct rtw_phl_stainfo_t *phl_sta_i = NULL; enum phl_band_idx hw_band; u32 reg_ofst = REG_PWRMACID_OFST + (macid << 2) + 0xd200; if (!bb->sta_exist[macid]) { BB_WARNING("Error Set Pwr Macid for STA not exist!!\n"); return; } phl_sta_i = bb->phl_sta_info[macid]; if (!phl_sta_i) return; //phl_sta_i = bb->phl_sta_info[macid]; hw_band = phl_sta_i->wrole->hw_band; /* pwr : S(8,1)*/ ret_v |= rtw_hal_mac_write_msk_pwr_reg(bb->hal_com, hw_band, reg_ofst, mask_ccath, cca_th); ret_v |= rtw_hal_mac_write_msk_pwr_reg(bb->hal_com, hw_band, reg_ofst, mask_en, cca_th_en); BB_DBG(bb, DBG_PWR_CTRL, "halbb_set_ccath_macid = %x %x\n", cca_th, cca_th_en); if (ret_v != 0) BB_WARNING("Error Set Pwr Macid for API return fail!!\n"); } void halbb_ccath_init(struct bb_info *bb) { u8 i; struct bb_dyncca_info *dyncca_i = &bb->bb_dyncca_i; BB_DBG(bb, DBG_PWR_CTRL, "[%s]\n", __func__); dyncca_i->dyncca_offset = 10; /* clean */ dyncca_i->dyncca_offset_n = 6; /* noisy */ for (i = 0; i < PHL_MAX_STA_NUM; i++) { dyncca_i->macidcca_i[i].cca_th = 0; dyncca_i->macidcca_i[i].cca_th_en= 0; } } void halbb_cca_th_per_sta(struct bb_info *bb, u16 macid) { bool noisy_state = bb->is_noisy; struct bb_dyncca_info *dyncca_i = &bb->bb_dyncca_i; s8 dyn_ccath = 0; s8 offset = dyncca_i->dyncca_offset; struct rtw_phl_stainfo_t *sta; u8 rssi = 0; #if 0 if (!dyncca_i) { BB_DBG(bb, DBG_PWR_CTRL, "NULL pointer!\n"); return; } #endif sta = bb->phl_sta_info[macid]; if (!sta) { BB_DBG(bb, DBG_PWR_CTRL, "NULL PHL STA info\n"); return; } if (!is_sta_active(sta)) return; rssi = sta->hal_sta->rssi_stat.rssi; if (noisy_state) offset = dyncca_i->dyncca_offset_n; dyn_ccath = (s8)rssi - 110 - offset; } void halbb_dyncca_th(struct bb_info *bb) { struct bb_dyncca_info *dyncca_i = &bb->bb_dyncca_i; u8 i; if (!dyncca_i) { BB_DBG(bb, DBG_PWR_CTRL, "NULL pointer!\n"); return; } if (!dyncca_i->dyncca_en) return; /* Need to add support ability here */ /*if (!(bb->support_ability & BB_PWR_CTRL)) return; */ BB_DBG(bb, DBG_PWR_CTRL, "[%s]\n", __func__); for (i = 0; i < PHL_MAX_STA_NUM; i++) halbb_cca_th_per_sta( bb, i); } /* @ Power Ctrl part */ s8 halbb_get_pwr_macid_idx(struct bb_info *bb, u16 macid, u8 idx) { s8 tx_pwr = 0; struct bb_dtp_info *dtp = &bb->bb_pwr_ctrl_i.dtp_i[macid]; if (!dtp) { BB_DBG(bb, DBG_PWR_CTRL, "NULL pointer macid = %d\n", macid); return 0; } tx_pwr = dtp->pwr_val[idx]; return tx_pwr; /* S(8,1)*/ } bool halbb_get_pwr_macid_en_idx(struct bb_info *bb, u16 macid, u8 idx) { bool pwr_en = false; struct bb_dtp_info *dtp = &bb->bb_pwr_ctrl_i.dtp_i[macid]; if (!dtp) { BB_DBG(bb, DBG_PWR_CTRL, "NULL pointer macid = %d\n", macid); return 0; } pwr_en = dtp->en_pwr[idx]; return pwr_en; /* bool*/ } void halbb_set_pwr_macid_idx(struct bb_info *bb, u16 macid, s8 pwr, bool pwr_en, u8 idx) { u32 ret_v = 0; u32 mask_pwr = 0xff; u32 mask_en = BIT(24); struct rtw_phl_stainfo_t *phl_sta_i = NULL; enum phl_band_idx hw_band; u32 reg_ofst = REG_PWRMACID_OFST + (macid << 2) + 0xd200; if (!bb->sta_exist[macid]) { BB_WARNING("Error Set Pwr Macid for STA not exist!!\n"); return; } phl_sta_i = bb->phl_sta_info[macid]; if (!phl_sta_i) return; //phl_sta_i = bb->phl_sta_info[macid]; if (idx == 1) { mask_pwr = 0x0000ff00; mask_en = BIT(25); } hw_band = phl_sta_i->wrole->hw_band; /* pwr : S(8,1)*/ ret_v |= rtw_hal_mac_write_msk_pwr_reg(bb->hal_com, hw_band, reg_ofst, mask_pwr, pwr); ret_v |= rtw_hal_mac_write_msk_pwr_reg(bb->hal_com, hw_band, reg_ofst, mask_en, pwr_en); BB_DBG(bb, DBG_PWR_CTRL, "halbb_set_pwr_macid(%d) = %x %x\n", idx, pwr, pwr_en); if (ret_v != 0) BB_WARNING("Error Set Pwr Macid for API return fail!!\n"); } void halbb_pwr_ctrl_en(struct bb_info *bb, bool pwr_ctrl_en) { u32 ret_v = 0; u32 mask_en = BIT(29); u32 reg_ofst = 0xd20c; BB_DBG(bb, DBG_PWR_CTRL, "halbb_pwr_ctrl_en() = %x\n", (u32)pwr_ctrl_en); if(pwr_ctrl_en) { ret_v |= rtw_hal_mac_write_msk_pwr_reg(bb->hal_com, 0, reg_ofst, mask_en, 0x1); if (bb->hal_com->dbcc_en) ret_v |= rtw_hal_mac_write_msk_pwr_reg(bb->hal_com, 1, reg_ofst, mask_en, 0x1); } else { ret_v |= rtw_hal_mac_write_msk_pwr_reg(bb->hal_com, 0, reg_ofst, mask_en, 0x0); if (bb->hal_com->dbcc_en) ret_v |= rtw_hal_mac_write_msk_pwr_reg(bb->hal_com, 1, reg_ofst, mask_en, 0x0); } if (ret_v != 0) BB_WARNING("Error Enable Power Control for API return fail!!\n"); } void halbb_pwr_ctrl_th(struct bb_info *bb) { bool noisy_state = bb->is_noisy; struct bb_pwr_ctrl_info *pwr_ctrl_i = &bb->bb_pwr_ctrl_i; if (!pwr_ctrl_i) { BB_DBG(bb, DBG_PWR_CTRL, "NULL pointer!\n"); return; } if (noisy_state == 0) { pwr_ctrl_i->enhance_pwr_th[0] = pwr_ctrl_i->set_pwr_th[0]; pwr_ctrl_i->enhance_pwr_th[1] = pwr_ctrl_i->set_pwr_th[1]; pwr_ctrl_i->enhance_pwr_th[2] = pwr_ctrl_i->set_pwr_th[2]; } else { pwr_ctrl_i->enhance_pwr_th[0] = pwr_ctrl_i->set_pwr_th[0] + 8; pwr_ctrl_i->enhance_pwr_th[1] = pwr_ctrl_i->set_pwr_th[1] + 5; pwr_ctrl_i->enhance_pwr_th[2] = pwr_ctrl_i->set_pwr_th[2]; } BB_DBG(bb, DBG_PWR_CTRL, "halbb pwr ctrl pwr_th: Lv1_th =%d ,Lv2_th = %d ,Lv3_th = %d\n", pwr_ctrl_i->enhance_pwr_th[0], pwr_ctrl_i->enhance_pwr_th[1], pwr_ctrl_i->enhance_pwr_th[2]); } u8 halbb_pwr_lvl_check(struct bb_info *bb, u8 rssi_in, u8 last_pwr_lvl) { u8 i; u8 th[HALBB_PWR_STATE_NUM]; struct bb_pwr_ctrl_info *pwr_ctrl_i = &bb->bb_pwr_ctrl_i; if (!pwr_ctrl_i) { BB_DBG(bb, DBG_PWR_CTRL, "NULL pointer!\n"); return 0; } for (i = 0; i < HALBB_PWR_STATE_NUM; i++) th[i] = pwr_ctrl_i->set_pwr_th[i]; BB_DBG(bb, DBG_PWR_CTRL, "Ori-DTP th: Lv1_th = %d, Lv2_th = %d, Lv3_th = %d\n", th[0], th[1], th[2]); for (i = 0; i < HALBB_PWR_STATE_NUM; i++) { if (i >= last_pwr_lvl) th[i] += DTP_FLOOR_UP_GAP; } BB_DBG(bb, DBG_PWR_CTRL, "Mod-DTP th: Lv1_th = %d, Lv2_th = %d, Lv3_th = %d\n", th[0], th[1], th[2]); if (rssi_in >= th[2]) return TX_HP_LV_3; else if (rssi_in < (th[2] - 3) && rssi_in >= th[1]) return TX_HP_LV_2; else if (rssi_in < (th[1] - 3) && rssi_in >= th[0]) return TX_HP_LV_1; else if (rssi_in < (th[0] - 3)) return TX_HP_LV_0; else return TX_HP_LV_UNCHANGE; } void halbb_set_pwr_ctrl(struct bb_info *bb, u16 macid, u8 pwr_lv) { struct rtw_phl_stainfo_t *sta; s8 pwr = 0; bool pwr_ctrl_en = false; struct bb_pwr_ctrl_info *pwr_ctrl_i = &bb->bb_pwr_ctrl_i; if (!(bb->support_ability & BB_PWR_CTRL)) return; sta = bb->phl_sta_info[macid]; if (!sta) { BB_DBG(bb, DBG_PWR_CTRL, "NULL PHL STA info\n"); return; } if (pwr_lv == TX_HP_LV_3) { pwr_ctrl_en = true; pwr = pwr_ctrl_i->pwr_lv_dbm[2]; } else if (pwr_lv == TX_HP_LV_2) { pwr_ctrl_en = true; pwr = pwr_ctrl_i->pwr_lv_dbm[1]; } else if (pwr_lv == TX_HP_LV_1) { pwr_ctrl_en = true; pwr = pwr_ctrl_i->pwr_lv_dbm[0]; } else { pwr_ctrl_en = false; pwr = 0; } halbb_set_pwr_macid_idx(bb, macid, pwr, pwr_ctrl_en, 0); /* only use pwr_tbl_0 */ } void halbb_pwr_ctrl_per_sta(struct bb_info *bb, u16 macid) { struct rtw_phl_stainfo_t *sta; struct bb_dtp_info *dtp = &bb->bb_pwr_ctrl_i.dtp_i[macid]; u8 lst_pwr_lv = 0; u8 rssi = 0; sta = bb->phl_sta_info[macid]; if (!sta) { BB_DBG(bb, DBG_PWR_CTRL, "NULL PHL STA info\n"); return; } if (is_sta_active(sta)) { rssi = (sta->hal_sta->rssi_stat.rssi) >> 1; lst_pwr_lv = dtp->last_pwr_lvl; dtp->dyn_tx_pwr_lvl = halbb_pwr_lvl_check(bb, rssi, lst_pwr_lv); BB_DBG(bb, DBG_PWR_CTRL, "STA=%d , RSSI: %d , GetPwrLv: %d\n", macid, rssi, dtp->dyn_tx_pwr_lvl); if (dtp->dyn_tx_pwr_lvl == TX_HP_LV_UNCHANGE || dtp->dyn_tx_pwr_lvl == lst_pwr_lv) { dtp->dyn_tx_pwr_lvl = lst_pwr_lv; BB_DBG(bb, DBG_PWR_CTRL, "DTP_lv not change: ((%d))\n", dtp->dyn_tx_pwr_lvl); return; } BB_DBG(bb, DBG_PWR_CTRL, "DTP_lv update: ((%d)) -> ((%d))\n", lst_pwr_lv, dtp->dyn_tx_pwr_lvl); dtp->last_pwr_lvl = dtp->dyn_tx_pwr_lvl; halbb_set_pwr_ctrl(bb, macid, dtp->dyn_tx_pwr_lvl); } } void halbb_pwr_ctrl(struct bb_info *bb) { struct bb_pwr_ctrl_info *pwr_ctrl = &bb->bb_pwr_ctrl_i; u16 i; if (!(bb->support_ability & BB_PWR_CTRL)) { /* Disable*/ halbb_pwr_ctrl_en(bb, false); return; } BB_DBG(bb, DBG_PWR_CTRL, "[%s]\n", __func__); /*Enable*/ halbb_pwr_ctrl_en(bb, true); for (i = 0; i < PHL_MAX_STA_NUM; i++) halbb_pwr_ctrl_per_sta( bb, i); BB_DBG(bb, DBG_PWR_CTRL, "pwr = %d\n", pwr_ctrl->pwr); } void halbb_pwr_ctrl_para_init(struct bb_info *bb) { struct bb_pwr_ctrl_info *pwr_ctrl_i = &bb->bb_pwr_ctrl_i; pwr_ctrl_i->set_pwr_th[0] = TX_PWR_TH_LVL1; pwr_ctrl_i->set_pwr_th[1] = TX_PWR_TH_LVL2; pwr_ctrl_i->set_pwr_th[2] = TX_PWR_TH_LVL3; pwr_ctrl_i->pwr_lv_dbm[0] = TX_PWR_LVL1; pwr_ctrl_i->pwr_lv_dbm[1] = TX_PWR_LVL2; pwr_ctrl_i->pwr_lv_dbm[2] = TX_PWR_LVL3; } void halbb_pwr_ctrl_txpwr_cfg(struct bb_info *bb, u8 pwr_lv1, u8 pwr_lv2, u8 pwr_lv3) { struct bb_pwr_ctrl_info *pwr_ctrl_i = &bb->bb_pwr_ctrl_i; pwr_ctrl_i->pwr_lv_dbm[0] = pwr_lv1; pwr_ctrl_i->pwr_lv_dbm[1] = pwr_lv2; pwr_ctrl_i->pwr_lv_dbm[2] = pwr_lv3; } void halbb_pwr_ctrl_th_cfg(struct bb_info *bb, u8 th_lv1, u8 th_lv2, u8 th_lv3) { struct bb_pwr_ctrl_info *pwr_ctrl_i = &bb->bb_pwr_ctrl_i; pwr_ctrl_i->set_pwr_th[0] = th_lv1; pwr_ctrl_i->set_pwr_th[1] = th_lv2; pwr_ctrl_i->set_pwr_th[2] = th_lv3; } void halbb_pwr_ctrl_init(struct bb_info *bb) { struct bb_pwr_ctrl_info *pwr_ctrl_i = &bb->bb_pwr_ctrl_i; u8 i = 0; if (!pwr_ctrl_i) { BB_DBG(bb, DBG_PWR_CTRL, "NULL pointer!\n"); return; } for (i = 0; i < PHL_MAX_STA_NUM; i++) { pwr_ctrl_i->dtp_i[i].last_pwr_lvl= TX_HP_LV_0; pwr_ctrl_i->dtp_i[i].dyn_tx_pwr_lvl= TX_HP_LV_0; } halbb_pwr_ctrl_para_init(bb); for (i = 0; i < HALBB_PWR_STATE_NUM; i++) pwr_ctrl_i->enhance_pwr_th[i] = 0xff; BB_DBG(bb, DBG_PWR_CTRL, "pwr = %d\n", pwr_ctrl_i->pwr); } void halbb_pwr_ctrl_dbg(struct bb_info *bb, char input[][16], u32 *_used, char *output, u32 *_out_len) { char help[] = "-h"; u32 val[10] = {0}; u8 i = 0; struct bb_pwr_ctrl_info *pwr_ctrl_i = &bb->bb_pwr_ctrl_i; if (_os_strcmp(input[1], help) == 0) { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "{Use Org TH and PWR} [pwr_ctrl] [0]\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "{Modify LV1(H)~LV3(L) Power} [pwr_ctrl] [1] [LV1] [LV2] [LV3]\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "{Modify LV1(H)~LV3(L) TH} [pwr_ctrl] [2] [LV1] [LV2] [LV3]\n"); return; } for (i = 0; i < 8; i++) { if (input[i + 1]) HALBB_SCAN(input[i + 1], DCMD_DECIMAL, &val[i]); } switch (val[0]) { case 0: halbb_pwr_ctrl_para_init(bb); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Reset Parameters\n"); break; case 1: halbb_pwr_ctrl_txpwr_cfg(bb, (u8)val[1], (u8)val[2], (u8)val[3]); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "PWRCTRL TxPWR for each LV = {%d, %d, %d}\n", pwr_ctrl_i->pwr_lv_dbm[0], pwr_ctrl_i->pwr_lv_dbm[1], pwr_ctrl_i->pwr_lv_dbm[2]); break; case 2: halbb_pwr_ctrl_th_cfg(bb, (u8)val[1], (u8)val[2], (u8)val[3]); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "PWRCTRL TH for each LV = {%d, %d, %d}\n", pwr_ctrl_i->set_pwr_th[0], pwr_ctrl_i->set_pwr_th[1], pwr_ctrl_i->set_pwr_th[2]); break; default: break; } } #endif bool halbb_set_pwr_ul_tb_ofst(struct bb_info *bb, s16 pw_ofst, enum phl_phy_idx phy_idx) { switch (bb->ic_type) { #ifdef BB_8852A_2_SUPPORT case BB_RTL8852A: halbb_set_pwr_ul_tb_ofst_8852a_2(bb, pw_ofst, phy_idx); break; #endif #ifdef BB_8852B_SUPPORT case BB_RTL8852B: halbb_set_pwr_ul_tb_ofst_8852b(bb, pw_ofst, phy_idx); break; #endif #ifdef BB_8852C_SUPPORT case BB_RTL8852C: halbb_set_pwr_ul_tb_ofst_8852c(bb, (s8)pw_ofst, phy_idx); break; #endif default: break; } return true; } void halbb_macid_ctrl_init(struct bb_info *bb) { u8 i = 0; u32 reg_ofst = 0; u32 ret_v = 0; BB_DBG(bb, DBG_PWR_CTRL, "[%s]\n", __func__); if (bb->hal_com == NULL) { BB_WARNING("hal_com is not allocated in halbb_macid_ctrl_init!!\n"); return; } for (i = 0; i < PHL_MAX_STA_NUM; i++) { reg_ofst = REG_PWRMACID_OFST + (i<<2) + 0xd200; ret_v = rtw_hal_mac_set_pwr_reg( bb->hal_com, 0, reg_ofst, 0); if (bb->hal_com->dbcc_en) ret_v = rtw_hal_mac_set_pwr_reg( bb->hal_com, 1, reg_ofst, 0); } } void halbb_tpu_mac_cr_init(struct bb_info *bb, enum phl_phy_idx phy_idx) { u32 tpu_array_type1[] = {0xD248, 0x07763333, 0xD220, 0x01ebf004, 0xD240, 0x0002f8ff}; u32 *tpu_array = NULL; u8 cr_size = 0; u8 i = 0; enum phl_band_idx band; band = (phy_idx == HW_PHY_0) ? HW_BAND_0 : HW_BAND_1; switch (bb->ic_type) { #if defined(BB_8852A_2_SUPPORT) || defined(BB_8852B_SUPPORT) case BB_RTL8852A: case BB_RTL8852B: tpu_array = (u32 *)tpu_array_type1; cr_size = sizeof(tpu_array_type1)/sizeof(u32); break; #endif default: break; } BB_DBG(bb, DBG_INIT, "[%s] size=%d\n", __func__, cr_size >> 1); if (!tpu_array) { BB_WARNING("[%s]\n", __func__); return; } for (i = 0; i < cr_size; i+=2) { BB_DBG(bb, DBG_INIT, "0x%x = 0x%x\n", tpu_array[i], tpu_array[i+1]); rtw_hal_mac_set_pwr_reg(bb->hal_com, band, tpu_array[i], tpu_array[i+1]); } } void halbb_pwr_dbg(struct bb_info *bb, char input[][16], u32 *_used, char *output, u32 *_out_len) { struct rtw_tpu_info *tpu = &bb->hal_com->band[bb->bb_phy_idx].rtw_tpu_i; struct rtw_tpu_pwr_by_rate_info *by_rate = &tpu->rtw_tpu_pwr_by_rate_i; struct rtw_tpu_pwr_imt_info *lmt = &tpu->rtw_tpu_pwr_imt_i; bool rpt_tmp; u16 size_tmp = 0; u32 val[10] = {0}; u16 i = 0, j = 0; u8 rate_idx = 0, path = 0; s8 *tmp_s8, val_s8; if (_os_strcmp(input[1], "-h") == 0) { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "dbg_en {en}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "show\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "set all {s(7,1) dB}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "set lgcy {idx} {s(7,1) dB}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "set mcs {path:0~3} {idx} {s(7,1) dB}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "ofst bw {all:255, 0~4: 80_80/160/80/40/20} {0:+, 1:-} {u(3,1) dB}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "ofst mode {all:255 0~4: HE/VHT/HT/Legacy/CCK} {0:+, 1:-} {u(3,1) dB}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "ref {cck, ofdm} {s(9,2) dB}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "ref ofst {s(8,3) dB}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "cw {0:rf_0db_cw(39), 1:tssi_16dBm_cw(300)} {val}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "lmt en {en}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "lmt {all, ru_all} {s(7,1) dB}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "tb_ofst {s(5,0) dB}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "tx_shap {ch} {shap_idx} {is_ofdm}\n"); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "tpu 0\n"); return; } if (_os_strcmp(input[1], "tpu") == 0) { halbb_set_tx_pow_ref(bb, bb->bb_phy_idx); rtw_hal_mac_write_pwr_by_rate_reg(bb->hal_com, (enum phl_band_idx)bb->bb_phy_idx); rtw_hal_mac_write_pwr_limit_rua_reg(bb->hal_com, (enum phl_band_idx)bb->bb_phy_idx); rtw_hal_mac_write_pwr_limit_reg(bb->hal_com, (enum phl_band_idx)bb->bb_phy_idx); rtw_hal_mac_write_pwr_ofst_mode(bb->hal_com, (enum phl_band_idx)bb->bb_phy_idx); rtw_hal_mac_write_pwr_ofst_bw(bb->hal_com, (enum phl_band_idx)bb->bb_phy_idx); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set all TPU component\n"); } else if (_os_strcmp(input[1], "dbg_en") == 0) { HALBB_SCAN(input[2], DCMD_HEX, &val[0]); rtw_hal_mac_set_tpu_mode(bb->hal_com, (enum rtw_tpu_op_mode)val[0], bb->bb_phy_idx); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "dbg_en=%d, Locking driver set TPU = %d\n", val[0], tpu->normal_mode_lock_en); } else if (_os_strcmp(input[1], "show") == 0) { BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "================\n\n"); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "[PW Ref]\n"); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s {%d}\n", "[base_cw_0db]", tpu->base_cw_0db); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s {%s dB}\n", "[ref_ofst]", halbb_print_sign_frac_digit2(bb, tpu->ofst_int, 8, 3)); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s {%s dBm} pw_cw=0x%03x\n", "[CCK]", halbb_print_sign_frac_digit2(bb, tpu->ref_pow_cck, 16, 2), tpu->ref_pow_cck_cw); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s {%s dBm} pw_cw=0x%03x\n", "[OFDM]", halbb_print_sign_frac_digit2(bb, tpu->ref_pow_ofdm, 16, 2), tpu->ref_pow_ofdm_cw); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "================\n\n"); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "[PW Offset] (s41)\n"); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-20s {%02d, %02d, %02d, %02d, %02d}\n", "[AX/AC/N/G/B]", tpu->pwr_ofst_mode[0], tpu->pwr_ofst_mode[1], tpu->pwr_ofst_mode[2], tpu->pwr_ofst_mode[3], tpu->pwr_ofst_mode[4]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-20s {%02d, %02d, %02d, %02d, %02d}\n", "[80_80/160/80/40/20]", tpu->pwr_ofst_bw[0], tpu->pwr_ofst_bw[1], tpu->pwr_ofst_bw[2], tpu->pwr_ofst_bw[3], tpu->pwr_ofst_bw[4]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "================\n\n"); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "[Pwr By Rate] (s71)\n"); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s {%02d, %02d, %02d, %02d}\n", "[CCK]", by_rate->pwr_by_rate_lgcy[0], by_rate->pwr_by_rate_lgcy[1], by_rate->pwr_by_rate_lgcy[2], by_rate->pwr_by_rate_lgcy[3]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s {%02d, %02d, %02d, %02d, %02d, %02d, %02d, %02d}\n","[Lgcy]", by_rate->pwr_by_rate_lgcy[4], by_rate->pwr_by_rate_lgcy[5], by_rate->pwr_by_rate_lgcy[6], by_rate->pwr_by_rate_lgcy[7], by_rate->pwr_by_rate_lgcy[8], by_rate->pwr_by_rate_lgcy[9], by_rate->pwr_by_rate_lgcy[10], by_rate->pwr_by_rate_lgcy[11]); for (i = 0; i < HAL_MAX_PATH; i++) { BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "[%d]%-7s {%02d, %02d, %02d, %02d, %02d, %02d, %02d, %02d, %02d, %02d, %02d, %02d}\n", i, "[OFDM]", by_rate->pwr_by_rate[i][0], by_rate->pwr_by_rate[i][1], by_rate->pwr_by_rate[i][2], by_rate->pwr_by_rate[i][3], by_rate->pwr_by_rate[i][4], by_rate->pwr_by_rate[i][5], by_rate->pwr_by_rate[i][6], by_rate->pwr_by_rate[i][7], by_rate->pwr_by_rate[i][8], by_rate->pwr_by_rate[i][9], by_rate->pwr_by_rate[i][10], by_rate->pwr_by_rate[i][11]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "[%d]%-7s {%02d, %02d, %02d, %02d}\n", i,"[DCM]", by_rate->pwr_by_rate[i][12], by_rate->pwr_by_rate[i][13], by_rate->pwr_by_rate[i][14], by_rate->pwr_by_rate[i][15]); } for (j = 0; j < TPU_SIZE_BF; j++) { BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "================\n\n"); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "[Pwr Lmt][%sBF]\n", (j == 0) ? "non-" : ""); for (i = 0; i < HAL_MAX_PATH; i++) { BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s [%d]{%02d}\n", "[CCK-20M]", i, lmt->pwr_lmt_cck_20m[i][j]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s [%d]{%02d}\n", "[CCK-40M]", i, lmt->pwr_lmt_cck_40m[i][j]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s [%d]{%02d}\n", "[Lgcy-20M]", i, lmt->pwr_lmt_lgcy_20m[i][j]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s [%d]{%02d, %02d, %02d, %02d, %02d, %02d, %02d, %02d}\n", "[OFDM-20M]", i, lmt->pwr_lmt_20m[i][0][j], lmt->pwr_lmt_20m[i][1][j], lmt->pwr_lmt_20m[i][2][j], lmt->pwr_lmt_20m[i][3][j], lmt->pwr_lmt_20m[i][4][j], lmt->pwr_lmt_20m[i][5][j], lmt->pwr_lmt_20m[i][6][j], lmt->pwr_lmt_20m[i][7][j]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s [%d]{%02d, %02d, %02d, %02d}\n", "[OFDM-40M]", i, lmt->pwr_lmt_40m[i][0][j], lmt->pwr_lmt_40m[i][1][j], lmt->pwr_lmt_40m[i][2][j], lmt->pwr_lmt_40m[i][3][j]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s [%d]{%02d, %02d}\n", "[OFDM-80M]", i, lmt->pwr_lmt_80m[i][0][j], lmt->pwr_lmt_80m[i][1][j]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s[%d]{%02d}\n", "[OFDM-160M]", i, lmt->pwr_lmt_160m[i][j]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s [%d]{%02d}\n", "[40m_0p5]", i, lmt->pwr_lmt_40m_0p5[i][j]); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s [%d]{%02d}\n", "[40m_2p5]", i, lmt->pwr_lmt_40m_2p5[i][j]); } } BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "================\n\n"); BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "[Pwr Lmt RUA]\n"); for (j = 0; j < TPU_SIZE_RUA; j++) { BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "[RU-%3d]\n", (j == 0) ? 26 : ((j == 1) ? 52 : 106)); for (i = 0; i < HAL_MAX_PATH; i++) { BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s [%d]{%02d, %02d, %02d, %02d, %02d, %02d, %02d, %02d}\n", "[OFDM-20M]", i, tpu->pwr_lmt_ru[i][j][0], tpu->pwr_lmt_ru[i][j][1], tpu->pwr_lmt_ru[i][j][2], tpu->pwr_lmt_ru[i][j][3], tpu->pwr_lmt_ru[i][j][4], tpu->pwr_lmt_ru[i][j][5], tpu->pwr_lmt_ru[i][j][6], tpu->pwr_lmt_ru[i][j][7]); } } BB_DBG_VAST(*_out_len, *_used, output + *_used, *_out_len - *_used, "================\n\n"); } else if (_os_strcmp(input[1], "cw") == 0) { HALBB_SCAN(input[2], DCMD_DECIMAL, &val[0]); HALBB_SCAN(input[3], DCMD_DECIMAL, &val[1]); if (val[0] == 0) { tpu->base_cw_0db = (u8)val[1]; BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "rf_cw_0dbm=%d\n", tpu->base_cw_0db); } else if (val[0] == 1) { tpu->tssi_16dBm_cw = (u16)val[1]; BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "tssi_16dBm_cw=%d\n", tpu->tssi_16dBm_cw); } else { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set Err\n"); return; } halbb_set_tx_pow_ref(bb, bb->bb_phy_idx); } else if (_os_strcmp(input[1], "ofst") == 0) { HALBB_SCAN(input[3], DCMD_DECIMAL, &val[0]); HALBB_SCAN(input[4], DCMD_DECIMAL, &val[1]); HALBB_SCAN(input[5], DCMD_DECIMAL, &val[2]); if (val[1] == 0) { if (val[2] > 7) { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "[Set Err] max = +3.5 dB\n"); return; } val_s8 = (s8)val[2]; } else { if (val[2] > 8) { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "[Set Err] max = -4 dB\n"); return; } val_s8 = (s8)val[2] * -1; } if (_os_strcmp(input[2], "bw") == 0) { if (val[0] == 255) { for (i = 0; i < TPU_SIZE_BW; i++) tpu->pwr_ofst_bw[i] = val_s8; } else if (val[0] >= TPU_SIZE_BW) { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set Err\n"); return; } else { tpu->pwr_ofst_bw[val[0]] = val_s8; } rtw_hal_mac_write_pwr_ofst_bw(bb->hal_com, (enum phl_band_idx)bb->bb_phy_idx); } else if (_os_strcmp(input[2], "mode") == 0) { if (val[0] == 255) { for (i = 0; i < TPU_SIZE_MODE; i++) tpu->pwr_ofst_mode[i] = val_s8; } else if (val[0] >= TPU_SIZE_MODE) { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set Err\n"); return; } else { tpu->pwr_ofst_mode[val[0]] = val_s8; } rtw_hal_mac_write_pwr_ofst_mode(bb->hal_com, (enum phl_band_idx)bb->bb_phy_idx); } else { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set Err\n"); return; } BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "[%s]pw ofst[%d]=(%s%d.%d)dB\n", (_os_strcmp(input[2], "bw") == 0) ? "BW" : "MODE", val[0], (val[1] == 0) ? "+" : "-", val[2] >> 1, (val[2] & 0x1) * 5); } else if (_os_strcmp(input[1], "ref") == 0) { if (_os_strcmp(input[2], "ofst") == 0) { HALBB_SCAN(input[3], DCMD_DECIMAL, &val[0]); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "ref_ofst=(%s)dB\n", halbb_print_sign_frac_digit2(bb, tpu->ofst_int, 8, 3)); } else { HALBB_SCAN(input[3], DCMD_DECIMAL, &val[0]); if (_os_strcmp(input[2], "ofdm") == 0) { tpu->ref_pow_ofdm = (s16)val[0]; BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s ref_pw={%s dBm} cw=0x%09x\n", "[OFDM]", halbb_print_sign_frac_digit2(bb, tpu->ref_pow_ofdm, 16, 2), tpu->ref_pow_ofdm_cw); } else if (_os_strcmp(input[2], "cck") == 0) { tpu->ref_pow_cck = (s16)val[0]; BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "%-10s ref_pw={%s dBm} cw=0x%09x\n", "[CCK]", halbb_print_sign_frac_digit2(bb, tpu->ref_pow_cck, 16, 2), tpu->ref_pow_cck_cw); } else { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set Err\n"); return; } //halbb_print_sign_frac_digit2(bb, val[0], 32, 2); //BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "ref_pw = (%s)dBm\n", bb->dbg_buf); } halbb_set_tx_pow_ref(bb, bb->bb_phy_idx); } else if (_os_strcmp(input[1], "set") == 0) { HALBB_SCAN(input[3], DCMD_DECIMAL, &val[0]); HALBB_SCAN(input[4], DCMD_DECIMAL, &val[1]); HALBB_SCAN(input[5], DCMD_DECIMAL, &val[2]); if (_os_strcmp(input[2], "lgcy") == 0) { rate_idx = (u8)val[0]; if (rate_idx > TPU_SIZE_PWR_TAB_lGCY) return; tpu->rtw_tpu_pwr_by_rate_i.pwr_by_rate_lgcy[rate_idx] = (s8)val[1]; BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "[TX Pw] lgcy[%d] = (%d.%d)dBm\n", rate_idx, val[1]>>1, (val[1] & 1)*5); } else if (_os_strcmp(input[2], "mcs") == 0) { path = (u8)val[0]; if (path > HAL_MAX_PATH) return; rate_idx = (u8)val[1]; if (rate_idx > TPU_SIZE_PWR_TAB) return; tpu->rtw_tpu_pwr_by_rate_i.pwr_by_rate[path][rate_idx] = (s8)val[2]; BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "[TX Pw] Path[%d] MCS[%d] = (%d.%d)dBm\n", path, rate_idx, val[2]>>1, (val[2] & 1)*5); } else if (_os_strcmp(input[2], "all") == 0) { HALBB_SCAN(input[3], DCMD_DECIMAL, &val[0]); for (i = 0; i < TPU_SIZE_PWR_TAB_lGCY; i++) tpu->rtw_tpu_pwr_by_rate_i.pwr_by_rate_lgcy[i] = (s8)val[0]; for (i = 0; i < HAL_MAX_PATH; i++) { for (j = 0; j < TPU_SIZE_PWR_TAB; j++) tpu->rtw_tpu_pwr_by_rate_i.pwr_by_rate[i][j] = (s8)val[0]; } BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "[TX Pw] All rate = (%d.%d)dBm\n", val[0]>>1, (val[0] & 1)*5); } else { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set Err\n"); return; } rtw_hal_mac_write_pwr_by_rate_reg(bb->hal_com, (enum phl_band_idx)bb->bb_phy_idx); } else if (_os_strcmp(input[1], "lmt") == 0) { if (_os_strcmp(input[2], "en") == 0) { HALBB_SCAN(input[3], DCMD_DECIMAL, &val[0]); tpu->pwr_lmt_en = (bool)val[0]; rtw_hal_mac_write_pwr_limit_en(bb->hal_com, (enum phl_band_idx)bb->bb_phy_idx); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "pwr_lmt_en = %d\n", tpu->pwr_lmt_en); } else if (_os_strcmp(input[2], "all") == 0) { HALBB_SCAN(input[3], DCMD_DECIMAL, &val[0]); size_tmp = sizeof(struct rtw_tpu_pwr_imt_info) / sizeof(s8); tmp_s8 = &lmt->pwr_lmt_cck_20m[0][0]; BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "pwr_lmt_size = %d\n", size_tmp); for (i = 0; i < size_tmp; i++) { *tmp_s8 = (u8)val[0]; tmp_s8++; } rtw_hal_mac_write_pwr_limit_reg(bb->hal_com, (enum phl_band_idx)bb->bb_phy_idx); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set all Pwr Lmt = (%d.%d)dBm\n", val[0]>>1, (val[0] & 1)*5); } else if (_os_strcmp(input[2], "ru_all") == 0) { HALBB_SCAN(input[3], DCMD_DECIMAL, &val[0]); size_tmp = HAL_MAX_PATH * TPU_SIZE_RUA * TPU_SIZE_BW20_SC; tmp_s8 = &tpu->pwr_lmt_ru[0][0][0]; BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "pwr_lmt_size_ru = %d\n", size_tmp); for (i = 0; i < size_tmp; i++) { *tmp_s8 = (s8)val[0]; tmp_s8++; } BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set all RUA Pwr Lmt = (%d.%d)dBm\n", val[0]>>1, (val[0] & 1)*5); rtw_hal_mac_write_pwr_limit_rua_reg(bb->hal_com, (enum phl_band_idx)bb->bb_phy_idx); } else { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set Err\n"); return; } } else if (_os_strcmp(input[1], "tb_ofst") == 0) { HALBB_SCAN(input[2], DCMD_DECIMAL, &val[0]); rpt_tmp = halbb_set_pwr_ul_tb_ofst(bb, (s16)val[0], bb->bb_phy_idx); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "[ULTB Ofst]Set succcess=%d, en = %d, pw_ofst=%d\n", rpt_tmp, val[0], (s16)val[1]); } else if (_os_strcmp(input[1], "tx_shap") == 0) { HALBB_SCAN(input[2], DCMD_DECIMAL, &val[0]); HALBB_SCAN(input[3], DCMD_DECIMAL, &val[1]); HALBB_SCAN(input[4], DCMD_DECIMAL, &val[2]); tpu->tx_ptrn_shap_idx = (u8)val[1]; halbb_set_tx_pow_pattern_shap(bb, (u8)val[0], (bool)val[2], bb->bb_phy_idx); BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "[Tx Shap] ch=%d, shap_idx=%d\n", val[0], tpu->tx_ptrn_shap_idx); } else { BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used, "Set Err\n"); } }