OSDN Git Service

staging: rtl8723bs: update to the latest driver
[android-x86/kernel.git] / drivers / staging / rtl8723bs / hal / odm_NoiseMonitor.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15
16 #include "odm_precomp.h"
17
18 /*  This function is for inband noise test utility only */
19 /*  To obtain the inband noise level(dbm), do the following. */
20 /*  1. disable DIG and Power Saving */
21 /*  2. Set initial gain = 0x1a */
22 /*  3. Stop updating idle time pwer report (for driver read) */
23 /*      - 0x80c[25] */
24
25 #define Valid_Min                               -35
26 #define Valid_Max                       10
27 #define ValidCnt                                5
28
29 static s16 odm_InbandNoise_Monitor_NSeries(PDM_ODM_T    pDM_Odm, u8 bPauseDIG, u8 IGIValue, u32 max_time)
30 {
31         u32                     tmp4b;
32         u8              max_rf_path = 0, rf_path;
33         u8              reg_c50, reg_c58, valid_done = 0;
34         struct noise_level              noise_data;
35         u32 start  = 0,         func_start = 0, func_end = 0;
36
37         func_start = jiffies;
38         pDM_Odm->noise_level.noise_all = 0;
39
40         if ((pDM_Odm->RFType == ODM_1T2R) ||(pDM_Odm->RFType == ODM_2T2R))
41                 max_rf_path = 2;
42         else
43                 max_rf_path = 1;
44
45         ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_DebugControlInbandNoise_Nseries() ==>\n"));
46
47         memset(&noise_data, 0, sizeof(struct noise_level));
48
49         /*  */
50         /*  Step 1. Disable DIG && Set initial gain. */
51         /*  */
52
53         if (bPauseDIG)
54         {
55                 odm_PauseDIG(pDM_Odm, ODM_PAUSE_DIG, IGIValue);
56         }
57         /*  */
58         /*  Step 2. Disable all power save for read registers */
59         /*  */
60         /* dcmd_DebugControlPowerSave(padapter, PSDisable); */
61
62         /*  */
63         /*  Step 3. Get noise power level */
64         /*  */
65         start = jiffies;
66         while (1)
67         {
68
69                 /* Stop updating idle time pwer report (for driver read) */
70                 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_TxGainStage, BIT25, 1);
71
72                 /* Read Noise Floor Report */
73                 tmp4b = PHY_QueryBBReg(pDM_Odm->Adapter, 0x8f8, bMaskDWord);
74                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("Noise Floor Report (0x8f8) = 0x%08x\n", tmp4b));
75
76                 /* PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XAAGCCore1, bMaskByte0, TestInitialGain); */
77                 /* if (max_rf_path == 2) */
78                 /*      PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBAGCCore1, bMaskByte0, TestInitialGain); */
79
80                 /* update idle time pwer report per 5us */
81                 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_TxGainStage, BIT25, 0);
82
83                 noise_data.value[ODM_RF_PATH_A] = (u8)(tmp4b&0xff);
84                 noise_data.value[ODM_RF_PATH_B]  = (u8)((tmp4b&0xff00)>>8);
85
86                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("value_a = 0x%x(%d), value_b = 0x%x(%d)\n",
87                         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]));
88
89                  for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++)
90                  {
91                         noise_data.sval[rf_path] = (s8)noise_data.value[rf_path];
92                         noise_data.sval[rf_path] /= 2;
93                  }
94
95
96                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("sval_a = %d, sval_b = %d\n",
97                         noise_data.sval[ODM_RF_PATH_A], noise_data.sval[ODM_RF_PATH_B]));
98                 /* mdelay(10); */
99                 /* msleep(10); */
100
101                 for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++)
102                 {
103                         if ((noise_data.valid_cnt[rf_path] < ValidCnt) && (noise_data.sval[rf_path] < Valid_Max && noise_data.sval[rf_path] >= Valid_Min))
104                         {
105                                 noise_data.valid_cnt[rf_path]++;
106                                 noise_data.sum[rf_path] += noise_data.sval[rf_path];
107                                 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]));
108                                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("Sum of sval = %d,\n", noise_data.sum[rf_path]));
109                                 if (noise_data.valid_cnt[rf_path] == ValidCnt)
110                                 {
111                                         valid_done++;
112                                         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]));
113                                 }
114
115                         }
116
117                 }
118
119                 /* printk("####### valid_done:%d #############\n", valid_done); */
120                 if ((valid_done ==max_rf_path) || (jiffies_to_msecs(jiffies - start) > max_time))
121                 {
122                         for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++)
123                         {
124                                 /* printk("%s PATH_%d - sum = %d, valid_cnt = %d\n", __func__, rf_path, noise_data.sum[rf_path], noise_data.valid_cnt[rf_path]); */
125                                 if (noise_data.valid_cnt[rf_path])
126                                         noise_data.sum[rf_path] /= noise_data.valid_cnt[rf_path];
127                                 else
128                                         noise_data.sum[rf_path]  = 0;
129                         }
130                         break;
131                 }
132         }
133         reg_c50 = (s32)PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XAAGCCore1, bMaskByte0);
134         reg_c50 &= ~BIT7;
135         ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("0x%x = 0x%02x(%d)\n", rOFDM0_XAAGCCore1, reg_c50, reg_c50));
136         pDM_Odm->noise_level.noise[ODM_RF_PATH_A] = -110 + reg_c50 + noise_data.sum[ODM_RF_PATH_A];
137         pDM_Odm->noise_level.noise_all += pDM_Odm->noise_level.noise[ODM_RF_PATH_A];
138
139         if (max_rf_path == 2) {
140                 reg_c58 = (s32)PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XBAGCCore1, bMaskByte0);
141                 reg_c58 &= ~BIT7;
142                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("0x%x = 0x%02x(%d)\n", rOFDM0_XBAGCCore1, reg_c58, reg_c58));
143                 pDM_Odm->noise_level.noise[ODM_RF_PATH_B] = -110 + reg_c58 + noise_data.sum[ODM_RF_PATH_B];
144                 pDM_Odm->noise_level.noise_all += pDM_Odm->noise_level.noise[ODM_RF_PATH_B];
145         }
146         pDM_Odm->noise_level.noise_all /= max_rf_path;
147
148         ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("noise_a = %d, noise_b = %d\n",
149                 pDM_Odm->noise_level.noise[ODM_RF_PATH_A],
150                 pDM_Odm->noise_level.noise[ODM_RF_PATH_B]));
151
152         /*  */
153         /*  Step 4. Recover the Dig */
154         /*  */
155         if (bPauseDIG)
156         {
157                 odm_PauseDIG(pDM_Odm, ODM_RESUME_DIG, IGIValue);
158         }
159         func_end = jiffies_to_msecs(jiffies - func_start) ;
160         /* printk("%s noise_a = %d, noise_b = %d noise_all:%d (%d ms)\n", __func__, */
161         /*      pDM_Odm->noise_level.noise[ODM_RF_PATH_A], */
162         /*      pDM_Odm->noise_level.noise[ODM_RF_PATH_B], */
163         /*      pDM_Odm->noise_level.noise_all, func_end); */
164
165         ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_DebugControlInbandNoise_Nseries() <==\n"));
166         return pDM_Odm->noise_level.noise_all;
167
168 }
169 s16 ODM_InbandNoise_Monitor(void *pDM_VOID, u8 bPauseDIG, u8 IGIValue, u32 max_time)
170 {
171         return odm_InbandNoise_Monitor_NSeries(pDM_VOID, bPauseDIG, IGIValue, max_time);
172 }