s2Byte odm_InbandNoise_Monitor_NSeries(PDM_ODM_T pDM_Odm,u8 bPauseDIG,u8 IGIValue,u32 max_time) { u4Byte tmp4b; u1Byte max_rf_path=0,rf_path; u1Byte reg_c50, reg_c58,valid_done=0; struct noise_level noise_data; u32 start = 0, func_start=0, func_end = 0; func_start = ODM_GetCurrentTime(pDM_Odm); pDM_Odm->noise_level.noise_all = 0; if((pDM_Odm->RFType == ODM_1T2R) ||(pDM_Odm->RFType == ODM_2T2R)) max_rf_path = 2; else max_rf_path = 1; ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("odm_DebugControlInbandNoise_Nseries() ==> \n")); ODM_Memory_Set(pDM_Odm,&noise_data,0,sizeof(struct noise_level)); // // Step 1. Disable DIG && Set initial gain. // if(bPauseDIG) { odm_PauseDIG(pDM_Odm,ODM_PAUSE_DIG,IGIValue); } // // Step 2. Disable all power save for read registers // //dcmd_DebugControlPowerSave(pAdapter, PSDisable); // // Step 3. Get noise power level // start = ODM_GetCurrentTime(pDM_Odm); while(1) { //Stop updating idle time pwer report (for driver read) ODM_SetBBReg(pDM_Odm, rFPGA0_TxGainStage, BIT25, 1); //Read Noise Floor Report tmp4b = ODM_GetBBReg(pDM_Odm, 0x8f8,bMaskDWord ); ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("Noise Floor Report (0x8f8) = 0x%08x\n", tmp4b)); //ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskByte0, TestInitialGain); //if(max_rf_path == 2) // ODM_SetBBReg(pDM_Odm, rOFDM0_XBAGCCore1, bMaskByte0, TestInitialGain); //update idle time pwer report per 5us ODM_SetBBReg(pDM_Odm, rFPGA0_TxGainStage, BIT25, 0); noise_data.value[ODM_RF_PATH_A] = (u1Byte)(tmp4b&0xff); noise_data.value[ODM_RF_PATH_B] = (u1Byte)((tmp4b&0xff00)>>8); ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("value_a = 0x%x(%d), value_b = 0x%x(%d)\n", noise_data.value[ODM_RF_PATH_A], noise_data.value[ODM_RF_PATH_A], noise_data.value[ODM_RF_PATH_B], noise_data.value[ODM_RF_PATH_B])); for(rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) { noise_data.sval[rf_path] = (s1Byte)noise_data.value[rf_path]; noise_data.sval[rf_path] /= 2; } ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("sval_a = %d, sval_b = %d\n", noise_data.sval[ODM_RF_PATH_A], noise_data.sval[ODM_RF_PATH_B])); //ODM_delay_ms(10); //ODM_sleep_ms(10); for(rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) { if( (noise_data.valid_cnt[rf_path] < ValidCnt) && (noise_data.sval[rf_path] < Valid_Max && noise_data.sval[rf_path] >= Valid_Min)) { noise_data.valid_cnt[rf_path]++; noise_data.sum[rf_path] += noise_data.sval[rf_path]; ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("RF_Path:%d Valid sval = %d\n", rf_path,noise_data.sval[rf_path])); ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("Sum of sval = %d, \n", noise_data.sum[rf_path])); if(noise_data.valid_cnt[rf_path] == ValidCnt) { valid_done++; ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("After divided, RF_Path:%d ,sum = %d \n", rf_path,noise_data.sum[rf_path])); } } } //printk("####### valid_done:%d #############\n",valid_done); if ((valid_done==max_rf_path) || (ODM_GetProgressingTime(pDM_Odm,start) > max_time)) { for(rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) { //printk("%s PATH_%d - sum = %d, valid_cnt = %d \n",__FUNCTION__,rf_path,noise_data.sum[rf_path], noise_data.valid_cnt[rf_path]); if(noise_data.valid_cnt[rf_path]) noise_data.sum[rf_path] /= noise_data.valid_cnt[rf_path]; else noise_data.sum[rf_path] = 0; } break; } } reg_c50 = (s4Byte)ODM_GetBBReg(pDM_Odm,rOFDM0_XAAGCCore1,bMaskByte0); reg_c50 &= ~BIT7; ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("0x%x = 0x%02x(%d)\n", rOFDM0_XAAGCCore1, reg_c50, reg_c50)); pDM_Odm->noise_level.noise[ODM_RF_PATH_A] = -110 + reg_c50 + noise_data.sum[ODM_RF_PATH_A]; pDM_Odm->noise_level.noise_all += pDM_Odm->noise_level.noise[ODM_RF_PATH_A]; if(max_rf_path == 2){ reg_c58 = (s4Byte)ODM_GetBBReg(pDM_Odm,rOFDM0_XBAGCCore1,bMaskByte0); reg_c58 &= ~BIT7; ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("0x%x = 0x%02x(%d)\n", rOFDM0_XBAGCCore1, reg_c58, reg_c58)); pDM_Odm->noise_level.noise[ODM_RF_PATH_B] = -110 + reg_c58 + noise_data.sum[ODM_RF_PATH_B]; pDM_Odm->noise_level.noise_all += pDM_Odm->noise_level.noise[ODM_RF_PATH_B]; } pDM_Odm->noise_level.noise_all /= max_rf_path; ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("noise_a = %d, noise_b = %d\n", pDM_Odm->noise_level.noise[ODM_RF_PATH_A], pDM_Odm->noise_level.noise[ODM_RF_PATH_B])); // // Step 4. Recover the Dig // if(bPauseDIG) { odm_PauseDIG(pDM_Odm,ODM_RESUME_DIG,IGIValue); } func_end = ODM_GetProgressingTime(pDM_Odm,func_start) ; //printk("%s noise_a = %d, noise_b = %d noise_all:%d (%d ms)\n",__FUNCTION__, // pDM_Odm->noise_level.noise[ODM_RF_PATH_A], // pDM_Odm->noise_level.noise[ODM_RF_PATH_B], // pDM_Odm->noise_level.noise_all,func_end); ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD,("odm_DebugControlInbandNoise_Nseries() <== \n")); return pDM_Odm->noise_level.noise_all; }
static s16 odm_InbandNoise_Monitor_NSeries( PDM_ODM_T pDM_Odm, u8 bPauseDIG, u8 IGIValue, u32 max_time ) { u32 tmp4b; u8 max_rf_path = 0, rf_path; u8 reg_c50, reg_c58, valid_done = 0; struct noise_level noise_data; u32 start = 0, func_start = 0, func_end = 0; func_start = jiffies; pDM_Odm->noise_level.noise_all = 0; if ((pDM_Odm->RFType == ODM_1T2R) || (pDM_Odm->RFType == ODM_2T2R)) max_rf_path = 2; else max_rf_path = 1; ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_DebugControlInbandNoise_Nseries() ==>\n")); memset(&noise_data, 0, sizeof(struct noise_level)); /* */ /* Step 1. Disable DIG && Set initial gain. */ /* */ if (bPauseDIG) odm_PauseDIG(pDM_Odm, ODM_PAUSE_DIG, IGIValue); /* */ /* Step 2. Disable all power save for read registers */ /* */ /* dcmd_DebugControlPowerSave(padapter, PSDisable); */ /* */ /* Step 3. Get noise power level */ /* */ start = jiffies; while (1) { /* Stop updating idle time pwer report (for driver read) */ PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_TxGainStage, BIT25, 1); /* Read Noise Floor Report */ tmp4b = PHY_QueryBBReg(pDM_Odm->Adapter, 0x8f8, bMaskDWord); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("Noise Floor Report (0x8f8) = 0x%08x\n", tmp4b)); /* PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XAAGCCore1, bMaskByte0, TestInitialGain); */ /* if (max_rf_path == 2) */ /* PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBAGCCore1, bMaskByte0, TestInitialGain); */ /* update idle time pwer report per 5us */ PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_TxGainStage, BIT25, 0); noise_data.value[ODM_RF_PATH_A] = (u8)(tmp4b&0xff); noise_data.value[ODM_RF_PATH_B] = (u8)((tmp4b&0xff00)>>8); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("value_a = 0x%x(%d), value_b = 0x%x(%d)\n", noise_data.value[ODM_RF_PATH_A], noise_data.value[ODM_RF_PATH_A], noise_data.value[ODM_RF_PATH_B], noise_data.value[ODM_RF_PATH_B])); for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) { noise_data.sval[rf_path] = (s8)noise_data.value[rf_path]; noise_data.sval[rf_path] /= 2; } ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("sval_a = %d, sval_b = %d\n", noise_data.sval[ODM_RF_PATH_A], noise_data.sval[ODM_RF_PATH_B])); /* mdelay(10); */ /* msleep(10); */ for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) { if ((noise_data.valid_cnt[rf_path] < ValidCnt) && (noise_data.sval[rf_path] < Valid_Max && noise_data.sval[rf_path] >= Valid_Min)) { noise_data.valid_cnt[rf_path]++; noise_data.sum[rf_path] += noise_data.sval[rf_path]; ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("RF_Path:%d Valid sval = %d\n", rf_path, noise_data.sval[rf_path])); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("Sum of sval = %d,\n", noise_data.sum[rf_path])); if (noise_data.valid_cnt[rf_path] == ValidCnt) { valid_done++; ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("After divided, RF_Path:%d , sum = %d\n", rf_path, noise_data.sum[rf_path])); } } } /* printk("####### valid_done:%d #############\n", valid_done); */ if ((valid_done == max_rf_path) || (jiffies_to_msecs(jiffies - start) > max_time)) { for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) { /* printk("%s PATH_%d - sum = %d, valid_cnt = %d\n", __func__, rf_path, noise_data.sum[rf_path], noise_data.valid_cnt[rf_path]); */ if (noise_data.valid_cnt[rf_path]) noise_data.sum[rf_path] /= noise_data.valid_cnt[rf_path]; else noise_data.sum[rf_path] = 0; } break; } } reg_c50 = (s32)PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XAAGCCore1, bMaskByte0); reg_c50 &= ~BIT7; ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("0x%x = 0x%02x(%d)\n", rOFDM0_XAAGCCore1, reg_c50, reg_c50)); pDM_Odm->noise_level.noise[ODM_RF_PATH_A] = -110 + reg_c50 + noise_data.sum[ODM_RF_PATH_A]; pDM_Odm->noise_level.noise_all += pDM_Odm->noise_level.noise[ODM_RF_PATH_A]; if (max_rf_path == 2) { reg_c58 = (s32)PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XBAGCCore1, bMaskByte0); reg_c58 &= ~BIT7; ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("0x%x = 0x%02x(%d)\n", rOFDM0_XBAGCCore1, reg_c58, reg_c58)); pDM_Odm->noise_level.noise[ODM_RF_PATH_B] = -110 + reg_c58 + noise_data.sum[ODM_RF_PATH_B]; pDM_Odm->noise_level.noise_all += pDM_Odm->noise_level.noise[ODM_RF_PATH_B]; } pDM_Odm->noise_level.noise_all /= max_rf_path; ODM_RT_TRACE( pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ( "noise_a = %d, noise_b = %d\n", pDM_Odm->noise_level.noise[ODM_RF_PATH_A], pDM_Odm->noise_level.noise[ODM_RF_PATH_B] ) ); /* */ /* Step 4. Recover the Dig */ /* */ if (bPauseDIG) odm_PauseDIG(pDM_Odm, ODM_RESUME_DIG, IGIValue); func_end = jiffies_to_msecs(jiffies - func_start); /* printk("%s noise_a = %d, noise_b = %d noise_all:%d (%d ms)\n", __func__, */ /* pDM_Odm->noise_level.noise[ODM_RF_PATH_A], */ /* pDM_Odm->noise_level.noise[ODM_RF_PATH_B], */ /* pDM_Odm->noise_level.noise_all, func_end); */ ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_DebugControlInbandNoise_Nseries() <==\n")); return pDM_Odm->noise_level.noise_all; }
void Scan_BB_PSD( IN PDM_ODM_T pDM_Odm, int *PSD_report_right, int *PSD_report_left, int len, int initial_gain) { struct rtl8192cd_priv *priv=pDM_Odm->priv; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; u1Byte ST_TH_origin; u1Byte idx[20]={//96,99,102,106,109,112,115,118,122,125, 224,227,230,234,237,240,243,246,250,253, 0,3,6,10,13,16,19,22,26,29}; int tone_idx, channel_org, channel, i; // set DFS ST_TH to max value ST_TH_origin = RTL_R8(0x91c); RTL_W8(0x91c, 0x4e); // Turn off CCK ODM_SetBBReg(pDM_Odm, 0x808, BIT28, 0); //808[28] // Turn off TX // Pause TX Queue if (!priv->pmib->dot11DFSEntry.disable_tx) ODM_Write1Byte(pDM_Odm, 0x522, 0xFF); //REG_TXPAUSE 改為0x522 // Turn off CCA if(GET_CHIP_VER(priv) == VERSION_8814A){ ODM_SetBBReg(pDM_Odm, 0x838, BIT1, 0x1); //838[1] 設為1 } else{ ODM_SetBBReg(pDM_Odm, 0x838, BIT3, 0x1); //838[3] 設為1 } // PHYTXON while loop PHY_SetBBReg(priv, 0x8fc, 0xfff, 0); i = 0; while (ODM_GetBBReg(pDM_Odm, 0xfa0, BIT18)) { i++; if (i > 1000000) { panic_printk("Wait in %s() more than %d times!\n", __FUNCTION__, i); break; } } // backup IGI_origin , set IGI = 0x3e; pDM_DigTable->bPSDInProgress = TRUE; odm_PauseDIG(pDM_Odm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_7, initial_gain); // Turn off 3-wire ODM_SetBBReg(pDM_Odm, 0xC00, BIT1|BIT0, 0x0); //c00[1:0] 寫0 // pts value = 128, 256, 512, 1024 ODM_SetBBReg(pDM_Odm, 0x910, BIT14|BIT15, 0x1); //910[15:14]設為1, 用256點 ODM_SetBBReg(pDM_Odm, 0x910, BIT12|BIT13, 0x1); //910[13:12]設為1, avg 8 次 // scan in-band PSD channel_org = ODM_GetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, 0x3FF); if(priv, priv->pshare->CurrentChannelBW != HT_CHANNEL_WIDTH_20){ priv->pshare->No_RF_Write = 0; SwBWMode(priv, HT_CHANNEL_WIDTH_20, 0); priv->pshare->No_RF_Write = 1; } if (priv->pshare->rf_ft_var.dfs_scan_inband) { int PSD_report_inband[20]; for (tone_idx=0;tone_idx<len;tone_idx++) PSD_report_inband[tone_idx] = GetPSDData_8812(pDM_Odm, idx[tone_idx], initial_gain); panic_printk("PSD inband: "); for (i=0; i<len; i++) panic_printk("%d ", PSD_report_inband[i]); panic_printk("\n"); } // scan right(higher) neighbor channel if (priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_20) channel = channel_org + 4; else if (priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) channel = channel_org + 6; else channel = channel_org + 10; delay_us(300); // for idle 20M, it will emit signal in right 20M channel priv->pshare->No_RF_Write = 0; ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, 0x3FF, channel); priv->pshare->No_RF_Write = 1; for (tone_idx=0;tone_idx<len;tone_idx++) PSD_report_right[tone_idx] = GetPSDData_8812(pDM_Odm, idx[tone_idx], initial_gain); // scan left(lower) neighbor channel if (priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_20) channel = channel_org - 4; else if (priv->pshare->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) channel = channel_org - 6; else channel = channel_org - 10; priv->pshare->No_RF_Write = 0; ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, 0x3FF, channel); priv->pshare->No_RF_Write = 1; for (tone_idx=0;tone_idx<len;tone_idx++) PSD_report_left[tone_idx] = GetPSDData_8812(pDM_Odm, idx[tone_idx], initial_gain); // restore originl center frequency if(priv, priv->pshare->CurrentChannelBW != HT_CHANNEL_WIDTH_20){ priv->pshare->No_RF_Write = 0; SwBWMode(priv, priv->pshare->CurrentChannelBW, priv->pshare->offset_2nd_chan); priv->pshare->No_RF_Write = 1; } priv->pshare->No_RF_Write = 0; ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, 0x3FF, channel_org); priv->pshare->No_RF_Write = 1; // Turn on 3-wire ODM_SetBBReg(pDM_Odm, 0xc00, BIT1|BIT0, 0x3); //c00[1:0] 寫3 // Restore Current Settings // Resume DIG pDM_DigTable->bPSDInProgress = FALSE; odm_PauseDIG(pDM_Odm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_7, NONE); //Turn on CCA if(GET_CHIP_VER(priv) == VERSION_8814A){ ODM_SetBBReg(pDM_Odm, 0x838, BIT1, 0); //838[1] 設為0 } else{ ODM_SetBBReg(pDM_Odm, 0x838, BIT3, 0); //838[3] 設為0 } // Turn on TX // Resume TX Queue if (!priv->pmib->dot11DFSEntry.disable_tx) ODM_Write1Byte(pDM_Odm, 0x522, 0x00); //REG_TXPAUSE 改為0x522 // CCK on if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G) ODM_SetBBReg(pDM_Odm, 0x808, BIT28, 1); //808[28] // Resume DFS ST_TH RTL_W8(0x91c, ST_TH_origin); }