/****************************************************************************** * * Copyright(c) 2007 - 2017 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * *****************************************************************************/ #include "mp_precomp.h" #include "phydm_precomp.h" #ifdef FAHM_SUPPORT u16 phydm_hw_divider( void *p_dm_void, u16 numerator, u16 denumerator ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; u16 result = DEVIDER_ERROR; u32 tmp_u32 = ((numerator << 16) | denumerator); u32 reg_devider_input; u32 reg_devider_rpt; u8 i; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { reg_devider_input = 0x1cbc; reg_devider_rpt = 0x1f98; } else { reg_devider_input = 0x980; reg_devider_rpt = 0x9f0; } odm_set_bb_reg(p_dm, reg_devider_input, MASKDWORD, tmp_u32); for (i = 0; i < 10; i++) { ODM_delay_ms(1); if (odm_get_bb_reg(p_dm, reg_devider_rpt, BIT(24))) { /*Chk HW rpt is ready*/ result = (u16)odm_get_bb_reg(p_dm, reg_devider_rpt, MASKBYTE2); break; } } return result; } void phydm_fahm_trigger( void *p_dm_void, u16 trigger_period /*unit (4us)*/ ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; u32 fahm_reg1; u32 fahm_reg2; if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { odm_set_bb_reg(p_dm, 0x1cf8, 0xffff00, trigger_period); fahm_reg1 = 0x994; } else { odm_set_bb_reg(p_dm, 0x978, 0xff000000, (trigger_period & 0xff)); odm_set_bb_reg(p_dm, 0x97c, 0xff, (trigger_period & 0xff00)>>8); fahm_reg1 = 0x890; } odm_set_bb_reg(p_dm, fahm_reg1, BIT(2), 0); odm_set_bb_reg(p_dm, fahm_reg1, BIT(2), 1); } void phydm_fahm_set_valid_cnt( void *p_dm_void, u8 numerator_sel, u8 denumerator_sel ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; u32 fahm_reg1; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); if ((ccx_info->fahm_nume_sel == numerator_sel) && (ccx_info->fahm_denum_sel == denumerator_sel)) { PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("no need to update\n", __FUNCTION__)); return; } ccx_info->fahm_nume_sel = numerator_sel; ccx_info->fahm_denum_sel = denumerator_sel; if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { fahm_reg1 = 0x994; } else { fahm_reg1 = 0x890; } odm_set_bb_reg(p_dm, fahm_reg1, 0xe0, numerator_sel); odm_set_bb_reg(p_dm, fahm_reg1, 0x7000, denumerator_sel); } void phydm_get_fahm_result( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; u16 fahm_rpt_cnt[12]; /*packet count*/ u16 fahm_rpt[12]; /*percentage*/ u16 fahm_denumerator; /*packet count*/ u32 reg_rpt, reg_rpt_2; u32 reg_val_tmp; boolean is_ready = false; u8 i; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { reg_rpt = 0x1f80; reg_rpt_2 = 0x1f98; } else { reg_rpt = 0x9d8; reg_rpt_2 = 0x9f0; } for (i = 0; i < 10; i++) { if (odm_get_bb_reg(p_dm, reg_rpt_2, BIT(31))) { /*Chk HW rpt is ready*/ is_ready = true; break; } ODM_delay_ms(1); } if (is_ready == false) return; /*Get Denumerator*/ fahm_denumerator = (u16)odm_get_bb_reg(p_dm, reg_rpt_2, MASKLWORD); PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("Reg[0x%x] fahm_denmrtr = %d\n", reg_rpt_2, fahm_denumerator)); /*Get nemerator*/ for (i = 0; i<6; i++) { reg_val_tmp = odm_get_bb_reg(p_dm, reg_rpt + (i<<2), MASKDWORD); PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("Reg[0x%x] fahm_denmrtr = %d\n", (p_dm, reg_rpt + (i*4), reg_val_tmp))); fahm_rpt_cnt[i*2] = (u16)(reg_val_tmp & MASKLWORD); fahm_rpt_cnt[i*2 +1] = (u16)((reg_val_tmp & MASKHWORD)>>16); } for (i = 0; i<12; i++) { fahm_rpt[i] = phydm_hw_divider(p_dm, fahm_rpt_cnt[i], fahm_denumerator); } PHYDM_DBG(p_dm, DBG_ENV_MNTR,("FAHM_RPT_cnt[10:0]=[%d, %d, %d, %d, %d(IGI), %d, %d, %d, %d, %d, %d, %d]\n", fahm_rpt_cnt[11], fahm_rpt_cnt[10], fahm_rpt_cnt[9], fahm_rpt_cnt[8], fahm_rpt_cnt[7], fahm_rpt_cnt[6], fahm_rpt_cnt[5], fahm_rpt_cnt[4], fahm_rpt_cnt[3], fahm_rpt_cnt[2], fahm_rpt_cnt[1], fahm_rpt_cnt[0])); PHYDM_DBG(p_dm, DBG_ENV_MNTR,("FAHM_RPT_%[10:0]=[%d, %d, %d, %d, %d(IGI), %d, %d, %d, %d, %d, %d, %d]\n", fahm_rpt[11], fahm_rpt[10], fahm_rpt[9], fahm_rpt[8], fahm_rpt[7], fahm_rpt[6], fahm_rpt[5], fahm_rpt[4], fahm_rpt[3], fahm_rpt[2], fahm_rpt[1], fahm_rpt[0])); } void phydm_set_fahm_th_by_igi( void *p_dm_void, u8 igi ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; u8 fahm_th[11]; u8 rssi_th[11]; /*in RSSI scale*/ u8 th_gap = 2 * IGI_TO_NHM_TH_MULTIPLIER; /*beacuse unit is 0.5dB for FAHM*/ u8 i; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); if (ccx_info->env_mntr_igi == igi) { PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("No need to update FAHM_th, IGI=0x%x\n", ccx_info->env_mntr_igi)); return; } ccx_info->env_mntr_igi = igi; /*bkp IGI*/ if (igi >= CCA_CAP) fahm_th[0] = (igi - CCA_CAP) * IGI_TO_NHM_TH_MULTIPLIER; else fahm_th[0] = 0; rssi_th[0] = igi -10 - CCA_CAP; for (i = 1; i <= 10; i++) { fahm_th[i] = fahm_th[0] + th_gap * i; rssi_th[i] = rssi_th[0] + (i<<1); } PHYDM_DBG(p_dm, DBG_ENV_MNTR,("FAHM_RSSI_th[10:0]=[%d, %d, %d, (IGI)%d, %d, %d, %d, %d, %d, %d, %d]\n", rssi_th[10], rssi_th[9], rssi_th[8], rssi_th[7], rssi_th[6], rssi_th[5], rssi_th[4], rssi_th[3], rssi_th[2], rssi_th[1], rssi_th[0])); if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { odm_set_bb_reg(p_dm, 0x1c38, 0xffffff00, ((fahm_th[2]<<24) |(fahm_th[1]<<16) | (fahm_th[0]<<8))); odm_set_bb_reg(p_dm, 0x1c78, 0xffffff00, ((fahm_th[5]<<24) |(fahm_th[4]<<16) | (fahm_th[3]<<8))); odm_set_bb_reg(p_dm, 0x1c7c, 0xffffff00, ((fahm_th[7]<<24) |(fahm_th[6]<<16))); odm_set_bb_reg(p_dm, 0x1cb8, 0xffffff00, ((fahm_th[10]<<24) |(fahm_th[9]<<16) | (fahm_th[8]<<8))); } else { odm_set_bb_reg(p_dm, 0x970, MASKDWORD, ((fahm_th[3]<<24) |(fahm_th[2]<<16) | (fahm_th[1]<<8) | fahm_th[0])); odm_set_bb_reg(p_dm, 0x974, MASKDWORD, ((fahm_th[7]<<24) |(fahm_th[6]<<16) | (fahm_th[5]<<8) | fahm_th[4])); odm_set_bb_reg(p_dm, 0x978, MASKDWORD, ((fahm_th[10]<<16) | (fahm_th[9]<<8) | fahm_th[8])); } } void phydm_fahm_init( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; u32 fahm_reg1; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("IGI=0x%x\n", p_dm->dm_dig_table.cur_ig_value)); if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { fahm_reg1 = 0x994; } else { fahm_reg1 = 0x890; } ccx_info->fahm_period = 65535; odm_set_bb_reg(p_dm, fahm_reg1, 0x6, 3); /*FAHM HW block enable*/ phydm_fahm_set_valid_cnt(p_dm, FAHM_INCLD_FA, (FAHM_INCLD_FA| FAHM_INCLD_CRC_OK |FAHM_INCLD_CRC_ER)); phydm_set_fahm_th_by_igi(p_dm, p_dm->dm_dig_table.cur_ig_value); } void phydm_fahm_dbg( void *p_dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len, u32 input_num ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; char help[] = "-h"; u32 var1[10] = {0}; u32 used = *_used; u32 out_len = *_out_len; u32 i; for (i = 0; i < 2; i++) { if (input[i + 1]) { PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } } if ((strcmp(input[1], help) == 0)) { PHYDM_SNPRINTF((output + used, out_len - used, "{1: trigger, 2:get result}\n")); PHYDM_SNPRINTF((output + used, out_len - used, "{3: MNTR mode sel} {1: driver, 2. FW}\n")); return; } else if (var1[0] == 1) { /* Set & trigger CLM */ phydm_set_fahm_th_by_igi(p_dm, p_dm->dm_dig_table.cur_ig_value); phydm_fahm_trigger(p_dm, ccx_info->fahm_period); PHYDM_SNPRINTF((output + used, out_len - used, "Monitor FAHM for %d * 4us\n", ccx_info->fahm_period)); } else if (var1[0] == 2) { /* Get CLM results */ phydm_get_fahm_result(p_dm); PHYDM_SNPRINTF((output + used, out_len - used, "FAHM_result=%d us\n", (ccx_info->clm_result<<2))); } /*else if (var1[0] == 3) { if (var1[1] == 1) ccx_info->clm_mntr_mode = CLM_DRIVER_MNTR; else if (var1[1] == 2) ccx_info->clm_mntr_mode = CLM_FW_MNTR; }*/ else { PHYDM_SNPRINTF((output + used, out_len - used, "Error\n")); } *_used = used; *_out_len = out_len; } #endif void phydm_c2h_clm_report_handler( void *p_dm_void, u8 *cmd_buf, u8 cmd_len ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; u8 clm_report = cmd_buf[0]; u8 clm_report_idx = cmd_buf[1]; if (cmd_len >=12) return; ccx_info->clm_fw_result_acc += clm_report; ccx_info->clm_fw_result_cnt++; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%d] clm_report= %d\n", ccx_info->clm_fw_result_cnt, clm_report)); } void phydm_clm_h2c( void *p_dm_void, u16 obs_time, u8 fw_clm_en ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; u8 h2c_val[H2C_MAX_LENGTH] = {0}; u8 i = 0; u8 obs_time_idx = 0; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("%s ======>\n", __func__)); PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("obs_time_index=%d *4 ms\n", obs_time)); for (i =1; i<=16; i++) { if (obs_time & BIT(16 -i)) { obs_time_idx = 16-i; break; } } /* obs_time =(2^16 -1) ~ (2^15) => obs_time_idx = 15 (65535 ~ 32768) obs_time =(2^15 -1) ~ (2^14) => obs_time_idx = 14 ... ... ... obs_time =(2^1 -1) ~ (2^0) => obs_time_idx = 0 */ h2c_val[0] = obs_time_idx | (((fw_clm_en) ? 1 : 0)<< 7); h2c_val[1] = CLM_MAX_REPORT_TIME; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("PHYDM h2c[0x4d]=0x%x %x %x %x %x %x %x\n", h2c_val[6], h2c_val[5], h2c_val[4], h2c_val[3], h2c_val[2], h2c_val[1], h2c_val[0])); odm_fill_h2c_cmd(p_dm, PHYDM_H2C_FW_CLM_MNTR, H2C_MAX_LENGTH, h2c_val); } boolean phydm_cal_nhm_cnt( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; u8 noisy_nhm_th_index, low_pwr_cnt = 0, high_pwr_cnt = 0; u8 noisy_nhm_th = 0x52; u8 i; boolean noisy = false, clean = true; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); if (!(p_dm->support_ability & ODM_BB_ENV_MONITOR)) return noisy; /*nhm_th = 0x52 means 0x52/2-110 = -69dbm*/ /* IGI < 0x14 */ if (ccx_info->nhm_th[10] < noisy_nhm_th) return clean; else if (ccx_info->nhm_th[0] > noisy_nhm_th) return (p_dm->noisy_decision) ? noisy : clean; /* 0x14 <= IGI <= 0x37*/ else { /* search index */ noisy_nhm_th_index = (noisy_nhm_th - ccx_info->nhm_th[0]) << 2; for (i = 0; i <= 11; i++) { if (i <= noisy_nhm_th_index) low_pwr_cnt += ccx_info->nhm_result[i]; else high_pwr_cnt += ccx_info->nhm_result[i]; } if (low_pwr_cnt + high_pwr_cnt == 0) return noisy; /* noisy environment */ else if (low_pwr_cnt - high_pwr_cnt >= 100) return clean; /* clean environment */ else return noisy; /* noisy environment */ } } void phydm_nhm_setting( void *p_dm_void, u8 nhm_setting ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("IGI=0x%x\n", ccx_info->echo_igi)); if (nhm_setting == SET_NHM_SETTING) { PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("NHM_th[H->L]=[0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x]\n", ccx_info->nhm_th[10], ccx_info->nhm_th[9], ccx_info->nhm_th[8], ccx_info->nhm_th[7], ccx_info->nhm_th[6], ccx_info->nhm_th[5], ccx_info->nhm_th[4], ccx_info->nhm_th[3], ccx_info->nhm_th[2], ccx_info->nhm_th[1], ccx_info->nhm_th[0])); } if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { if (nhm_setting == SET_NHM_SETTING) { /*Set inexclude_cca, inexclude_txon*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9), ccx_info->nhm_inexclude_cca); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10), ccx_info->nhm_inexclude_txon); /*Set NHM period*/ odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD, ccx_info->nhm_period); /*Set NHM threshold*/ /*Unit: PWdB U(8,1)*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0, ccx_info->nhm_th[0]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1, ccx_info->nhm_th[1]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2, ccx_info->nhm_th[2]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3, ccx_info->nhm_th[3]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0, ccx_info->nhm_th[4]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1, ccx_info->nhm_th[5]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2, ccx_info->nhm_th[6]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3, ccx_info->nhm_th[7]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0, ccx_info->nhm_th[8]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2, ccx_info->nhm_th[9]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3, ccx_info->nhm_th[10]); /*CCX EN*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(8), CCX_EN); } else if (nhm_setting == STORE_NHM_SETTING) { /*Store pervious disable_ignore_cca, disable_ignore_txon*/ ccx_info->nhm_inexclude_cca_restore = (enum nhm_inexclude_cca)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9)); ccx_info->nhm_inexclude_txon_restore = (enum nhm_inexclude_txon)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10)); /*Store pervious NHM period*/ ccx_info->nhm_period_restore = (u16)odm_get_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD); /*Store NHM threshold*/ ccx_info->nhm_th_restore[0] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0); ccx_info->nhm_th_restore[1] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1); ccx_info->nhm_th_restore[2] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2); ccx_info->nhm_th_restore[3] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3); ccx_info->nhm_th_restore[4] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0); ccx_info->nhm_th_restore[5] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1); ccx_info->nhm_th_restore[6] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2); ccx_info->nhm_th_restore[7] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3); ccx_info->nhm_th_restore[8] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0); ccx_info->nhm_th_restore[9] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2); ccx_info->nhm_th_restore[10] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3); } else if (nhm_setting == RESTORE_NHM_SETTING) { /*Set disable_ignore_cca, disable_ignore_txon*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9), ccx_info->nhm_inexclude_cca_restore); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10), ccx_info->nhm_inexclude_txon_restore); /*Set NHM period*/ odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD, ccx_info->nhm_period); /*Set NHM threshold*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0, ccx_info->nhm_th_restore[0]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1, ccx_info->nhm_th_restore[1]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2, ccx_info->nhm_th_restore[2]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3, ccx_info->nhm_th_restore[3]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0, ccx_info->nhm_th_restore[4]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1, ccx_info->nhm_th_restore[5]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2, ccx_info->nhm_th_restore[6]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3, ccx_info->nhm_th_restore[7]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0, ccx_info->nhm_th_restore[8]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2, ccx_info->nhm_th_restore[9]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3, ccx_info->nhm_th_restore[10]); } else return; } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) { if (nhm_setting == SET_NHM_SETTING) { /*Set disable_ignore_cca, disable_ignore_txon*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(9), ccx_info->nhm_inexclude_cca); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(10), ccx_info->nhm_inexclude_txon); /*Set NHM period*/ odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11N, MASKHWORD, ccx_info->nhm_period); /*Set NHM threshold*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0, ccx_info->nhm_th[0]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1, ccx_info->nhm_th[1]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2, ccx_info->nhm_th[2]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3, ccx_info->nhm_th[3]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0, ccx_info->nhm_th[4]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1, ccx_info->nhm_th[5]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2, ccx_info->nhm_th[6]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3, ccx_info->nhm_th[7]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH8_11N, MASKBYTE0, ccx_info->nhm_th[8]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2, ccx_info->nhm_th[9]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3, ccx_info->nhm_th[10]); /*CCX EN*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(8), CCX_EN); } else if (nhm_setting == STORE_NHM_SETTING) { /*Store pervious disable_ignore_cca, disable_ignore_txon*/ ccx_info->nhm_inexclude_cca_restore = (enum nhm_inexclude_cca)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(9)); ccx_info->nhm_inexclude_txon_restore = (enum nhm_inexclude_txon)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(10)); /*Store pervious NHM period*/ ccx_info->nhm_period_restore = (u16)odm_get_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11N, MASKHWORD); /*Store NHM threshold*/ ccx_info->nhm_th_restore[0] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0); ccx_info->nhm_th_restore[1] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1); ccx_info->nhm_th_restore[2] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2); ccx_info->nhm_th_restore[3] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3); ccx_info->nhm_th_restore[4] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0); ccx_info->nhm_th_restore[5] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1); ccx_info->nhm_th_restore[6] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2); ccx_info->nhm_th_restore[7] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3); ccx_info->nhm_th_restore[8] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH8_11N, MASKBYTE0); ccx_info->nhm_th_restore[9] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2); ccx_info->nhm_th_restore[10] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3); } else if (nhm_setting == RESTORE_NHM_SETTING) { /*Set disable_ignore_cca, disable_ignore_txon*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(9), ccx_info->nhm_inexclude_cca_restore); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(10), ccx_info->nhm_inexclude_txon_restore); /*Set NHM period*/ odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11N, MASKHWORD, ccx_info->nhm_period_restore); /*Set NHM threshold*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0, ccx_info->nhm_th_restore[0]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1, ccx_info->nhm_th_restore[1]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2, ccx_info->nhm_th_restore[2]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3, ccx_info->nhm_th_restore[3]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0, ccx_info->nhm_th_restore[4]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1, ccx_info->nhm_th_restore[5]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2, ccx_info->nhm_th_restore[6]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3, ccx_info->nhm_th_restore[7]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH8_11N, MASKBYTE0, ccx_info->nhm_th_restore[8]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2, ccx_info->nhm_th_restore[9]); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3, ccx_info->nhm_th_restore[10]); } else return; } } void phydm_nhm_trigger( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { /*Trigger NHM*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 0); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 1); } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) { /*Trigger NHM*/ odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 0); odm_set_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 1); } } void phydm_get_nhm_result( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; u32 value32; u8 i; if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT_11AC); ccx_info->nhm_result[0] = (u8)(value32 & MASKBYTE0); ccx_info->nhm_result[1] = (u8)((value32 & MASKBYTE1) >> 8); ccx_info->nhm_result[2] = (u8)((value32 & MASKBYTE2) >> 16); ccx_info->nhm_result[3] = (u8)((value32 & MASKBYTE3) >> 24); value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT7_TO_CNT4_11AC); ccx_info->nhm_result[4] = (u8)(value32 & MASKBYTE0); ccx_info->nhm_result[5] = (u8)((value32 & MASKBYTE1) >> 8); ccx_info->nhm_result[6] = (u8)((value32 & MASKBYTE2) >> 16); ccx_info->nhm_result[7] = (u8)((value32 & MASKBYTE3) >> 24); value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT11_TO_CNT8_11AC); ccx_info->nhm_result[8] = (u8)(value32 & MASKBYTE0); ccx_info->nhm_result[9] = (u8)((value32 & MASKBYTE1) >> 8); ccx_info->nhm_result[10] = (u8)((value32 & MASKBYTE2) >> 16); ccx_info->nhm_result[11] = (u8)((value32 & MASKBYTE3) >> 24); /*Get NHM duration*/ value32 = odm_read_4byte(p_dm, ODM_REG_NHM_DUR_READY_11AC); ccx_info->nhm_duration = (u16)(value32 & MASKLWORD); } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) { value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT_11N); ccx_info->nhm_result[0] = (u8)(value32 & MASKBYTE0); ccx_info->nhm_result[1] = (u8)((value32 & MASKBYTE1) >> 8); ccx_info->nhm_result[2] = (u8)((value32 & MASKBYTE2) >> 16); ccx_info->nhm_result[3] = (u8)((value32 & MASKBYTE3) >> 24); value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT7_TO_CNT4_11N); ccx_info->nhm_result[4] = (u8)(value32 & MASKBYTE0); ccx_info->nhm_result[5] = (u8)((value32 & MASKBYTE1) >> 8); ccx_info->nhm_result[6] = (u8)((value32 & MASKBYTE2) >> 16); ccx_info->nhm_result[7] = (u8)((value32 & MASKBYTE3) >> 24); value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT9_TO_CNT8_11N); ccx_info->nhm_result[8] = (u8)((value32 & MASKBYTE2) >> 16); ccx_info->nhm_result[9] = (u8)((value32 & MASKBYTE3) >> 24); value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT10_TO_CNT11_11N); ccx_info->nhm_result[10] = (u8)((value32 & MASKBYTE2) >> 16); ccx_info->nhm_result[11] = (u8)((value32 & MASKBYTE3) >> 24); /*Get NHM duration*/ value32 = odm_read_4byte(p_dm, ODM_REG_NHM_CNT10_TO_CNT11_11N); ccx_info->nhm_duration = (u16)(value32 & MASKLWORD); } /* sum all nhm_result */ ccx_info->nhm_result_total = 0; for (i = 0; i <= 11; i++) ccx_info->nhm_result_total += ccx_info->nhm_result[i]; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("NHM_result=(H->L)[%d %d %d %d (igi) %d %d %d %d %d %d %d %d]\n", ccx_info->nhm_result[11], ccx_info->nhm_result[10], ccx_info->nhm_result[9], ccx_info->nhm_result[8], ccx_info->nhm_result[7], ccx_info->nhm_result[6], ccx_info->nhm_result[5], ccx_info->nhm_result[4], ccx_info->nhm_result[3], ccx_info->nhm_result[2], ccx_info->nhm_result[1], ccx_info->nhm_result[0])); } boolean phydm_check_nhm_rdy( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; u8 i; boolean is_ready = false; if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { for (i = 0; i < 200; i++) { ODM_delay_ms(1); if (odm_get_bb_reg(p_dm, ODM_REG_NHM_DUR_READY_11AC, BIT(16))) { is_ready = 1; break; } } } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) { for (i = 0; i < 200; i++) { ODM_delay_ms(1); if (odm_get_bb_reg(p_dm, 0x8b4, BIT(17))) { is_ready = 1; break; } } } PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("NHM rdy=%d\n", is_ready)); return is_ready; } void phydm_store_nhm_setting( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) { } } void phydm_clm_setting( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11AC, MASKLWORD, ccx_info->clm_period); /*4us sample 1 time*/ /**/ } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) { odm_set_bb_reg(p_dm, ODM_REG_CCX_PERIOD_11N, MASKLWORD, ccx_info->clm_period); /**/ } PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("Set CLM period=%d * 4us\n", ccx_info->clm_period)); } void phydm_clm_hw_restart( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { odm_set_bb_reg(p_dm, ODM_REG_CLM_11AC, BIT(8), 0x0); /*Enable CCX for CLM*/ odm_set_bb_reg(p_dm, ODM_REG_CLM_11AC, BIT(8), 0x1); /*Enable CCX for CLM*/ } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) { odm_set_bb_reg(p_dm, ODM_REG_CLM_11AC, BIT(8), 0x0); /*Enable CCX for CLM*/ odm_set_bb_reg(p_dm, ODM_REG_CLM_11N, BIT(8), 0x1); /*Enable CCX for CLM*/ } PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("Set CLM period=%d * 4us\n", ccx_info->clm_period)); } void phydm_clm_trigger( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { odm_set_bb_reg(p_dm, ODM_REG_CLM_11AC, BIT(0), 0x0); /*Trigger CLM*/ odm_set_bb_reg(p_dm, ODM_REG_CLM_11AC, BIT(0), 0x1); } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) { odm_set_bb_reg(p_dm, ODM_REG_CLM_11N, BIT(0), 0x0); /*Trigger CLM*/ odm_set_bb_reg(p_dm, ODM_REG_CLM_11N, BIT(0), 0x1); } } boolean phydm_check_clm_rdy( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; boolean is_ready = false; u8 i; if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { for (i = 0; i < 200; i++) { ODM_delay_ms(1); if (odm_get_bb_reg(p_dm, ODM_REG_CLM_RESULT_11AC, BIT(16))) { is_ready = 1; break; } } } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) { for (i = 0; i < 200; i++) { ODM_delay_ms(1); if (odm_get_bb_reg(p_dm, ODM_REG_CLM_READY_11N, BIT(16))) { is_ready = 1; break; } } } PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("CLM rdy=%d\n", is_ready)); return is_ready; } void phydm_get_clm_result( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) ccx_info->clm_result = (u16)odm_get_bb_reg(p_dm, ODM_REG_CLM_RESULT_11AC, MASKDWORD); else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) ccx_info->clm_result = (u16)odm_get_bb_reg(p_dm, ODM_REG_CLM_RESULT_11N, MASKDWORD); PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("CLM result = %d *4 us\n", ccx_info->clm_result)); } void phydm_set_nhm_th_by_igi( void *p_dm_void, u8 igi ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; u8 th_gap = 2 * IGI_TO_NHM_TH_MULTIPLIER; u8 i; ccx_info->echo_igi = igi; ccx_info->nhm_th[0] = (ccx_info->echo_igi - CCA_CAP) * IGI_TO_NHM_TH_MULTIPLIER; for (i = 1; i <= 10; i++) ccx_info->nhm_th[i] = ccx_info->nhm_th[0] + th_gap * i; } void phydm_set_clm_mntr_mode( void *p_dm_void, enum clm_monitor_mode_e mode ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; if (ccx_info->clm_mntr_mode != mode) { ccx_info->clm_mntr_mode = mode; phydm_clm_hw_restart(p_dm); if (mode == CLM_DRIVER_MNTR) { phydm_clm_h2c(p_dm,0, 0); } } } void phydm_ccx_monitor_trigger( void *p_dm_void, u16 monitor_time /*unit ms*/ ) { u8 nhm_th[11], i, igi; struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; u16 monitor_time_4us = 0; if (!(p_dm->support_ability & ODM_BB_ENV_MONITOR)) return; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); if (monitor_time == 0) return; if (monitor_time >= 262) monitor_time_4us = 65534; else monitor_time_4us = monitor_time * MS_TO_4US_RATIO; /* check if NHM threshold is changed */ if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) { nhm_th[0] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0); nhm_th[1] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1); nhm_th[2] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2); nhm_th[3] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3); nhm_th[4] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0); nhm_th[5] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1); nhm_th[6] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2); nhm_th[7] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3); nhm_th[8] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0); nhm_th[9] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2); nhm_th[10] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3); } else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) { nhm_th[0] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0); nhm_th[1] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1); nhm_th[2] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2); nhm_th[3] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3); nhm_th[4] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0); nhm_th[5] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1); nhm_th[6] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2); nhm_th[7] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3); nhm_th[8] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH8_11N, MASKBYTE0); nhm_th[9] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2); nhm_th[10] = (u8)odm_get_bb_reg(p_dm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3); } for (i = 0; i <= 10; i++) { if (nhm_th[i] != ccx_info->nhm_th[i]) { PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("nhm_th[%d] != ccx_info->nhm_th[%d]!!\n", i, i)); } } /*[NHM]*/ igi = (u8)odm_get_bb_reg(p_dm, 0xC50, MASKBYTE0); phydm_set_nhm_th_by_igi(p_dm, igi); ccx_info->nhm_period = monitor_time_4us; ccx_info->nhm_inexclude_cca = NHM_EXCLUDE_CCA; ccx_info->nhm_inexclude_txon = NHM_EXCLUDE_TXON; phydm_nhm_setting(p_dm, SET_NHM_SETTING); phydm_nhm_trigger(p_dm); /*[CLM]*/ ccx_info->clm_period = monitor_time_4us; if (ccx_info->clm_mntr_mode == CLM_DRIVER_MNTR) { phydm_clm_setting(p_dm); phydm_clm_trigger(p_dm); } else if (ccx_info->clm_mntr_mode == CLM_FW_MNTR){ phydm_clm_h2c(p_dm, monitor_time_4us, TRUE); } else { PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("CLM_ECHO_DBG_MODE\n")); } } void phydm_ccx_monitor_result( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; u32 clm_result_tmp = 0; if (!(p_dm->support_ability & ODM_BB_ENV_MONITOR)) return; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("%s ======>\n", __func__)); if (phydm_check_nhm_rdy(p_dm)) { phydm_get_nhm_result(p_dm); if (ccx_info->nhm_result_total != 0) ccx_info->nhm_ratio = (u8)(((ccx_info->nhm_result_total - ccx_info->nhm_result[0])*100) >> 8); } if (ccx_info->clm_mntr_mode == CLM_DRIVER_MNTR) { if (phydm_check_clm_rdy(p_dm)) { phydm_get_clm_result(p_dm); if (ccx_info->clm_period != 0) { if (ccx_info->clm_period == 64000) ccx_info->clm_ratio = (u8)(((ccx_info->clm_result >> 6) + 5) /10); else if (ccx_info->clm_period == 65535) { clm_result_tmp = (u32)(ccx_info->clm_result * 100); ccx_info->clm_ratio = (u8)((clm_result_tmp + (1<<15)) >> 16); } else ccx_info->clm_ratio = (u8)((ccx_info->clm_result*100) / ccx_info->clm_period); } } } else { if (ccx_info->clm_fw_result_cnt != 0) ccx_info->clm_ratio = (u8)(ccx_info->clm_fw_result_acc /ccx_info->clm_fw_result_cnt); else ccx_info->clm_ratio = 0; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("clm_fw_result_acc=%d, clm_fw_result_cnt=%d\n", ccx_info->clm_fw_result_acc, ccx_info->clm_fw_result_cnt)); ccx_info->clm_fw_result_acc = 0; ccx_info->clm_fw_result_cnt = 0; } PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("IGI=0x%x, nhm_ratio=%d, clm_ratio=%d\n\n", ccx_info->echo_igi, ccx_info->nhm_ratio, ccx_info->clm_ratio)); } void phydm_ccx_monitor( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; if (!(p_dm->support_ability & ODM_BB_ENV_MONITOR)) return; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); phydm_ccx_monitor_result(p_dm); phydm_ccx_monitor_trigger(p_dm, 262); /*monitor 262ms*/ } void phydm_nhm_init( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("cur_ig_value=0x%x\n", p_dm->dm_dig_table.cur_ig_value)); phydm_set_nhm_th_by_igi(p_dm, p_dm->dm_dig_table.cur_ig_value); ccx_info->nhm_period = 64000; ccx_info->nhm_inexclude_cca = NHM_EXCLUDE_CCA; ccx_info->nhm_inexclude_txon = NHM_EXCLUDE_TXON; phydm_nhm_setting(p_dm, SET_NHM_SETTING); } void phydm_clm_init( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); ccx_info->clm_mntr_mode = CLM_DRIVER_MNTR; ccx_info->clm_period = 65535; phydm_clm_setting(p_dm); phydm_clm_hw_restart(p_dm); } void phydm_env_monitor_init( void *p_dm_void ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; if (!(p_dm->support_ability & ODM_BB_ENV_MONITOR)) return; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); phydm_nhm_init(p_dm); phydm_clm_init(p_dm); } void phydm_clm_dbg( void *p_dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len, u32 input_num ) { struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void; struct _CCX_INFO *ccx_info = &p_dm->dm_ccx_info; char help[] = "-h"; u32 var1[10] = {0}; u32 used = *_used; u32 out_len = *_out_len; u32 i; for (i = 0; i < 2; i++) { if (input[i + 1]) { PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } } if ((strcmp(input[1], help) == 0)) { PHYDM_SNPRINTF((output + used, out_len - used, "{1: trigger, 2:get result}\n")); PHYDM_SNPRINTF((output + used, out_len - used, "{3: MNTR mode sel} {1: driver, 2. FW}\n")); return; } else if (var1[0] == 1) { /* Set & trigger CLM */ ccx_info->clm_period = 65535; /* 65535*4us = 262.14ms*/ phydm_clm_setting(p_dm); phydm_clm_hw_restart(p_dm); phydm_clm_trigger(p_dm); PHYDM_SNPRINTF((output + used, out_len - used, "Monitor CLM for 262ms\n")); } else if (var1[0] == 2) { /* Get CLM results */ phydm_get_clm_result(p_dm); PHYDM_SNPRINTF((output + used, out_len - used, "CLM_result=%d us\n", (ccx_info->clm_result<<2))); } else if (var1[0] == 3) { if (var1[1] == 1) ccx_info->clm_mntr_mode = CLM_DRIVER_MNTR; else if (var1[1] == 2) ccx_info->clm_mntr_mode = CLM_FW_MNTR; } else { PHYDM_SNPRINTF((output + used, out_len - used, "Error\n")); } *_used = used; *_out_len = out_len; }