/****************************************************************************** * * 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" /*Set NHM period, threshold, disable ignore cca or not, disable ignore txon or not*/ 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 = 0xC350; ccx_info->nhm_inexclude_cca = NHM_EXCLUDE_CCA; ccx_info->nhm_inexclude_txon = NHM_EXCLUDE_TXON; phydm_nhm_setting(p_dm, SET_NHM_SETTING); } 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__)); 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; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); 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, ODM_REG_NHM_DUR_READY_11AC, BIT(17))) { is_ready = 1; break; } } } PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]NHM rdy=%d\n", __FUNCTION__, 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*/ 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_CCX_PERIOD_11N, MASKLWORD, ccx_info->clm_period); odm_set_bb_reg(p_dm, ODM_REG_CLM_11N, BIT(8), 0x1); /*Enable CCX for CLM*/ } PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]CLM period=%dus\n", __func__, ccx_info->clm_period * 4)); } 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, ("[%s]CLM rdy=%d\n", __FUNCTION__, 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; u32 value32 = 0; if (p_dm->support_ic_type & ODM_IC_11AC_SERIES) value32 = odm_get_bb_reg(p_dm, ODM_REG_CLM_RESULT_11AC, MASKDWORD); else if (p_dm->support_ic_type & ODM_IC_11N_SERIES) value32 = odm_get_bb_reg(p_dm, ODM_REG_CLM_RESULT_11N, MASKDWORD); ccx_info->clm_result = (u16)(value32 & MASKLWORD); PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]CLM result = %dus\n", __func__, ccx_info->clm_result * 4)); } 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, (u16)0xC350); /*monitor 200ms*/ } void phydm_ccx_monitor_trigger( void *p_dm_void, u16 monitor_time /*unit 4us*/ ) { 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; if (!(p_dm->support_ability & ODM_BB_ENV_MONITOR)) return; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]===>\n", __FUNCTION__)); /* 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)); } } 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; 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); ccx_info->echo_clm_en = true; ccx_info->clm_period = monitor_time; phydm_clm_setting(p_dm); phydm_clm_trigger(p_dm); } 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 nhm_ratio = 0, clm_ratio = 0; if (!(p_dm->support_ability & ODM_BB_ENV_MONITOR)) return; if (phydm_check_nhm_rdy(p_dm)) phydm_get_nhm_result(p_dm); if (phydm_check_clm_rdy(p_dm)) phydm_get_clm_result(p_dm); if (ccx_info->clm_period != 0) clm_ratio = (ccx_info->clm_result*100) / ccx_info->clm_period; if (ccx_info->nhm_result_total != 0) nhm_ratio = ((ccx_info->nhm_result_total - ccx_info->nhm_result[0])*100) >> 8; ccx_info->clm_ratio = (u8)clm_ratio; ccx_info->nhm_ratio = (u8)nhm_ratio; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]echo_igi=0x%x, nhm_ratio=%d, clm_ratio=%d\n", __FUNCTION__, ccx_info->echo_igi, nhm_ratio, clm_ratio)); } 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 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] + 2 * IGI_TO_NHM_TH_MULTIPLIER * i; PHYDM_DBG(p_dm, DBG_ENV_MNTR, ("[%s]echo_igi=0x%x\n", __FUNCTION__, ccx_info->echo_igi)); }