Path: blob/master/ALFA-W1F1/RTL8814AU/hal/phydm/phydm_ccx.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13* The full GNU General Public License is included in this distribution in the14* file called LICENSE.15*16* Contact Information:17* wlanfae <[email protected]>18* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,19* Hsinchu 300, Taiwan.20*21* Larry Finger <[email protected]>22*23*****************************************************************************/2425#include "mp_precomp.h"26#include "phydm_precomp.h"2728void phydm_ccx_hw_restart(void *dm_void)29/*@Will Restart NHM/CLM/FAHM simultaneously*/30{31struct dm_struct *dm = (struct dm_struct *)dm_void;32u32 reg1 = 0;3334if (dm->support_ic_type & ODM_IC_11AC_SERIES)35reg1 = R_0x994;36#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT37else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)38reg1 = R_0x1e60;39#endif40else41reg1 = R_0x890;4243PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);44/*@disable NHM,CLM, FAHM*/45odm_set_bb_reg(dm, reg1, 0x7, 0x0);46odm_set_bb_reg(dm, reg1, BIT(8), 0x0);47odm_set_bb_reg(dm, reg1, BIT(8), 0x1);48}4950#ifdef FAHM_SUPPORT5152u16 phydm_hw_divider(void *dm_void, u16 numerator, u16 denumerator)53{54struct dm_struct *dm = (struct dm_struct *)dm_void;55u16 result = DEVIDER_ERROR;56u32 tmp_u32 = ((numerator << 16) | denumerator);57u32 reg_devider_input;58u32 reg;59u8 i;6061PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);6263if (dm->support_ic_type & ODM_IC_11AC_SERIES) {64reg_devider_input = 0x1cbc;65reg = 0x1f98;66} else {67reg_devider_input = 0x980;68reg = 0x9f0;69}7071odm_set_bb_reg(dm, reg_devider_input, MASKDWORD, tmp_u32);7273for (i = 0; i < 10; i++) {74ODM_delay_ms(1);75if (odm_get_bb_reg(dm, reg, BIT(24))) {76/*@Chk HW rpt is ready*/7778result = (u16)odm_get_bb_reg(dm, reg, MASKBYTE2);79break;80}81}82return result;83}8485void phydm_fahm_trigger(void *dm_void, u16 tgr_period)86{ /*@unit (4us)*/87struct dm_struct *dm = (struct dm_struct *)dm_void;88u32 fahm_reg1;8990if (dm->support_ic_type & ODM_IC_11AC_SERIES) {91odm_set_bb_reg(dm, R_0x1cf8, 0xffff00, tgr_period);9293fahm_reg1 = 0x994;94} else {95odm_set_bb_reg(dm, R_0x978, 0xff000000, (tgr_period & 0xff));96odm_set_bb_reg(dm, R_0x97c, 0xff, (tgr_period & 0xff00) >> 8);9798fahm_reg1 = 0x890;99}100101odm_set_bb_reg(dm, fahm_reg1, BIT(2), 0);102odm_set_bb_reg(dm, fahm_reg1, BIT(2), 1);103}104105void phydm_fahm_set_valid_cnt(void *dm_void, u8 numerator_sel,106u8 denominator_sel)107{108struct dm_struct *dm = (struct dm_struct *)dm_void;109struct ccx_info *ccx_info = &dm->dm_ccx_info;110u32 fahm_reg1;111112PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);113114if (ccx_info->fahm_nume_sel == numerator_sel &&115ccx_info->fahm_denom_sel == denominator_sel) {116PHYDM_DBG(dm, DBG_ENV_MNTR, "no need to update\n");117return;118}119120ccx_info->fahm_nume_sel = numerator_sel;121ccx_info->fahm_denom_sel = denominator_sel;122123if (dm->support_ic_type & ODM_IC_11AC_SERIES)124fahm_reg1 = 0x994;125else126fahm_reg1 = 0x890;127128odm_set_bb_reg(dm, fahm_reg1, 0xe0, numerator_sel);129odm_set_bb_reg(dm, fahm_reg1, 0x7000, denominator_sel);130}131132void phydm_fahm_get_result(void *dm_void)133{134struct dm_struct *dm = (struct dm_struct *)dm_void;135u16 fahm_cnt[12]; /*packet count*/136u16 fahm_rpt[12]; /*percentage*/137u16 denominator; /*@fahm_denominator packet count*/138u32 reg_rpt, reg_rpt_2;139u32 reg_tmp;140boolean is_ready = false;141u8 i;142143PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);144145if (dm->support_ic_type & ODM_IC_11AC_SERIES) {146reg_rpt = 0x1f80;147reg_rpt_2 = 0x1f98;148} else {149reg_rpt = 0x9d8;150reg_rpt_2 = 0x9f0;151}152153for (i = 0; i < 3; i++) {154if (odm_get_bb_reg(dm, reg_rpt_2, BIT(31))) {155/*@Chk HW rpt is ready*/156is_ready = true;157break;158}159ODM_delay_ms(1);160}161162if (!is_ready)163return;164165/*@Get FAHM Denominator*/166denominator = (u16)odm_get_bb_reg(dm, reg_rpt_2, MASKLWORD);167168PHYDM_DBG(dm, DBG_ENV_MNTR, "Reg[0x%x] fahm_denmrtr = %d\n", reg_rpt_2,169denominator);170171/*@Get FAHM nemerator*/172for (i = 0; i < 6; i++) {173reg_tmp = odm_get_bb_reg(dm, reg_rpt + (i << 2), MASKDWORD);174175PHYDM_DBG(dm, DBG_ENV_MNTR, "Reg[0x%x] fahm_denmrtr = %d\n",176reg_rpt + (i * 4), reg_tmp);177178fahm_cnt[i * 2] = (u16)(reg_tmp & MASKLWORD);179fahm_cnt[i * 2 + 1] = (u16)((reg_tmp & MASKHWORD) >> 16);180}181182for (i = 0; i < 12; i++)183fahm_rpt[i] = phydm_hw_divider(dm, fahm_cnt[i], denominator);184185PHYDM_DBG(dm, DBG_ENV_MNTR,186"FAHM_RPT_cnt[10:0]=[%d, %d, %d, %d, %d(IGI), %d, %d, %d, %d, %d, %d, %d]\n",187fahm_cnt[11], fahm_cnt[10], fahm_cnt[9],188fahm_cnt[8], fahm_cnt[7], fahm_cnt[6],189fahm_cnt[5], fahm_cnt[4], fahm_cnt[3],190fahm_cnt[2], fahm_cnt[1], fahm_cnt[0]);191192PHYDM_DBG(dm, DBG_ENV_MNTR,193"FAHM_RPT[10:0]=[%d, %d, %d, %d, %d(IGI), %d, %d, %d, %d, %d, %d, %d]\n",194fahm_rpt[11], fahm_rpt[10], fahm_rpt[9], fahm_rpt[8],195fahm_rpt[7], fahm_rpt[6], fahm_rpt[5], fahm_rpt[4],196fahm_rpt[3], fahm_rpt[2], fahm_rpt[1], fahm_rpt[0]);197}198199void phydm_fahm_set_th_by_igi(void *dm_void, u8 igi)200{201struct dm_struct *dm = (struct dm_struct *)dm_void;202struct ccx_info *ccx_info = &dm->dm_ccx_info;203u32 val = 0;204u8 f_th[11]; /*@FAHM Threshold*/205u8 rssi_th[11]; /*@in RSSI scale*/206u8 th_gap = 2 * IGI_TO_NHM_TH_MULTIPLIER; /*unit is 0.5dB for FAHM*/207u8 i;208209PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);210211if (ccx_info->env_mntr_igi == igi) {212PHYDM_DBG(dm, DBG_ENV_MNTR,213"No need to update FAHM_th, IGI=0x%x\n",214ccx_info->env_mntr_igi);215return;216}217218ccx_info->env_mntr_igi = igi; /*@bkp IGI*/219220if (igi >= CCA_CAP)221f_th[0] = (igi - CCA_CAP) * IGI_TO_NHM_TH_MULTIPLIER;222else223f_th[0] = 0;224225rssi_th[0] = igi - 10 - CCA_CAP;226227for (i = 1; i <= 10; i++) {228f_th[i] = f_th[0] + th_gap * i;229rssi_th[i] = rssi_th[0] + (i << 1);230}231232PHYDM_DBG(dm, DBG_ENV_MNTR,233"FAHM_RSSI_th[10:0]=[%d, %d, %d, (IGI)%d, %d, %d, %d, %d, %d, %d, %d]\n",234rssi_th[10], rssi_th[9], rssi_th[8], rssi_th[7], rssi_th[6],235rssi_th[5], rssi_th[4], rssi_th[3], rssi_th[2], rssi_th[1],236rssi_th[0]);237238if (dm->support_ic_type & ODM_IC_11AC_SERIES) {239val = BYTE_2_DWORD(0, f_th[2], f_th[1], f_th[0]);240odm_set_bb_reg(dm, R_0x1c38, 0xffffff00, val);241val = BYTE_2_DWORD(0, f_th[5], f_th[4], f_th[3]);242odm_set_bb_reg(dm, R_0x1c78, 0xffffff00, val);243val = BYTE_2_DWORD(0, 0, f_th[7], f_th[6]);244odm_set_bb_reg(dm, R_0x1c7c, 0xffff0000, val);245val = BYTE_2_DWORD(0, f_th[10], f_th[9], f_th[8]);246odm_set_bb_reg(dm, R_0x1cb8, 0xffffff00, val);247} else {248val = BYTE_2_DWORD(f_th[3], f_th[2], f_th[1], f_th[0]);249odm_set_bb_reg(dm, R_0x970, MASKDWORD, val);250val = BYTE_2_DWORD(f_th[7], f_th[6], f_th[5], f_th[4]);251odm_set_bb_reg(dm, R_0x974, MASKDWORD, val);252val = BYTE_2_DWORD(0, f_th[10], f_th[9], f_th[8]);253odm_set_bb_reg(dm, R_0x978, 0xffffff, val);254}255}256257void phydm_fahm_init(void *dm_void)258{259struct dm_struct *dm = (struct dm_struct *)dm_void;260struct ccx_info *ccx_info = &dm->dm_ccx_info;261u32 fahm_reg1;262u8 denumerator_sel = 0;263264PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);265PHYDM_DBG(dm, DBG_ENV_MNTR, "IGI=0x%x\n",266dm->dm_dig_table.cur_ig_value);267268if (dm->support_ic_type & ODM_IC_11AC_SERIES)269fahm_reg1 = 0x994;270else271fahm_reg1 = 0x890;272273ccx_info->fahm_period = 65535;274275odm_set_bb_reg(dm, fahm_reg1, 0x6, 3); /*@FAHM HW block enable*/276277denumerator_sel = FAHM_INCLD_FA | FAHM_INCLD_CRC_OK | FAHM_INCLD_CRC_ER;278phydm_fahm_set_valid_cnt(dm, FAHM_INCLD_FA, denumerator_sel);279phydm_fahm_set_th_by_igi(dm, dm->dm_dig_table.cur_ig_value);280}281282void phydm_fahm_dbg(void *dm_void, char input[][16], u32 *_used, char *output,283u32 *_out_len)284{285struct dm_struct *dm = (struct dm_struct *)dm_void;286struct ccx_info *ccx_info = &dm->dm_ccx_info;287char help[] = "-h";288u32 var1[10] = {0};289u32 used = *_used;290u32 out_len = *_out_len;291u32 i;292293for (i = 0; i < 2; i++) {294if (input[i + 1])295PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);296}297298if ((strcmp(input[1], help) == 0)) {299PDM_SNPF(out_len, used, output + used, out_len - used,300"{1: trigger, 2:get result}\n");301PDM_SNPF(out_len, used, output + used, out_len - used,302"{3: MNTR mode sel} {1: driver, 2. FW}\n");303return;304} else if (var1[0] == 1) { /* Set & trigger CLM */305306phydm_fahm_set_th_by_igi(dm, dm->dm_dig_table.cur_ig_value);307phydm_fahm_trigger(dm, ccx_info->fahm_period);308PDM_SNPF(out_len, used, output + used, out_len - used,309"Monitor FAHM for %d * 4us\n", ccx_info->fahm_period);310311} else if (var1[0] == 2) { /* @Get CLM results */312313phydm_fahm_get_result(dm);314PDM_SNPF(out_len, used, output + used, out_len - used,315"FAHM_result=%d us\n", (ccx_info->clm_result << 2));316317} else {318PDM_SNPF(out_len, used, output + used, out_len - used,319"Error\n");320}321322*_used = used;323*_out_len = out_len;324}325326#endif /*@#ifdef FAHM_SUPPORT*/327328#ifdef NHM_SUPPORT329330void phydm_nhm_racing_release(void *dm_void)331{332struct dm_struct *dm = (struct dm_struct *)dm_void;333struct ccx_info *ccx = &dm->dm_ccx_info;334u32 value32 = 0;335336PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);337PHYDM_DBG(dm, DBG_ENV_MNTR, "lv:(%d)->(0)\n", ccx->nhm_set_lv);338339ccx->nhm_ongoing = false;340ccx->nhm_set_lv = NHM_RELEASE;341342if (!(ccx->nhm_app == NHM_BACKGROUND || ccx->nhm_app == NHM_ACS)) {343phydm_pause_func(dm, F00_DIG, PHYDM_RESUME,344PHYDM_PAUSE_LEVEL_1, 1, &value32);345}346347ccx->nhm_app = NHM_BACKGROUND;348}349350u8 phydm_nhm_racing_ctrl(void *dm_void, enum phydm_nhm_level nhm_lv)351{352struct dm_struct *dm = (struct dm_struct *)dm_void;353struct ccx_info *ccx = &dm->dm_ccx_info;354u8 set_result = PHYDM_SET_SUCCESS;355/*@acquire to control NHM API*/356357PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_ongoing=%d, lv:(%d)->(%d)\n",358ccx->nhm_ongoing, ccx->nhm_set_lv, nhm_lv);359if (ccx->nhm_ongoing) {360if (nhm_lv <= ccx->nhm_set_lv) {361set_result = PHYDM_SET_FAIL;362} else {363phydm_ccx_hw_restart(dm);364ccx->nhm_ongoing = false;365}366}367368if (set_result)369ccx->nhm_set_lv = nhm_lv;370371PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm racing success=%d\n", set_result);372return set_result;373}374375void phydm_nhm_trigger(void *dm_void)376{377struct dm_struct *dm = (struct dm_struct *)dm_void;378struct ccx_info *ccx = &dm->dm_ccx_info;379u32 nhm_reg1 = 0;380381if (dm->support_ic_type & ODM_IC_11AC_SERIES)382nhm_reg1 = R_0x994;383#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT384else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)385nhm_reg1 = R_0x1e60;386#endif387else388nhm_reg1 = R_0x890;389PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);390391/* @Trigger NHM*/392pdm_set_reg(dm, nhm_reg1, BIT(1), 0);393pdm_set_reg(dm, nhm_reg1, BIT(1), 1);394ccx->nhm_trigger_time = dm->phydm_sys_up_time;395ccx->nhm_rpt_stamp++;396ccx->nhm_ongoing = true;397}398399boolean400phydm_nhm_check_rdy(void *dm_void)401{402struct dm_struct *dm = (struct dm_struct *)dm_void;403boolean is_ready = false;404u32 reg1 = 0, reg1_bit = 0;405406if (dm->support_ic_type & ODM_IC_11AC_SERIES) {407reg1 = R_0xfb4;408reg1_bit = 16;409#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT410} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {411reg1 = R_0x2d4c;412reg1_bit = 16;413#endif414} else {415reg1 = R_0x8b4;416if (dm->support_ic_type & (ODM_RTL8710B | ODM_RTL8721D |417ODM_RTL8710C))418reg1_bit = 25;419else420reg1_bit = 17;421}422if (odm_get_bb_reg(dm, reg1, BIT(reg1_bit)))423is_ready = true;424425PHYDM_DBG(dm, DBG_ENV_MNTR, "NHM rdy=%d\n", is_ready);426427return is_ready;428}429430void phydm_nhm_get_utility(void *dm_void)431{432struct dm_struct *dm = (struct dm_struct *)dm_void;433struct ccx_info *ccx = &dm->dm_ccx_info;434u8 nhm_rpt_non_0 = 0;435436if (ccx->nhm_rpt_sum >= ccx->nhm_result[0]) {437nhm_rpt_non_0 = ccx->nhm_rpt_sum - ccx->nhm_result[0];438ccx->nhm_ratio = (nhm_rpt_non_0 * 100) >> 8;439} else {440PHYDM_DBG(dm, DBG_ENV_MNTR, "[warning] nhm_rpt_sum invalid\n");441ccx->nhm_ratio = 0;442}443444PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_ratio=%d\n", ccx->nhm_ratio);445}446447boolean448phydm_nhm_get_result(void *dm_void)449{450struct dm_struct *dm = (struct dm_struct *)dm_void;451struct ccx_info *ccx = &dm->dm_ccx_info;452u32 value32 = 0;453u8 i = 0;454u32 nhm_reg1 = 0;455u16 nhm_rpt_sum_tmp = 0;456457if (dm->support_ic_type & ODM_IC_11AC_SERIES)458nhm_reg1 = R_0x994;459#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT460else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)461nhm_reg1 = R_0x1e60;462#endif463else464nhm_reg1 = R_0x890;465PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);466467if (!(dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F |468ODM_RTL8197G)))469pdm_set_reg(dm, nhm_reg1, BIT(1), 0);470471if (!(phydm_nhm_check_rdy(dm))) {472PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM report Fail\n");473phydm_nhm_racing_release(dm);474return false;475}476477if (dm->support_ic_type & ODM_IC_11AC_SERIES) {478value32 = odm_read_4byte(dm, R_0xfa8);479odm_move_memory(dm, &ccx->nhm_result[0], &value32, 4);480481value32 = odm_read_4byte(dm, R_0xfac);482odm_move_memory(dm, &ccx->nhm_result[4], &value32, 4);483484value32 = odm_read_4byte(dm, R_0xfb0);485odm_move_memory(dm, &ccx->nhm_result[8], &value32, 4);486487/*@Get NHM duration*/488value32 = odm_read_4byte(dm, R_0xfb4);489ccx->nhm_duration = (u16)(value32 & MASKLWORD);490#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT491} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {492value32 = odm_read_4byte(dm, R_0x2d40);493odm_move_memory(dm, &ccx->nhm_result[0], &value32, 4);494495value32 = odm_read_4byte(dm, R_0x2d44);496odm_move_memory(dm, &ccx->nhm_result[4], &value32, 4);497498value32 = odm_read_4byte(dm, R_0x2d48);499odm_move_memory(dm, &ccx->nhm_result[8], &value32, 4);500501/*@Get NHM duration*/502value32 = odm_read_4byte(dm, R_0x2d4c);503ccx->nhm_duration = (u16)(value32 & MASKLWORD);504#endif505} else {506value32 = odm_read_4byte(dm, R_0x8d8);507odm_move_memory(dm, &ccx->nhm_result[0], &value32, 4);508509value32 = odm_read_4byte(dm, R_0x8dc);510odm_move_memory(dm, &ccx->nhm_result[4], &value32, 4);511512value32 = odm_get_bb_reg(dm, R_0x8d0, 0xffff0000);513odm_move_memory(dm, &ccx->nhm_result[8], &value32, 2);514515value32 = odm_read_4byte(dm, R_0x8d4);516517ccx->nhm_result[10] = (u8)((value32 & MASKBYTE2) >> 16);518ccx->nhm_result[11] = (u8)((value32 & MASKBYTE3) >> 24);519520/*@Get NHM duration*/521ccx->nhm_duration = (u16)(value32 & MASKLWORD);522}523524/* sum all nhm_result */525if (ccx->nhm_period >= 65530) {526value32 = (ccx->nhm_duration * 100) >> 16;527PHYDM_DBG(dm, DBG_ENV_MNTR,528"NHM valid time = %d, valid: %d percent\n",529ccx->nhm_duration, value32);530}531532for (i = 0; i < NHM_RPT_NUM; i++)533nhm_rpt_sum_tmp += (u16)ccx->nhm_result[i];534535ccx->nhm_rpt_sum = (u8)nhm_rpt_sum_tmp;536537PHYDM_DBG(dm, DBG_ENV_MNTR,538"NHM_Rpt[%d](H->L)[%d %d %d %d %d %d %d %d %d %d %d %d]\n",539ccx->nhm_rpt_stamp, ccx->nhm_result[11], ccx->nhm_result[10],540ccx->nhm_result[9], ccx->nhm_result[8], ccx->nhm_result[7],541ccx->nhm_result[6], ccx->nhm_result[5], ccx->nhm_result[4],542ccx->nhm_result[3], ccx->nhm_result[2], ccx->nhm_result[1],543ccx->nhm_result[0]);544545phydm_nhm_racing_release(dm);546547if (nhm_rpt_sum_tmp > 255) {548PHYDM_DBG(dm, DBG_ENV_MNTR,549"[Warning] Invalid NHM RPT, total=%d\n",550nhm_rpt_sum_tmp);551return false;552}553554return true;555}556557void phydm_nhm_set_th_reg(void *dm_void)558{559struct dm_struct *dm = (struct dm_struct *)dm_void;560struct ccx_info *ccx = &dm->dm_ccx_info;561u32 reg1 = 0, reg2 = 0, reg3 = 0, reg4 = 0, reg4_bit = 0;562u32 val = 0;563564PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);565566if (dm->support_ic_type & ODM_IC_11AC_SERIES) {567reg1 = R_0x994;568reg2 = R_0x998;569reg3 = R_0x99c;570reg4 = R_0x9a0;571reg4_bit = MASKBYTE0;572#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT573} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {574reg1 = R_0x1e60;575reg2 = R_0x1e44;576reg3 = R_0x1e48;577reg4 = R_0x1e5c;578reg4_bit = MASKBYTE2;579#endif580} else {581reg1 = R_0x890;582reg2 = R_0x898;583reg3 = R_0x89c;584reg4 = R_0xe28;585reg4_bit = MASKBYTE0;586}587588/*Set NHM threshold*/ /*Unit: PWdB U(8,1)*/589val = BYTE_2_DWORD(ccx->nhm_th[3], ccx->nhm_th[2],590ccx->nhm_th[1], ccx->nhm_th[0]);591pdm_set_reg(dm, reg2, MASKDWORD, val);592val = BYTE_2_DWORD(ccx->nhm_th[7], ccx->nhm_th[6],593ccx->nhm_th[5], ccx->nhm_th[4]);594pdm_set_reg(dm, reg3, MASKDWORD, val);595pdm_set_reg(dm, reg4, reg4_bit, ccx->nhm_th[8]);596val = BYTE_2_DWORD(0, 0, ccx->nhm_th[10], ccx->nhm_th[9]);597pdm_set_reg(dm, reg1, 0xffff0000, val);598599PHYDM_DBG(dm, DBG_ENV_MNTR,600"Update NHM_th[H->L]=[%d %d %d %d %d %d %d %d %d %d %d]\n",601ccx->nhm_th[10], ccx->nhm_th[9], ccx->nhm_th[8],602ccx->nhm_th[7], ccx->nhm_th[6], ccx->nhm_th[5],603ccx->nhm_th[4], ccx->nhm_th[3], ccx->nhm_th[2],604ccx->nhm_th[1], ccx->nhm_th[0]);605}606607boolean608phydm_nhm_th_update_chk(void *dm_void, enum nhm_application nhm_app, u8 *nhm_th,609u32 *igi_new)610{611struct dm_struct *dm = (struct dm_struct *)dm_void;612struct ccx_info *ccx = &dm->dm_ccx_info;613boolean is_update = false;614u8 igi_curr = phydm_get_igi(dm, BB_PATH_A);615u8 nhm_igi_th_11k_low[NHM_TH_NUM] = {0x12, 0x15, 0x18, 0x1b, 0x1e,6160x23, 0x28, 0x2c, 0x78,6170x78, 0x78};618u8 nhm_igi_th_11k_high[NHM_TH_NUM] = {0x1e, 0x23, 0x28, 0x2d, 0x32,6190x37, 0x78, 0x78, 0x78, 0x78,6200x78};621u8 nhm_igi_th_xbox[NHM_TH_NUM] = {0x1a, 0x2c, 0x2e, 0x30, 0x32, 0x34,6220x36, 0x38, 0x3a, 0x3c, 0x3d};623u8 i = 0;624u8 th_tmp = igi_curr - CCA_CAP;625u8 th_step = 2;626627PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);628PHYDM_DBG(dm, DBG_ENV_MNTR, "App=%d, nhm_igi=0x%x, igi_curr=0x%x\n",629nhm_app, ccx->nhm_igi, igi_curr);630631if (igi_curr < 0x10) /* Protect for invalid IGI*/632return false;633634switch (nhm_app) {635case NHM_BACKGROUND: /* @Get IGI form driver parameter(cur_ig_value)*/636if (ccx->nhm_igi != igi_curr || ccx->nhm_app != nhm_app) {637is_update = true;638*igi_new = (u32)igi_curr;639640#ifdef NHM_DYM_PW_TH_SUPPORT641if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) &&642ccx->nhm_dym_pw_th_en) {643th_tmp = MAX_2(igi_curr - DYM_PWTH_CCA_CAP, 0);644th_step = 3;645}646#endif647648nhm_th[0] = (u8)IGI_2_NHM_TH(th_tmp);649650for (i = 1; i <= 10; i++)651nhm_th[i] = nhm_th[0] +652IGI_2_NHM_TH(th_step * i);653654}655break;656657case NHM_ACS:658if (ccx->nhm_igi != igi_curr || ccx->nhm_app != nhm_app) {659is_update = true;660*igi_new = (u32)igi_curr;661nhm_th[0] = (u8)IGI_2_NHM_TH(igi_curr - CCA_CAP);662for (i = 1; i <= 10; i++)663nhm_th[i] = nhm_th[0] + IGI_2_NHM_TH(2 * i);664}665break;666667case IEEE_11K_HIGH:668is_update = true;669*igi_new = 0x2c;670for (i = 0; i < NHM_TH_NUM; i++)671nhm_th[i] = IGI_2_NHM_TH(nhm_igi_th_11k_high[i]);672break;673674case IEEE_11K_LOW:675is_update = true;676*igi_new = 0x20;677for (i = 0; i < NHM_TH_NUM; i++)678nhm_th[i] = IGI_2_NHM_TH(nhm_igi_th_11k_low[i]);679break;680681case INTEL_XBOX:682is_update = true;683*igi_new = 0x36;684for (i = 0; i < NHM_TH_NUM; i++)685nhm_th[i] = IGI_2_NHM_TH(nhm_igi_th_xbox[i]);686break;687688case NHM_DBG: /*@Get IGI form register*/689igi_curr = phydm_get_igi(dm, BB_PATH_A);690if (ccx->nhm_igi != igi_curr || ccx->nhm_app != nhm_app) {691is_update = true;692*igi_new = (u32)igi_curr;693nhm_th[0] = (u8)IGI_2_NHM_TH(igi_curr - CCA_CAP);694for (i = 1; i <= 10; i++)695nhm_th[i] = nhm_th[0] + IGI_2_NHM_TH(2 * i);696}697break;698}699700if (is_update) {701PHYDM_DBG(dm, DBG_ENV_MNTR, "[Update NHM_TH] igi_RSSI=%d\n",702IGI_2_RSSI(*igi_new));703704for (i = 0; i < NHM_TH_NUM; i++) {705PHYDM_DBG(dm, DBG_ENV_MNTR, "NHM_th[%d](RSSI) = %d\n",706i, NTH_TH_2_RSSI(nhm_th[i]));707}708} else {709PHYDM_DBG(dm, DBG_ENV_MNTR, "No need to update NHM_TH\n");710}711return is_update;712}713714void phydm_nhm_set(void *dm_void, enum nhm_option_txon_all include_tx,715enum nhm_option_cca_all include_cca,716enum nhm_divider_opt_all divi_opt,717enum nhm_application nhm_app, u16 period)718{719struct dm_struct *dm = (struct dm_struct *)dm_void;720struct ccx_info *ccx = &dm->dm_ccx_info;721u8 nhm_th[NHM_TH_NUM] = {0};722u32 igi = 0x20;723u32 reg1 = 0, reg2 = 0;724u32 val_tmp = 0;725726PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);727728PHYDM_DBG(dm, DBG_ENV_MNTR,729"incld{tx, cca}={%d, %d}, divi_opt=%d, period=%d\n",730include_tx, include_cca, divi_opt, period);731732if (dm->support_ic_type & ODM_IC_11AC_SERIES) {733reg1 = R_0x994;734reg2 = R_0x990;735#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT736} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {737reg1 = R_0x1e60;738reg2 = R_0x1e40;739#endif740} else {741reg1 = R_0x890;742reg2 = R_0x894;743}744745/*Set disable_ignore_cca, disable_ignore_txon, ccx_en*/746if (include_tx != ccx->nhm_include_txon ||747include_cca != ccx->nhm_include_cca ||748divi_opt != ccx->nhm_divider_opt) {749/* some old ic is not supported on NHM divider option */750if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8723B |751ODM_RTL8195A | ODM_RTL8192E)) {752val_tmp = (u32)((include_tx << 2) |753(include_cca << 1) | 1);754pdm_set_reg(dm, reg1, 0x700, val_tmp);755} else {756val_tmp = (u32)BIT_2_BYTE(divi_opt, include_tx,757include_cca, 1);758pdm_set_reg(dm, reg1, 0xf00, val_tmp);759}760ccx->nhm_include_txon = include_tx;761ccx->nhm_include_cca = include_cca;762ccx->nhm_divider_opt = divi_opt;763#if 0764PHYDM_DBG(dm, DBG_ENV_MNTR,765"val_tmp=%d, incld{tx, cca}={%d, %d}, divi_opt=%d, period=%d\n",766val_tmp, include_tx, include_cca, divi_opt, period);767768PHYDM_DBG(dm, DBG_ENV_MNTR, "0x994=0x%x\n",769odm_get_bb_reg(dm, 0x994, 0xf00));770#endif771}772773/*Set NHM period*/774if (period != ccx->nhm_period) {775pdm_set_reg(dm, reg2, MASKHWORD, period);776PHYDM_DBG(dm, DBG_ENV_MNTR,777"Update NHM period ((%d)) -> ((%d))\n",778ccx->nhm_period, period);779780ccx->nhm_period = period;781}782783/*Set NHM threshold*/784if (phydm_nhm_th_update_chk(dm, nhm_app, &(nhm_th[0]), &igi)) {785/*Pause IGI*/786if (nhm_app == NHM_BACKGROUND || nhm_app == NHM_ACS) {787PHYDM_DBG(dm, DBG_ENV_MNTR, "DIG Free Run\n");788} else if (phydm_pause_func(dm, F00_DIG, PHYDM_PAUSE,789PHYDM_PAUSE_LEVEL_1, 1, &igi)790== PAUSE_FAIL) {791PHYDM_DBG(dm, DBG_ENV_MNTR, "pause DIG Fail\n");792return;793} else {794PHYDM_DBG(dm, DBG_ENV_MNTR, "pause DIG=0x%x\n", igi);795}796ccx->nhm_app = nhm_app;797ccx->nhm_igi = (u8)igi;798odm_move_memory(dm, &ccx->nhm_th[0], &nhm_th, NHM_TH_NUM);799800/*Set NHM th*/801phydm_nhm_set_th_reg(dm);802}803}804805u8 phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para)806{807struct dm_struct *dm = (struct dm_struct *)dm_void;808u16 nhm_time = 0; /*unit: 4us*/809810PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);811812if (nhm_para->mntr_time == 0)813return PHYDM_SET_FAIL;814815if (nhm_para->nhm_lv >= NHM_MAX_NUM) {816PHYDM_DBG(dm, DBG_ENV_MNTR, "Wrong LV=%d\n", nhm_para->nhm_lv);817return PHYDM_SET_FAIL;818}819820if (phydm_nhm_racing_ctrl(dm, nhm_para->nhm_lv) == PHYDM_SET_FAIL)821return PHYDM_SET_FAIL;822823if (nhm_para->mntr_time >= 262)824nhm_time = NHM_PERIOD_MAX;825else826nhm_time = nhm_para->mntr_time * MS_TO_4US_RATIO;827828phydm_nhm_set(dm, nhm_para->incld_txon, nhm_para->incld_cca,829nhm_para->div_opt, nhm_para->nhm_app, nhm_time);830831return PHYDM_SET_SUCCESS;832}833834void phydm_nhm_cal_noise(void *dm_void, u8 start_i, u8 end_i, u8 n_sum)835{836struct dm_struct *dm = (struct dm_struct *)dm_void;837struct ccx_info *ccx = &dm->dm_ccx_info;838u8 i = 0;839u32 noise_tmp = 0;840u8 noise = 0;841u8 th_step = 2;842u32 nhm_valid = 0;843844PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);845846if (n_sum == 0) {847PHYDM_DBG(dm, DBG_ENV_MNTR,848"n_sum = 0, don't need to update noise\n");849return;850} else if (end_i > NHM_RPT_NUM - 1) {851PHYDM_DBG(dm, DBG_ENV_MNTR,852"[WARNING]end_i is larger than 11!!\n");853return;854}855856#ifdef NHM_DYM_PW_TH_SUPPORT857if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) &&858ccx->nhm_dym_pw_th_en)859th_step = 3;860#endif861862for (i = start_i; i <= end_i; i++)863noise_tmp += ccx->nhm_result[i] * (ccx->nhm_th[0] - th_step +864th_step * i * 2);865866/* protection for the case of minus noise(RSSI)*/867noise = (u8)(NTH_TH_2_RSSI(MAX_2(PHYDM_DIV(noise_tmp, n_sum), 20)));868ccx->nhm_noise_pwr = noise;869ccx->nhm_noise_pwr_point = n_sum;870nhm_valid = (n_sum * 100) >> 8;871PHYDM_DBG(dm, DBG_ENV_MNTR,872"valid: ((%d)) percent, noise(RSSI)=((%d)), nhm_r[11](RSSI > %d)=((%d))\n",873nhm_valid, noise, NTH_TH_2_RSSI(ccx->nhm_th[NHM_TH_NUM - 1]),874ccx->nhm_result[NHM_RPT_NUM - 1]);875}876877#ifdef NHM_DYM_PW_TH_SUPPORT878void879phydm_nhm_restore_pw_th(void *dm_void)880{881struct dm_struct *dm = (struct dm_struct *)dm_void;882struct ccx_info *ccx = &dm->dm_ccx_info;883884odm_set_bb_reg(dm, R_0x82c, 0x3f, ccx->nhm_pw_th_rf20_dft);885}886887void888phydm_nhm_set_pw_th(void *dm_void, u8 noise, boolean chk_succ)889{890struct dm_struct *dm = (struct dm_struct *)dm_void;891struct ccx_info *ccx = &dm->dm_ccx_info;892u8 pre_pw_th_rf20 = 0;893u8 new_pw_th_rf20 = 0;894u8 pw_th_u_bnd = 0;895s8 noise_diff = 0;896u8 point_mean = 15;897898PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);899900if (*dm->band_width != CHANNEL_WIDTH_20 ||901*dm->band_type == ODM_BAND_5G) {902PHYDM_DBG(dm, DBG_ENV_MNTR, "bandwidth=((%d)), band=((%d))\n",903*dm->band_width, *dm->band_type);904phydm_nhm_restore_pw_th(dm);905return;906}907908pre_pw_th_rf20 = (u8)odm_get_bb_reg(dm, R_0x82c, 0x3f);909910/* @pre_pw_th can not be lower than default value*/911if (pre_pw_th_rf20 < ccx->nhm_pw_th_rf20_dft) {912PHYDM_DBG(dm, DBG_ENV_MNTR,913"pre_pw_th=((%d)), new_pw_th=((%d))\n",914pre_pw_th_rf20, ccx->nhm_pw_th_rf20_dft);915916phydm_nhm_restore_pw_th(dm);917return;918}919920if (chk_succ) {921noise_diff = noise - (ccx->nhm_igi - 10);922pw_th_u_bnd = (u8)(noise_diff + 32 + point_mean);923924pw_th_u_bnd = MIN_2(pw_th_u_bnd, ccx->nhm_pw_th_max);925926PHYDM_DBG(dm, DBG_ENV_MNTR,927"noise_diff=((%d)), max=((%d)), pw_th_u_bnd=((%d))\n",928noise_diff, ccx->nhm_pw_th_max, pw_th_u_bnd);929930if (pw_th_u_bnd > pre_pw_th_rf20) {931new_pw_th_rf20 = pre_pw_th_rf20 + 1;932} else if (pw_th_u_bnd == pre_pw_th_rf20) {933new_pw_th_rf20 = pre_pw_th_rf20;934} else {935if (pre_pw_th_rf20 > ccx->nhm_pw_th_rf20_dft)936new_pw_th_rf20 = pre_pw_th_rf20 - 1;937else /* @pre_pw_th = ccx->nhm_pw_th_dft*/938new_pw_th_rf20 = pre_pw_th_rf20;939}940} else {941if (pre_pw_th_rf20 > ccx->nhm_pw_th_rf20_dft)942new_pw_th_rf20 = pre_pw_th_rf20 - 1;943else /* @pre_pw_th = ccx->nhm_pw_th_dft*/944new_pw_th_rf20 = pre_pw_th_rf20;945}946947PHYDM_DBG(dm, DBG_ENV_MNTR, "pre_pw_th=((%d)), new_pw_th=((%d))\n",948pre_pw_th_rf20, new_pw_th_rf20);949950if (new_pw_th_rf20 != pre_pw_th_rf20)951odm_set_bb_reg(dm, R_0x82c, 0x3f, new_pw_th_rf20);952}953954void955phydm_nhm_dym_pw_th_1peak(void *dm_void)956{957struct dm_struct *dm = (struct dm_struct *)dm_void;958struct ccx_info *ccx = &dm->dm_ccx_info;959u8 i = 0;960u8 max_i = 0;961u8 m_dif_l1 = 0;962u8 m_dif_r1 = 0;963u8 patt_case = 0;964u8 l1_dif_r2 = 0;965u8 l2_dif_r1 = 0;966u8 l1_dif_r1 = 0;967u8 n_sum = 0;968u8 r1_dif_r2 = 0;969u8 l1_dif_l2 = 0;970u8 noise = 0;971boolean chk_succ = false;972973PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);974975/* @step1*/976for (i = 1; i < NHM_RPT_NUM; i++) {977if (ccx->nhm_result[i] >= ccx->nhm_result[max_i])978max_i = i;979}980981if (max_i == 0 || max_i == (NHM_RPT_NUM - 1)) {982PHYDM_DBG(dm, DBG_ENV_MNTR, "max index can not be 0 or 11\n");983phydm_nhm_set_pw_th(dm, 0, chk_succ);984return;985}986987/* @step2*/988m_dif_l1 = ccx->nhm_result[max_i] - ccx->nhm_result[max_i - 1];989m_dif_r1 = ccx->nhm_result[max_i] - ccx->nhm_result[max_i + 1];990991if (m_dif_r1 <= NHM_TH1 && (max_i != NHM_RPT_NUM - 1))992patt_case = NHM_1PEAK_PS;993else if ((m_dif_l1 <= NHM_TH1) && (max_i != 0))994patt_case = NHM_1PEAK_NS;995else996patt_case = NHM_1PEAK_SYM;997998switch (patt_case) {999case NHM_1PEAK_PS:1000/* @step3*/1001l1_dif_r2 = DIFF_2(ccx->nhm_result[max_i - 1],1002ccx->nhm_result[max_i + 2]);1003if (l1_dif_r2 > NHM_TH2) {1004PHYDM_DBG(dm, DBG_ENV_MNTR, "S3 fail:c1((%d))\n",1005l1_dif_r2);1006break;1007}1008/* @step4*/1009n_sum = ccx->nhm_result[max_i - 1] + ccx->nhm_result[max_i] +1010ccx->nhm_result[max_i + 1] + ccx->nhm_result[max_i + 2];1011if (n_sum < NHM_TH4) {1012PHYDM_DBG(dm, DBG_ENV_MNTR, "S4 fail:((%d))\n", n_sum);1013break;1014}1015/* @step5*/1016r1_dif_r2 = DIFF_2(ccx->nhm_result[max_i + 1],1017ccx->nhm_result[max_i + 2]);1018if (m_dif_l1 < NHM_TH5 || r1_dif_r2 < NHM_TH5) {1019PHYDM_DBG(dm, DBG_ENV_MNTR, "S5 fail:c1((%d, %d))\n",1020m_dif_l1, r1_dif_r2);1021break;1022}1023/* @step6*/1024chk_succ = true;1025phydm_nhm_cal_noise(dm, max_i - 1, max_i + 2, n_sum);1026break;1027case NHM_1PEAK_NS:1028/* @step3*/1029l2_dif_r1 = DIFF_2(ccx->nhm_result[max_i - 2],1030ccx->nhm_result[max_i + 1]);1031if (l2_dif_r1 > NHM_TH2) {1032PHYDM_DBG(dm, DBG_ENV_MNTR, "S3 fail:c2((%d))\n",1033l2_dif_r1);1034break;1035}1036/* @step4*/1037n_sum = ccx->nhm_result[max_i - 2] +1038ccx->nhm_result[max_i - 1] +1039ccx->nhm_result[max_i] + ccx->nhm_result[max_i + 1];1040if (n_sum < NHM_TH4) {1041PHYDM_DBG(dm, DBG_ENV_MNTR, "S4 fail:((%d))\n", n_sum);1042break;1043}1044/* @step5*/1045l1_dif_l2 = DIFF_2(ccx->nhm_result[max_i - 1],1046ccx->nhm_result[max_i - 2]);1047if (m_dif_r1 < NHM_TH5 || l1_dif_l2 < NHM_TH5) {1048PHYDM_DBG(dm, DBG_ENV_MNTR, "S5 fail:c2((%d, %d))\n",1049m_dif_r1, l1_dif_l2);1050break;1051}1052/* @step6*/1053chk_succ = true;1054phydm_nhm_cal_noise(dm, max_i - 2, max_i + 1, n_sum);1055break;1056case NHM_1PEAK_SYM:1057/* @step3*/1058l1_dif_r1 = DIFF_2(ccx->nhm_result[max_i - 1],1059ccx->nhm_result[max_i + 1]);1060if (l1_dif_r1 > NHM_TH3) {1061PHYDM_DBG(dm, DBG_ENV_MNTR, "S3 fail: c3((%d))\n",1062l1_dif_r1);1063break;1064}1065/* @step4*/1066n_sum = ccx->nhm_result[max_i - 1] + ccx->nhm_result[max_i] +1067ccx->nhm_result[max_i + 1];1068if (n_sum < NHM_TH4) {1069PHYDM_DBG(dm, DBG_ENV_MNTR, "S4 fail:((%d))\n", n_sum);1070break;1071}1072/* @step5*/1073if (m_dif_l1 < NHM_TH6 || m_dif_r1 < NHM_TH6) {1074PHYDM_DBG(dm, DBG_ENV_MNTR, "S5 fail:c3((%d, %d))\n",1075m_dif_l1, m_dif_r1);1076break;1077}1078/* @step6*/1079chk_succ = true;1080phydm_nhm_cal_noise(dm, max_i - 1, max_i + 1, n_sum);1081break;1082}1083phydm_nhm_set_pw_th(dm, ccx->nhm_noise_pwr, chk_succ);1084}10851086void1087phydm_nhm_dym_pw_th_sl(void *dm_void)1088{1089struct dm_struct *dm = (struct dm_struct *)dm_void;1090struct ccx_info *ccx = &dm->dm_ccx_info;1091u8 i = 0;1092u8 n_sum = 0;1093u8 noise = 0;1094boolean chk_succ = false;10951096PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);10971098for (i = 0; i < NHM_RPT_NUM - 3; i++) {1099n_sum = ccx->nhm_result[i] + ccx->nhm_result[i + 1] +1100ccx->nhm_result[i + 2] + ccx->nhm_result[i + 3];1101if (n_sum >= ccx->nhm_sl_pw_th) {1102PHYDM_DBG(dm, DBG_ENV_MNTR, "Do sl[%d:%d]\n", i, i + 3);1103chk_succ = true;1104phydm_nhm_cal_noise(dm, i, i + 3, n_sum);1105break;1106}1107}11081109if (!chk_succ)1110PHYDM_DBG(dm, DBG_ENV_MNTR, "SL method failed!\n");11111112phydm_nhm_set_pw_th(dm, ccx->nhm_noise_pwr, chk_succ);1113}11141115void1116phydm_nhm_dym_pw_th(void *dm_void)1117{1118struct dm_struct *dm = (struct dm_struct *)dm_void;1119struct ccx_info *ccx = &dm->dm_ccx_info;11201121if (ccx->nhm_dym_1_peak_en)1122phydm_nhm_dym_pw_th_1peak(dm);1123else1124phydm_nhm_dym_pw_th_sl(dm);1125}11261127void1128phydm_nhm_dym_pw_th_patch_id_chk(void *dm_void)1129{1130struct dm_struct *dm = (struct dm_struct *)dm_void;1131struct ccx_info *ccx = &dm->dm_ccx_info;11321133if (dm->iot_table.phydm_patch_id == 0x100f0401) {1134ccx->nhm_dym_pw_th_en = true;1135} else {1136if (ccx->nhm_dym_pw_th_en) {1137phydm_nhm_restore_pw_th(dm);1138ccx->nhm_dym_pw_th_en = false;1139}1140}1141}1142#endif11431144/*@Environment Monitor*/1145boolean1146phydm_nhm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/)1147{1148struct dm_struct *dm = (struct dm_struct *)dm_void;1149struct ccx_info *ccx = &dm->dm_ccx_info;1150struct nhm_para_info nhm_para = {0};1151boolean nhm_chk_result = false;1152u32 sys_return_time = 0;11531154PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);11551156if (ccx->nhm_manual_ctrl) {1157PHYDM_DBG(dm, DBG_ENV_MNTR, "NHM in manual ctrl\n");1158return nhm_chk_result;1159}1160sys_return_time = ccx->nhm_trigger_time + MAX_ENV_MNTR_TIME;1161if (ccx->nhm_app != NHM_BACKGROUND &&1162(sys_return_time > dm->phydm_sys_up_time)) {1163PHYDM_DBG(dm, DBG_ENV_MNTR,1164"nhm_app=%d, trigger_time %d, sys_time=%d\n",1165ccx->nhm_app, ccx->nhm_trigger_time,1166dm->phydm_sys_up_time);11671168return nhm_chk_result;1169}11701171/*@[NHM get result & calculate Utility----------------------------*/1172#ifdef NHM_DYM_PW_TH_SUPPORT1173if (!(ccx->dym_pwth_manual_ctrl))1174phydm_nhm_dym_pw_th_patch_id_chk(dm);1175#endif11761177if (phydm_nhm_get_result(dm)) {1178PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM_rpt success\n");1179phydm_nhm_get_utility(dm);11801181#ifdef NHM_DYM_PW_TH_SUPPORT1182if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) &&1183ccx->nhm_dym_pw_th_en)1184phydm_nhm_dym_pw_th(dm);1185else1186#endif1187/* bypass r[11]*/1188phydm_nhm_cal_noise(dm, 0, NHM_RPT_NUM - 2,1189ccx->nhm_rpt_sum -1190ccx->nhm_result[11]);1191} else {1192#ifdef NHM_DYM_PW_TH_SUPPORT1193if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) &&1194ccx->nhm_dym_pw_th_en)1195phydm_nhm_set_pw_th(dm, 0, false);1196#endif1197}11981199/*@[NHM trigger setting]------------------------------------------*/1200nhm_para.incld_txon = NHM_EXCLUDE_TXON;1201nhm_para.incld_cca = NHM_EXCLUDE_CCA;1202#ifdef NHM_DYM_PW_TH_SUPPORT1203if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) &&1204ccx->nhm_app == NHM_BACKGROUND && ccx->nhm_dym_pw_th_en)1205nhm_para.div_opt = NHM_VALID;1206else1207#endif1208nhm_para.div_opt = NHM_CNT_ALL;12091210nhm_para.nhm_app = NHM_BACKGROUND;1211nhm_para.nhm_lv = NHM_LV_1;1212#ifdef NHM_DYM_PW_TH_SUPPORT1213if ((dm->support_ic_type & ODM_IC_JGR3_SERIES) &&1214ccx->nhm_app == NHM_BACKGROUND && ccx->nhm_dym_pw_th_en)1215nhm_para.mntr_time = monitor_time >> ccx->nhm_period_decre;1216else1217#endif1218nhm_para.mntr_time = monitor_time;12191220nhm_chk_result = phydm_nhm_mntr_set(dm, &nhm_para);12211222return nhm_chk_result;1223}12241225void phydm_nhm_init(void *dm_void)1226{1227struct dm_struct *dm = (struct dm_struct *)dm_void;1228struct ccx_info *ccx = &dm->dm_ccx_info;12291230PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);1231PHYDM_DBG(dm, DBG_ENV_MNTR, "cur_igi=0x%x\n",1232dm->dm_dig_table.cur_ig_value);12331234ccx->nhm_app = NHM_BACKGROUND;1235ccx->nhm_igi = 0xff;12361237/*Set NHM threshold*/1238ccx->nhm_ongoing = false;1239ccx->nhm_set_lv = NHM_RELEASE;12401241if (phydm_nhm_th_update_chk(dm, ccx->nhm_app, &ccx->nhm_th[0],1242(u32 *)&ccx->nhm_igi))1243phydm_nhm_set_th_reg(dm);12441245ccx->nhm_period = 0;12461247ccx->nhm_include_cca = NHM_CCA_INIT;1248ccx->nhm_include_txon = NHM_TXON_INIT;1249ccx->nhm_divider_opt = NHM_CNT_INIT;12501251ccx->nhm_manual_ctrl = 0;1252ccx->nhm_rpt_stamp = 0;12531254#ifdef NHM_DYM_PW_TH_SUPPORT1255if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {1256ccx->nhm_dym_pw_th_en = false;1257ccx->nhm_dym_1_peak_en = false;1258ccx->nhm_pw_th_rf20_dft = (u8)odm_get_bb_reg(dm, R_0x82c, 0x3f);1259ccx->nhm_pw_th_max = 63;1260ccx->nhm_sl_pw_th = 100; /* @39%*/1261ccx->nhm_period_decre = 1;1262ccx->dym_pwth_manual_ctrl = false;1263}1264#endif1265}12661267void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output,1268u32 *_out_len)1269{1270struct dm_struct *dm = (struct dm_struct *)dm_void;1271struct ccx_info *ccx = &dm->dm_ccx_info;1272struct nhm_para_info nhm_para;1273char help[] = "-h";1274u32 var1[10] = {0};1275u32 used = *_used;1276u32 out_len = *_out_len;1277boolean nhm_rpt_success = true;1278u8 result_tmp = 0;1279u8 i;12801281PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);12821283if ((strcmp(input[1], help) == 0)) {1284PDM_SNPF(out_len, used, output + used, out_len - used,1285"NHM Basic-Trigger 262ms: {1}\n");12861287PDM_SNPF(out_len, used, output + used, out_len - used,1288"NHM Adv-Trigger: {2} {Include TXON} {Include CCA}\n{0:Cnt_all, 1:Cnt valid} {App} {LV} {0~262ms}\n");1289#ifdef NHM_DYM_PW_TH_SUPPORT1290if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {1291PDM_SNPF(out_len, used, output + used, out_len - used,1292"NHM dym_pw_th: {3} {0:off}\n");1293PDM_SNPF(out_len, used, output + used, out_len - used,1294"NHM dym_pw_th: {3} {1:on} {en_1-peak} {max} {period_decre} {sl_th}\n");1295PDM_SNPF(out_len, used, output + used, out_len - used,1296"NHM dym_pw_th: {3} {2:fast on}\n");1297}1298#endif12991300PDM_SNPF(out_len, used, output + used, out_len - used,1301"NHM Get Result: {100}\n");1302} else if (var1[0] == 100) { /*@Get NHM results*/13031304PDM_SNPF(out_len, used, output + used, out_len - used,1305"IGI=0x%x, rpt_stamp=%d\n", ccx->nhm_igi,1306ccx->nhm_rpt_stamp);13071308nhm_rpt_success = phydm_nhm_get_result(dm);13091310if (nhm_rpt_success) {1311for (i = 0; i <= 11; i++) {1312result_tmp = ccx->nhm_result[i];1313PDM_SNPF(out_len, used, output + used,1314out_len - used,1315"nhm_rpt[%d] = %d (%d percent)\n",1316i, result_tmp,1317(((result_tmp * 100) + 128) >> 8));1318}1319} else {1320PDM_SNPF(out_len, used, output + used, out_len - used,1321"Get NHM_rpt Fail\n");1322}1323ccx->nhm_manual_ctrl = 0;1324#ifdef NHM_DYM_PW_TH_SUPPORT1325} else if (var1[0] == 3) { /* @NMH dym_pw_th*/1326if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {1327for (i = 1; i < 7; i++) {1328if (input[i + 1]) {1329PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,1330&var1[i]);1331}1332}13331334if (var1[1] == 1) {1335ccx->nhm_dym_pw_th_en = true;1336ccx->nhm_dym_1_peak_en = (boolean)var1[2];1337ccx->nhm_pw_th_max = (u8)var1[3];1338ccx->nhm_period_decre = (u8)var1[4];1339ccx->nhm_sl_pw_th = (u8)var1[5];1340ccx->dym_pwth_manual_ctrl = true;1341} else if (var1[1] == 2) {1342ccx->nhm_dym_pw_th_en = true;1343ccx->nhm_dym_1_peak_en = false;1344ccx->nhm_pw_th_max = 63;1345ccx->nhm_period_decre = 1;1346ccx->nhm_sl_pw_th = 100;1347ccx->dym_pwth_manual_ctrl = true;1348} else {1349ccx->nhm_dym_pw_th_en = false;1350phydm_nhm_restore_pw_th(dm);1351ccx->dym_pwth_manual_ctrl = false;1352}1353}1354#endif1355} else { /*NMH trigger*/13561357ccx->nhm_manual_ctrl = 1;13581359for (i = 1; i < 7; i++) {1360if (input[i + 1]) {1361PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL,1362&var1[i]);1363}1364}13651366if (var1[0] == 1) {1367nhm_para.incld_txon = NHM_EXCLUDE_TXON;1368nhm_para.incld_cca = NHM_EXCLUDE_CCA;1369nhm_para.div_opt = NHM_CNT_ALL;1370nhm_para.nhm_app = NHM_DBG;1371nhm_para.nhm_lv = NHM_LV_4;1372nhm_para.mntr_time = 262;1373} else {1374nhm_para.incld_txon = (enum nhm_option_txon_all)var1[1];1375nhm_para.incld_cca = (enum nhm_option_cca_all)var1[2];1376nhm_para.div_opt = (enum nhm_divider_opt_all)var1[3];1377nhm_para.nhm_app = (enum nhm_application)var1[4];1378nhm_para.nhm_lv = (enum phydm_nhm_level)var1[5];1379nhm_para.mntr_time = (u16)var1[6];13801381/* some old ic is not supported on NHM divider option */1382if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8723B |1383ODM_RTL8195A | ODM_RTL8192E)) {1384nhm_para.div_opt = NHM_CNT_ALL;1385}1386}13871388PDM_SNPF(out_len, used, output + used, out_len - used,1389"txon=%d, cca=%d, dev=%d, app=%d, lv=%d, time=%d ms\n",1390nhm_para.incld_txon, nhm_para.incld_cca,1391nhm_para.div_opt, nhm_para.nhm_app,1392nhm_para.nhm_lv, nhm_para.mntr_time);13931394if (phydm_nhm_mntr_set(dm, &nhm_para) == PHYDM_SET_SUCCESS)1395phydm_nhm_trigger(dm);13961397PDM_SNPF(out_len, used, output + used, out_len - used,1398"IGI=0x%x, rpt_stamp=%d\n", ccx->nhm_igi,1399ccx->nhm_rpt_stamp);14001401for (i = 0; i <= 10; i++) {1402PDM_SNPF(out_len, used, output + used, out_len - used,1403"NHM_th[%d] RSSI = %d\n", i,1404NTH_TH_2_RSSI(ccx->nhm_th[i]));1405}1406}14071408*_used = used;1409*_out_len = out_len;1410}14111412#endif /*@#ifdef NHM_SUPPORT*/14131414#ifdef CLM_SUPPORT14151416void phydm_clm_racing_release(void *dm_void)1417{1418struct dm_struct *dm = (struct dm_struct *)dm_void;1419struct ccx_info *ccx = &dm->dm_ccx_info;14201421PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);1422PHYDM_DBG(dm, DBG_ENV_MNTR, "lv:(%d)->(0)\n", ccx->clm_set_lv);14231424ccx->clm_ongoing = false;1425ccx->clm_set_lv = CLM_RELEASE;1426ccx->clm_app = CLM_BACKGROUND;1427}14281429u8 phydm_clm_racing_ctrl(void *dm_void, enum phydm_clm_level clm_lv)1430{1431struct dm_struct *dm = (struct dm_struct *)dm_void;1432struct ccx_info *ccx = &dm->dm_ccx_info;1433u8 set_result = PHYDM_SET_SUCCESS;1434/*@acquire to control CLM API*/14351436PHYDM_DBG(dm, DBG_ENV_MNTR, "clm_ongoing=%d, lv:(%d)->(%d)\n",1437ccx->clm_ongoing, ccx->clm_set_lv, clm_lv);1438if (ccx->clm_ongoing) {1439if (clm_lv <= ccx->clm_set_lv) {1440set_result = PHYDM_SET_FAIL;1441} else {1442phydm_ccx_hw_restart(dm);1443ccx->clm_ongoing = false;1444}1445}14461447if (set_result)1448ccx->clm_set_lv = clm_lv;14491450PHYDM_DBG(dm, DBG_ENV_MNTR, "clm racing success=%d\n", set_result);1451return set_result;1452}14531454void phydm_clm_c2h_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len)1455{1456struct dm_struct *dm = (struct dm_struct *)dm_void;1457struct ccx_info *ccx_info = &dm->dm_ccx_info;1458u8 clm_report = cmd_buf[0];1459/*@u8 clm_report_idx = cmd_buf[1];*/14601461if (cmd_len >= 12)1462return;14631464ccx_info->clm_fw_result_acc += clm_report;1465ccx_info->clm_fw_result_cnt++;14661467PHYDM_DBG(dm, DBG_ENV_MNTR, "[%d] clm_report= %d\n",1468ccx_info->clm_fw_result_cnt, clm_report);1469}14701471void phydm_clm_h2c(void *dm_void, u16 obs_time, u8 fw_clm_en)1472{1473struct dm_struct *dm = (struct dm_struct *)dm_void;1474u8 h2c_val[H2C_MAX_LENGTH] = {0};1475u8 i = 0;1476u8 obs_time_idx = 0;14771478PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__);1479PHYDM_DBG(dm, DBG_ENV_MNTR, "obs_time_index=%d *4 us\n", obs_time);14801481for (i = 1; i <= 16; i++) {1482if (obs_time & BIT(16 - i)) {1483obs_time_idx = 16 - i;1484break;1485}1486}1487#if 01488obs_time = (2 ^ 16 - 1)~(2 ^ 15) => obs_time_idx = 15 (65535 ~32768)1489obs_time = (2 ^ 15 - 1)~(2 ^ 14) => obs_time_idx = 141490...1491...1492...1493obs_time = (2 ^ 1 - 1)~(2 ^ 0) => obs_time_idx = 014941495#endif14961497h2c_val[0] = obs_time_idx | (((fw_clm_en) ? 1 : 0) << 7);1498h2c_val[1] = CLM_MAX_REPORT_TIME;14991500PHYDM_DBG(dm, DBG_ENV_MNTR, "PHYDM h2c[0x4d]=0x%x %x %x %x %x %x %x\n",1501h2c_val[6], h2c_val[5], h2c_val[4], h2c_val[3], h2c_val[2],1502h2c_val[1], h2c_val[0]);15031504odm_fill_h2c_cmd(dm, PHYDM_H2C_FW_CLM_MNTR, H2C_MAX_LENGTH, h2c_val);1505}15061507void phydm_clm_setting(void *dm_void, u16 clm_period /*@4us sample 1 time*/)1508{1509struct dm_struct *dm = (struct dm_struct *)dm_void;1510struct ccx_info *ccx = &dm->dm_ccx_info;15111512if (ccx->clm_period != clm_period) {1513if (dm->support_ic_type & ODM_IC_11AC_SERIES)1514odm_set_bb_reg(dm, R_0x990, MASKLWORD, clm_period);1515#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT1516else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)1517odm_set_bb_reg(dm, R_0x1e40, MASKLWORD, clm_period);1518#endif1519else if (dm->support_ic_type & ODM_IC_11N_SERIES)1520odm_set_bb_reg(dm, R_0x894, MASKLWORD, clm_period);15211522ccx->clm_period = clm_period;1523PHYDM_DBG(dm, DBG_ENV_MNTR,1524"Update CLM period ((%d)) -> ((%d))\n",1525ccx->clm_period, clm_period);1526}15271528PHYDM_DBG(dm, DBG_ENV_MNTR, "Set CLM period=%d * 4us\n",1529ccx->clm_period);1530}15311532void phydm_clm_trigger(void *dm_void)1533{1534struct dm_struct *dm = (struct dm_struct *)dm_void;1535struct ccx_info *ccx = &dm->dm_ccx_info;1536u32 reg1 = 0;15371538if (dm->support_ic_type & ODM_IC_11AC_SERIES)1539reg1 = R_0x994;1540#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT1541else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)1542reg1 = R_0x1e60;1543#endif1544else1545reg1 = R_0x890;1546PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);15471548odm_set_bb_reg(dm, reg1, BIT(0), 0x0);1549odm_set_bb_reg(dm, reg1, BIT(0), 0x1);15501551ccx->clm_trigger_time = dm->phydm_sys_up_time;1552ccx->clm_rpt_stamp++;1553ccx->clm_ongoing = true;1554}15551556boolean1557phydm_clm_check_rdy(void *dm_void)1558{1559struct dm_struct *dm = (struct dm_struct *)dm_void;1560boolean is_ready = false;1561u32 reg1 = 0, reg1_bit = 0;15621563if (dm->support_ic_type & ODM_IC_11AC_SERIES) {1564reg1 = R_0xfa4;1565reg1_bit = 16;1566#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT1567} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {1568reg1 = R_0x2d88;1569reg1_bit = 16;1570#endif1571} else if (dm->support_ic_type & ODM_IC_11N_SERIES) {1572if (dm->support_ic_type & (ODM_RTL8710B | ODM_RTL8721D |1573ODM_RTL8710C)) {1574reg1 = R_0x8b4;1575reg1_bit = 24;1576} else {1577reg1 = R_0x8b4;1578reg1_bit = 16;1579}1580}1581if (odm_get_bb_reg(dm, reg1, BIT(reg1_bit)))1582is_ready = true;15831584PHYDM_DBG(dm, DBG_ENV_MNTR, "CLM rdy=%d\n", is_ready);15851586return is_ready;1587}15881589void phydm_clm_get_utility(void *dm_void)1590{1591struct dm_struct *dm = (struct dm_struct *)dm_void;1592struct ccx_info *ccx = &dm->dm_ccx_info;1593u32 clm_result_tmp;15941595if (ccx->clm_period == 0) {1596PHYDM_DBG(dm, DBG_ENV_MNTR, "[warning] clm_period = 0\n");1597ccx->clm_ratio = 0;1598} else if (ccx->clm_period >= 65530) {1599clm_result_tmp = (u32)(ccx->clm_result * 100);1600ccx->clm_ratio = (u8)((clm_result_tmp + (1 << 15)) >> 16);1601} else {1602clm_result_tmp = (u32)(ccx->clm_result * 100);1603ccx->clm_ratio = (u8)(clm_result_tmp / (u32)ccx->clm_period);1604}1605}16061607boolean1608phydm_clm_get_result(void *dm_void)1609{1610struct dm_struct *dm = (struct dm_struct *)dm_void;1611struct ccx_info *ccx_info = &dm->dm_ccx_info;1612u32 reg1 = 0;1613u32 val = 0;16141615if (dm->support_ic_type & ODM_IC_11AC_SERIES)1616reg1 = R_0x994;1617#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT1618else if (dm->support_ic_type & ODM_IC_JGR3_SERIES)1619reg1 = R_0x1e60;1620#endif1621else1622reg1 = R_0x890;1623if (!(dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F |1624ODM_RTL8197G)))1625odm_set_bb_reg(dm, reg1, BIT(0), 0x0);1626if (!(phydm_clm_check_rdy(dm))) {1627PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM report Fail\n");1628phydm_clm_racing_release(dm);1629return false;1630}16311632if (dm->support_ic_type & ODM_IC_11AC_SERIES) {1633val = odm_get_bb_reg(dm, R_0xfa4, MASKLWORD);1634ccx_info->clm_result = (u16)val;1635#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT1636} else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {1637val = odm_get_bb_reg(dm, R_0x2d88, MASKLWORD);1638ccx_info->clm_result = (u16)val;1639#endif1640} else if (dm->support_ic_type & ODM_IC_11N_SERIES) {1641val = odm_get_bb_reg(dm, R_0x8d0, MASKLWORD);1642ccx_info->clm_result = (u16)val;1643}16441645PHYDM_DBG(dm, DBG_ENV_MNTR, "CLM result = %d *4 us\n",1646ccx_info->clm_result);1647phydm_clm_racing_release(dm);1648return true;1649}16501651void phydm_clm_mntr_fw(void *dm_void, u16 monitor_time /*unit ms*/)1652{1653struct dm_struct *dm = (struct dm_struct *)dm_void;1654struct ccx_info *ccx = &dm->dm_ccx_info;1655u32 val = 0;16561657/*@[Get CLM report]*/1658if (ccx->clm_fw_result_cnt != 0) {1659val = ccx->clm_fw_result_acc / ccx->clm_fw_result_cnt;1660ccx->clm_ratio = (u8)val;1661} else {1662ccx->clm_ratio = 0;1663}16641665PHYDM_DBG(dm, DBG_ENV_MNTR,1666"clm_fw_result_acc=%d, clm_fw_result_cnt=%d\n",1667ccx->clm_fw_result_acc, ccx->clm_fw_result_cnt);16681669ccx->clm_fw_result_acc = 0;1670ccx->clm_fw_result_cnt = 0;16711672/*@[CLM trigger]*/1673if (monitor_time >= 262)1674ccx->clm_period = 65535;1675else1676ccx->clm_period = monitor_time * MS_TO_4US_RATIO;16771678phydm_clm_h2c(dm, ccx->clm_period, true);1679}16801681u8 phydm_clm_mntr_set(void *dm_void, struct clm_para_info *clm_para)1682{1683/*@Driver Monitor CLM*/1684struct dm_struct *dm = (struct dm_struct *)dm_void;1685struct ccx_info *ccx = &dm->dm_ccx_info;1686u16 clm_period = 0;16871688if (clm_para->mntr_time == 0)1689return PHYDM_SET_FAIL;16901691if (clm_para->clm_lv >= CLM_MAX_NUM) {1692PHYDM_DBG(dm, DBG_ENV_MNTR, "[WARNING] Wrong LV=%d\n",1693clm_para->clm_lv);1694return PHYDM_SET_FAIL;1695}16961697if (phydm_clm_racing_ctrl(dm, clm_para->clm_lv) == PHYDM_SET_FAIL)1698return PHYDM_SET_FAIL;16991700if (clm_para->mntr_time >= 262)1701clm_period = CLM_PERIOD_MAX;1702else1703clm_period = clm_para->mntr_time * MS_TO_4US_RATIO;17041705ccx->clm_app = clm_para->clm_app;1706phydm_clm_setting(dm, clm_period);17071708return PHYDM_SET_SUCCESS;1709}17101711boolean1712phydm_clm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/)1713{1714struct dm_struct *dm = (struct dm_struct *)dm_void;1715struct ccx_info *ccx = &dm->dm_ccx_info;1716struct clm_para_info clm_para = {0};1717boolean clm_chk_result = false;1718u32 sys_return_time = 0;17191720PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__);1721if (ccx->clm_manual_ctrl) {1722PHYDM_DBG(dm, DBG_ENV_MNTR, "CLM in manual ctrl\n");1723return clm_chk_result;1724}17251726sys_return_time = ccx->clm_trigger_time + MAX_ENV_MNTR_TIME;17271728if (ccx->clm_app != CLM_BACKGROUND &&1729sys_return_time > dm->phydm_sys_up_time) {1730PHYDM_DBG(dm, DBG_ENV_MNTR, "trigger_time %d, sys_time=%d\n",1731ccx->clm_trigger_time, dm->phydm_sys_up_time);17321733return clm_chk_result;1734}17351736clm_para.clm_app = CLM_BACKGROUND;1737clm_para.clm_lv = CLM_LV_1;1738clm_para.mntr_time = monitor_time;1739if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) {1740/*@[Get CLM report]*/1741if (phydm_clm_get_result(dm)) {1742PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM_rpt success\n");1743phydm_clm_get_utility(dm);1744}17451746/*@[CLM trigger]----------------------------------------------*/1747if (phydm_clm_mntr_set(dm, &clm_para) == PHYDM_SET_SUCCESS)1748clm_chk_result = true;1749} else {1750phydm_clm_mntr_fw(dm, monitor_time);1751}17521753PHYDM_DBG(dm, DBG_ENV_MNTR, "clm_ratio=%d\n", ccx->clm_ratio);17541755/*@PHYDM_DBG(dm, DBG_ENV_MNTR, "clm_chk_result=%d\n",clm_chk_result);*/17561757return clm_chk_result;1758}17591760void phydm_set_clm_mntr_mode(void *dm_void, enum clm_monitor_mode mode)1761{1762struct dm_struct *dm = (struct dm_struct *)dm_void;1763struct ccx_info *ccx_info = &dm->dm_ccx_info;17641765if (ccx_info->clm_mntr_mode != mode) {1766ccx_info->clm_mntr_mode = mode;1767phydm_ccx_hw_restart(dm);17681769if (mode == CLM_DRIVER_MNTR)1770phydm_clm_h2c(dm, 0, 0);1771}1772}17731774void phydm_clm_init(void *dm_void)1775{1776struct dm_struct *dm = (struct dm_struct *)dm_void;1777struct ccx_info *ccx = &dm->dm_ccx_info;17781779PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);1780ccx->clm_ongoing = false;1781ccx->clm_manual_ctrl = 0;1782ccx->clm_mntr_mode = CLM_DRIVER_MNTR;1783ccx->clm_period = 0;1784ccx->clm_rpt_stamp = 0;1785phydm_clm_setting(dm, 65535);1786}17871788void phydm_clm_dbg(void *dm_void, char input[][16], u32 *_used, char *output,1789u32 *_out_len)1790{1791struct dm_struct *dm = (struct dm_struct *)dm_void;1792struct ccx_info *ccx = &dm->dm_ccx_info;1793char help[] = "-h";1794u32 var1[10] = {0};1795u32 used = *_used;1796u32 out_len = *_out_len;1797struct clm_para_info clm_para = {0};1798u32 i;17991800for (i = 0; i < 4; i++) {1801if (input[i + 1])1802PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);1803}18041805if ((strcmp(input[1], help) == 0)) {1806PDM_SNPF(out_len, used, output + used, out_len - used,1807"CLM Driver Basic-Trigger 262ms: {1}\n");1808PDM_SNPF(out_len, used, output + used, out_len - used,1809"CLM Driver Adv-Trigger: {2} {app} {LV} {0~262ms}\n");1810PDM_SNPF(out_len, used, output + used, out_len - used,1811"CLM FW Trigger: {3} {1:drv, 2:fw}\n");1812PDM_SNPF(out_len, used, output + used, out_len - used,1813"CLM Get Result: {100}\n");1814} else if (var1[0] == 100) { /* @Get CLM results */18151816if (phydm_clm_get_result(dm))1817phydm_clm_get_utility(dm);18181819PDM_SNPF(out_len, used, output + used, out_len - used,1820"clm_rpt_stamp=%d\n", ccx->clm_rpt_stamp);18211822PDM_SNPF(out_len, used, output + used, out_len - used,1823"clm_ratio:((%d percent)) = (%d us/ %d us)\n",1824ccx->clm_ratio, ccx->clm_result << 2,1825ccx->clm_period << 2);18261827ccx->clm_manual_ctrl = 0;1828} else if (var1[0] == 3) {1829phydm_set_clm_mntr_mode(dm, (enum clm_monitor_mode)var1[1]);1830PDM_SNPF(out_len, used, output + used, out_len - used,1831"CLM mode: %s mode\n",1832((ccx->clm_mntr_mode == CLM_FW_MNTR) ? "FW" : "Drv"));1833} else { /* Set & trigger CLM */1834ccx->clm_manual_ctrl = 1;18351836if (var1[0] == 1) {1837clm_para.clm_app = CLM_BACKGROUND;1838clm_para.clm_lv = CLM_LV_4;1839clm_para.mntr_time = 262;1840ccx->clm_mntr_mode = CLM_DRIVER_MNTR;1841} else if (var1[0] == 2) {1842clm_para.clm_app = (enum clm_application)var1[1];1843clm_para.clm_lv = (enum phydm_clm_level)var1[2];1844ccx->clm_mntr_mode = CLM_DRIVER_MNTR;1845clm_para.mntr_time = (u16)var1[3];1846}18471848PDM_SNPF(out_len, used, output + used, out_len - used,1849"app=%d, lv=%d, mode=%s, time=%d ms\n",1850clm_para.clm_app, clm_para.clm_lv,1851((ccx->clm_mntr_mode == CLM_FW_MNTR) ? "FW" :1852"driver"), clm_para.mntr_time);18531854if (phydm_clm_mntr_set(dm, &clm_para) == PHYDM_SET_SUCCESS)1855phydm_clm_trigger(dm);18561857PDM_SNPF(out_len, used, output + used, out_len - used,1858"clm_rpt_stamp=%d\n", ccx->clm_rpt_stamp);1859}18601861*_used = used;1862*_out_len = out_len;1863}18641865#endif /*@#ifdef CLM_SUPPORT*/18661867u8 phydm_env_mntr_trigger(void *dm_void, struct nhm_para_info *nhm_para,1868struct clm_para_info *clm_para,1869struct env_trig_rpt *trig_rpt)1870{1871#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT))1872struct dm_struct *dm = (struct dm_struct *)dm_void;1873struct ccx_info *ccx = &dm->dm_ccx_info;1874boolean nhm_set_ok = false;1875boolean clm_set_ok = false;1876u8 trigger_result = 0;18771878PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__);18791880/*@[NHM]*/1881nhm_set_ok = phydm_nhm_mntr_set(dm, nhm_para);18821883/*@[CLM]*/1884if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) {1885clm_set_ok = phydm_clm_mntr_set(dm, clm_para);1886} else if (ccx->clm_mntr_mode == CLM_FW_MNTR) {1887phydm_clm_h2c(dm, CLM_PERIOD_MAX, true);1888trigger_result |= CLM_SUCCESS;1889}18901891if (nhm_set_ok) {1892phydm_nhm_trigger(dm);1893trigger_result |= NHM_SUCCESS;1894}18951896if (clm_set_ok) {1897phydm_clm_trigger(dm);1898trigger_result |= CLM_SUCCESS;1899}19001901/*@monitor for the test duration*/1902ccx->start_time = odm_get_current_time(dm);19031904trig_rpt->nhm_rpt_stamp = ccx->nhm_rpt_stamp;1905trig_rpt->clm_rpt_stamp = ccx->clm_rpt_stamp;19061907PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_rpt_stamp=%d, clm_rpt_stamp=%d,\n\n",1908trig_rpt->nhm_rpt_stamp, trig_rpt->clm_rpt_stamp);19091910return trigger_result;1911#endif1912}19131914u8 phydm_env_mntr_result(void *dm_void, struct env_mntr_rpt *rpt)1915{1916#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT))1917struct dm_struct *dm = (struct dm_struct *)dm_void;1918struct ccx_info *ccx = &dm->dm_ccx_info;1919u8 env_mntr_rpt = 0;1920u64 progressing_time = 0;1921u32 val_tmp = 0;19221923/*@monitor for the test duration*/1924progressing_time = odm_get_progressing_time(dm, ccx->start_time);1925PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__);1926PHYDM_DBG(dm, DBG_ENV_MNTR, "env_time=%lld\n", progressing_time);19271928/*@Get NHM result*/1929if (phydm_nhm_get_result(dm)) {1930PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM_rpt success\n");1931phydm_nhm_get_utility(dm);1932/* bypass r[11]*/1933phydm_nhm_cal_noise(dm, 0, NHM_RPT_NUM - 2,1934ccx->nhm_rpt_sum - ccx->nhm_result[11]);1935rpt->nhm_ratio = ccx->nhm_ratio;1936rpt->nhm_noise_pwr = ccx->nhm_noise_pwr;1937env_mntr_rpt |= NHM_SUCCESS;19381939odm_move_memory(dm, &rpt->nhm_result[0],1940&ccx->nhm_result[0], NHM_RPT_NUM);1941} else {1942rpt->nhm_ratio = ENV_MNTR_FAIL;1943}19441945/*@Get CLM result*/1946if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) {1947if (phydm_clm_get_result(dm)) {1948PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM_rpt success\n");1949phydm_clm_get_utility(dm);1950env_mntr_rpt |= CLM_SUCCESS;1951rpt->clm_ratio = ccx->clm_ratio;1952} else {1953rpt->clm_ratio = ENV_MNTR_FAIL;1954}19551956} else {1957if (ccx->clm_fw_result_cnt != 0) {1958val_tmp = ccx->clm_fw_result_acc1959/ ccx->clm_fw_result_cnt;1960ccx->clm_ratio = (u8)val_tmp;1961} else {1962ccx->clm_ratio = 0;1963}19641965rpt->clm_ratio = ccx->clm_ratio;1966PHYDM_DBG(dm, DBG_ENV_MNTR,1967"clm_fw_result_acc=%d, clm_fw_result_cnt=%d\n",1968ccx->clm_fw_result_acc, ccx->clm_fw_result_cnt);19691970ccx->clm_fw_result_acc = 0;1971ccx->clm_fw_result_cnt = 0;1972env_mntr_rpt |= CLM_SUCCESS;1973}19741975rpt->nhm_rpt_stamp = ccx->nhm_rpt_stamp;1976rpt->clm_rpt_stamp = ccx->clm_rpt_stamp;19771978PHYDM_DBG(dm, DBG_ENV_MNTR,1979"IGI=0x%x, nhm_ratio=%d, clm_ratio=%d, nhm_rpt_stamp=%d, clm_rpt_stamp=%d\n\n",1980ccx->nhm_igi, rpt->nhm_ratio, rpt->clm_ratio,1981rpt->nhm_rpt_stamp, rpt->clm_rpt_stamp);19821983return env_mntr_rpt;1984#endif1985}19861987/*@Environment Monitor*/1988void phydm_env_mntr_watchdog(void *dm_void)1989{1990#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT))1991struct dm_struct *dm = (struct dm_struct *)dm_void;1992struct ccx_info *ccx = &dm->dm_ccx_info;1993boolean nhm_chk_ok = false;1994boolean clm_chk_ok = false;19951996if (!(dm->support_ability & ODM_BB_ENV_MONITOR))1997return;19981999PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);2000nhm_chk_ok = phydm_nhm_mntr_chk(dm, 262); /*@monitor 262ms*/2001clm_chk_ok = phydm_clm_mntr_chk(dm, 262); /*@monitor 262ms*/20022003/*@PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_chk_ok %d\n\n",nhm_chk_ok);*/2004/*@PHYDM_DBG(dm, DBG_ENV_MNTR, "clm_chk_ok %d\n\n",clm_chk_ok);*/20052006if (nhm_chk_ok)2007phydm_nhm_trigger(dm);20082009if (clm_chk_ok)2010phydm_clm_trigger(dm);20112012PHYDM_DBG(dm, DBG_ENV_MNTR,2013"Summary: nhm_ratio=((%d)) clm_ratio=((%d))\n\n",2014ccx->nhm_ratio, ccx->clm_ratio);2015#endif2016}20172018void phydm_env_monitor_init(void *dm_void)2019{2020#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT))2021struct dm_struct *dm = (struct dm_struct *)dm_void;20222023if (!(dm->support_ability & ODM_BB_ENV_MONITOR))2024return;20252026PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__);2027phydm_ccx_hw_restart(dm);2028phydm_nhm_init(dm);2029phydm_clm_init(dm);2030#endif2031}20322033void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used,2034char *output, u32 *_out_len)2035{2036struct dm_struct *dm = (struct dm_struct *)dm_void;2037char help[] = "-h";2038u32 var1[10] = {0};2039u32 used = *_used;2040u32 out_len = *_out_len;2041struct clm_para_info clm_para = {0};2042struct nhm_para_info nhm_para = {0};2043struct env_mntr_rpt rpt = {0};2044struct env_trig_rpt trig_rpt = {0};2045u8 set_result;2046u8 i;20472048PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);20492050if ((strcmp(input[1], help) == 0)) {2051PDM_SNPF(out_len, used, output + used, out_len - used,2052"Basic-Trigger 262ms: {1}\n");2053PDM_SNPF(out_len, used, output + used, out_len - used,2054"Get Result: {100}\n");2055} else if (var1[0] == 100) { /* @Get CLM results */2056set_result = phydm_env_mntr_result(dm, &rpt);20572058PDM_SNPF(out_len, used, output + used, out_len - used,2059"Set Result=%d\n nhm_ratio=%d clm_ratio=%d\n nhm_rpt_stamp=%d, clm_rpt_stamp=%d,\n",2060set_result, rpt.nhm_ratio, rpt.clm_ratio,2061rpt.nhm_rpt_stamp, rpt.clm_rpt_stamp);20622063for (i = 0; i <= 11; i++) {2064PDM_SNPF(out_len, used, output + used, out_len - used,2065"nhm_rpt[%d] = %d (%d percent)\n", i,2066rpt.nhm_result[i],2067(((rpt.nhm_result[i] * 100) + 128) >> 8));2068}20692070} else { /* Set & trigger CLM */2071/*nhm para*/2072nhm_para.incld_txon = NHM_EXCLUDE_TXON;2073nhm_para.incld_cca = NHM_EXCLUDE_CCA;2074nhm_para.div_opt = NHM_CNT_ALL;2075nhm_para.nhm_app = NHM_ACS;2076nhm_para.nhm_lv = NHM_LV_2;2077nhm_para.mntr_time = 262;20782079/*@clm para*/2080clm_para.clm_app = CLM_ACS;2081clm_para.clm_lv = CLM_LV_2;2082clm_para.mntr_time = 262;20832084set_result = phydm_env_mntr_trigger(dm, &nhm_para,2085&clm_para, &trig_rpt);20862087PDM_SNPF(out_len, used, output + used, out_len - used,2088"Set Result=%d, nhm_rpt_stamp=%d, clm_rpt_stamp=%d\n",2089set_result, trig_rpt.nhm_rpt_stamp,2090trig_rpt.clm_rpt_stamp);2091}20922093*_used = used;2094*_out_len = out_len;2095}2096209720982099