/**************************************************************************** Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT be copied by any method or incorporated into another program without the express written consent of Aerospace C.Power. This Information or any portion thereof remains the property of Aerospace C.Power. The Information contained herein is believed to be accurate and Aerospace C.Power assumes no responsibility or liability for its use in any way and conveys no license or title under any patent or copyright and makes no representation or warranty that this Information is free from patent or copyright infringement. ****************************************************************************/ #include "iot_config.h" #include "iot_errno_api.h" #include "iot_io.h" #include "iot_utils_api.h" #include "hw_phy_api.h" #include "hw_tonemask.h" #include "phy_txrx_pwr.h" #include "phy_bb.h" #include "phy_cfg.h" #include "phy_dfe_reg.h" #include "hw_reg_api.h" #include "phy_rxtd_reg.h" #include "mac_rx_descriptor_reg.h" #include "rx_desc_reg_api.h" /* get fd rms info depend on tonemask id */ uint32_t phy_tone_msk_rms_get_by_valid_tone(uint16_t valid_tone_num, uint8_t *fd_rms) { uint8_t band_idx = 0; uint32_t ret = ERR_FAIL; #if IOT_DTEST_ONLY_SUPPORT == 0 if (g_phy_ctxt.indep.tx_pwr_psd_fix_db > 0) { if (g_phy_cpu_share_ctxt.tx_pwr_ctl_ena) { *fd_rms = (uint8_t)( g_phy_ctxt.indep.tx_pwr_psd_fix_db - PHY_PWR_DIG_ATT_MAX); } else { *fd_rms = (uint8_t)( g_phy_ctxt.indep.tx_pwr_psd_fix_db); } return ERR_OK; } #endif for(band_idx = 0; band_idx < IOT_ARRAY_CNT(iot_plc_tonemask_rms_all); band_idx++) { if (iot_plc_tonemask_rms_all[band_idx].valid_tone_number == valid_tone_num) { #if IOT_DTEST_ONLY_SUPPORT == 0 if (g_phy_cpu_share_ctxt.tx_pwr_ctl_ena) #else if (0) #endif { *fd_rms = (uint8_t)( iot_plc_tonemask_rms_all[band_idx].fd_rms_max); } else { *fd_rms = (uint8_t)( iot_plc_tonemask_rms_all[band_idx].fd_rms_max - g_phy_ctxt.indep.tx_pwr_reduce_db); } ret = ERR_OK; break; } } #if IOT_DTEST_ONLY_SUPPORT == 0 if (!g_phy_cpu_share_ctxt.tx_pwr_ctl_ena) { *fd_rms += PHY_PWR_DIG_ATT_MAX; } #endif return ret; } /* kunlun2 pwr control */ const phy_fd_td_ana_full_t phy_fd_td_ana_full_tbl[] = { {IOT_SUPPORT_TONE_80_490, {56, 9, 7, 9, 12}, {PHY_FULL_PWR_DBUV, 125}}, {IOT_SUPPORT_TONE_100_230, {61, 9, 7, 9, 12}, {PHY_FULL_PWR_DBUV, 122}}, {IOT_SUPPORT_TONE_32_120, {63, 6, 7, 6, 12}, {PHY_FULL_PWR_DBUV, 121}}, {IOT_SUPPORT_TONE_72_120, {66, 0, 7, 0, 12}, {PHY_FULL_PWR_DBUV, 117}}, {IOT_SUPPORT_TONE_231_490, {58, 9, 7, 9, 12}, {PHY_FULL_PWR_DBUV, 125}}, {IOT_SUPPORT_TONE_240_370, {61, 9, 7, 9, 12}, {PHY_FULL_PWR_DBUV, 122}}, {IOT_SUPPORT_TONE_200_1000, {54, 0, 7, 0, 12}, {PHY_FULL_PWR_DBUV, 130}}, {IOT_SUPPORT_TONE_1160_1415, {59, 0, 7, 0, 12}, {PHY_FULL_PWR_DBUV, 125}}, {IOT_SUPPORT_TONE_200_500, {58, 3, 7, 3, 12}, {PHY_FULL_PWR_DBUV, 127}} }; uint32_t phy_fd_td_ana_full_get(uint32_t band_id, const phy_fd_td_ana_full_t *tbl, uint16_t tbl_len, uint8_t *fd_pwr_int, uint8_t *fd_pwr_frac, uint8_t *td_pwr, uint8_t *ana_pwr) { for (int i = 0; i < tbl_len; i++) { if (tbl[i].band_id == band_id) { *fd_pwr_int = tbl[i].fd_td_ana_full.fd_pwr_int; if (phy_get_pwr_ctl_en()) { *fd_pwr_frac = tbl[i].fd_td_ana_full.fd_pwr_frac; } else { *fd_pwr_frac = tbl[i].fd_td_ana_full.fd_pwr_frac_lp; } *td_pwr = tbl[i].fd_td_ana_full.td_pwr; *ana_pwr = tbl[i].fd_td_ana_full.ana_pwr; return ERR_OK; } } return ERR_INVAL; } uint32_t phy_tx_pwr_to_fd_td_ana_value( uint32_t hw_rate_id, uint32_t band_id, uint8_t uint_dbuv, uint8_t *fd_pwr_int, uint8_t *fd_pwr_frac, uint8_t *td_pwr, uint8_t *ana_pwr) { uint32_t ret = ERR_OK; uint8_t rms_delta = 0; /* get set delta */ rms_delta = PHY_FULL_PWR_DBUV - uint_dbuv; ret = phy_fd_td_ana_full_get(band_id, phy_fd_td_ana_full_tbl, IOT_ARRAY_CNT(phy_fd_td_ana_full_tbl), fd_pwr_int, fd_pwr_frac, td_pwr, ana_pwr); if (ret != ERR_OK) { iot_printf("phy fd_td_ana full power para get fail\n"); return ret; } #if HW_PLATFORM == HW_PLATFORM_FPGA /* without analog PA */ *fd_pwr_int = *fd_pwr_int - rms_delta; *ana_pwr = 0; #elif HW_PLATFORM == HW_PLATFORM_SILICON /* TD: -12/12 ,ana: -10.5/13.5 */ if (rms_delta < PHY_PWR_CTRL_THRESHHOLD) { /* ana 6db step*/ *ana_pwr -= rms_delta / PHY_PWR_ANA_STEP_LEN; *td_pwr -= rms_delta % PHY_PWR_ANA_STEP_LEN; } else if (rms_delta <= 2 * PHY_PWR_CTRL_THRESHHOLD) { *ana_pwr = 0; *td_pwr -= rms_delta - PHY_PWR_CTRL_THRESHHOLD; } else { *ana_pwr = 0; *td_pwr = PHY_PWR_TD_MIN; *fd_pwr_int -= rms_delta - PHY_PWR_CTRL_THRESHHOLD; } #endif (void)hw_rate_id; return ret; } uint32_t phy_get_default_tx_pwr(uint32_t band_id,uint8_t *uint_dbuv, uint8_t *dlt_max) { uint32_t ret = ERR_INVAL; uint8_t full_dbuv, lp_dbuv; for (int i = 0; i < IOT_ARRAY_CNT(phy_fd_td_ana_full_tbl); i++) { if (phy_fd_td_ana_full_tbl[i].band_id == band_id) { full_dbuv = phy_fd_td_ana_full_tbl[i].psd_full.full_dbuv; if (!phy_get_pwr_ctl_en()) { lp_dbuv = phy_fd_td_ana_full_tbl[i].psd_full.lp_dbuv; *dlt_max = full_dbuv - lp_dbuv; *uint_dbuv = lp_dbuv; return ERR_OK; } else { *dlt_max = 0; *uint_dbuv = full_dbuv; return ERR_OK; } } } return ret; } /* war for setting sack tx power. * Now adjust the power of each packet to control the power of all packets * by configuring registers. * so ana/td/fd frac/fd int all config to register. */ uint32_t phy_set_common_pwr_reg(uint32_t pwr_db) { uint8_t fd_pwr_int, fd_pwr_frac, td_pwr, ana_pwr; uint32_t hw_band_id = phy_def_hw_band_id_get(); uint32_t single_proto_band = phy_proto_single_band_id_get(); phy_tx_pwr_to_fd_td_ana_value(0, single_proto_band, pwr_db, &fd_pwr_int, &fd_pwr_frac, &td_pwr, &ana_pwr); /* set td and ana power to register */ phy_force_ana_td_power(true); phy_set_tx_pwr_td(td_pwr); phy_set_tx_pwr_ana(ana_pwr); phy_set_tx_pwr_fd_frac(fd_pwr_frac); phy_set_tx_pwr_fd_int(fd_pwr_int); /* war for fd int/frac invalid */ phy_tx_rms_set(0, hw_band_id, fd_pwr_int, fd_pwr_frac); phy_tx_rms_set(1, hw_band_id, fd_pwr_int, fd_pwr_frac); iot_printf("[ptr_dbg] set pwr_reg power:%d, td_pwr:%d, ana_pwr:%d, " "fd_frac:%d, fd_int:%d\n", pwr_db, td_pwr, ana_pwr, fd_pwr_frac, fd_pwr_int); return 0; } void phy_set_sack_tx_power(uint32_t pwr_db) { (void)pwr_db; } uint32_t phy_swagc_set(bool_t en) { return ERR_OK; } void phy_tx_resp_pwr_ctl_en( uint8_t fd_int_en, uint8_t fd_frac_en, uint8_t td_en, uint8_t ana_en) { (void)fd_int_en; (void)fd_frac_en; (void)td_en; (void)ana_en; } void phy_set_tx_resp_pwr( uint8_t fd_int, uint8_t fd_frac, uint8_t td, uint8_t ana) { (void)fd_int; (void)fd_frac; (void)td; (void)ana; } uint32_t phy_info_check_entry(void *mpdu_st, void *fc, uint32_t role, uint8_t mt_mode_sel) { (void)mpdu_st; (void)role; /* check beacon pkt */ frame_control_t *sg_fc = (frame_control_t *)fc; if(sg_fc->delimiter_type == 0) { if(g_phy_ctxt.indep.work_mode == PHY_MODE_TEST && (mt_mode_sel == CERT_TEST_CMD_ENTER_PHY_T)) { phy_channel_est_request(); } } return ERR_OK; } void phy_check_spur_cert_handle(uint16_t notch_alpha) { (void)notch_alpha; } uint32_t phy_work_mode_set(phy_work_mode_id mode) { if (mode < PHY_MODE_END) { g_phy_ctxt.indep.work_mode = mode; if (g_phy_ctxt.indep.work_mode == PHY_MODE_TEST && phy_get_g_mt_mode_sel() == CERT_TEST_CMD_ENTER_PHY_LP) { /* notch filter clear */ phy_anf_option_set(PHY_ANF_MODE_BYPASS,0,0,0); /* bypass fnf */ phy_fnf_option_set(PHY_FNF_MODE_BYPASS, 0, 0); /* clear to avoid mask over for time-varying spur */ phy_tone_mask_amp_phase_tab_load(&all_mask_amp_phase_table, phy_mask_id_get(), PHY_PROTO_TYPE_GET()); iot_printf("[BB] enter cert mode!\n"); } } return ERR_OK; } void phy_overstress_power_down(uint32_t dowm_db) { #if HW_PLATFORM >= HW_PLATFORM_FPGA uint32_t tx_power = phy_get_tx_pwr_limit(phy_proto_single_band_id_get()); if (tx_power > dowm_db) { tx_power -= dowm_db; } g_phy_ctxt.indep.ovs_ctxt.ovr_pwr = max(tx_power, MIN_TX_POWER); phy_set_tx_pwr_limit(tx_power); #else (void)dowm_db; #endif } void phy_overstress_power_up() { #if HW_PLATFORM >= HW_PLATFORM_FPGA /* ignore overstress power and set sw_set_power */ phy_set_tx_pwr_limit(g_phy_ctxt.dep.sw_set_pwr); #endif }