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
 | 
						|
}
 | 
						|
 |