319 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			319 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | ||
|  | 
 | ||
|  | 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
 | ||
|  | } | ||
|  | 
 |