mirror of
https://github.com/aircrack-ng/rtl8812au.git
synced 2024-11-14 18:05:36 +00:00
1163 lines
37 KiB
C
1163 lines
37 KiB
C
/******************************************************************************
|
|
*
|
|
* 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;
|
|
} |