GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / staging / rtl8723bs / hal / odm_NoiseMonitor.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7
8 #include "odm_precomp.h"
9
10 /*  This function is for inband noise test utility only */
11 /*  To obtain the inband noise level(dbm), do the following. */
12 /*  1. disable DIG and Power Saving */
13 /*  2. Set initial gain = 0x1a */
14 /*  3. Stop updating idle time pwer report (for driver read) */
15 /* - 0x80c[25] */
16
17 #define Valid_Min                               -35
18 #define Valid_Max                       10
19 #define ValidCnt                                5
20
21 static s16 odm_InbandNoise_Monitor_NSeries(
22         struct dm_odm_t *pDM_Odm,
23         u8 bPauseDIG,
24         u8 IGIValue,
25         u32 max_time
26 )
27 {
28         u32 tmp4b;
29         u8 max_rf_path = 0, rf_path;
30         u8 reg_c50, reg_c58, valid_done = 0;
31         struct noise_level noise_data;
32         u32 start  = 0;
33
34         pDM_Odm->noise_level.noise_all = 0;
35
36         max_rf_path = 1;
37
38         memset(&noise_data, 0, sizeof(struct noise_level));
39
40         /*  */
41         /*  Step 1. Disable DIG && Set initial gain. */
42         /*  */
43
44         if (bPauseDIG)
45                 odm_PauseDIG(pDM_Odm, ODM_PAUSE_DIG, IGIValue);
46         /*  */
47         /*  Step 2. Disable all power save for read registers */
48         /*  */
49         /* dcmd_DebugControlPowerSave(padapter, PSDisable); */
50
51         /*  */
52         /*  Step 3. Get noise power level */
53         /*  */
54         start = jiffies;
55         while (1) {
56
57                 /* Stop updating idle time pwer report (for driver read) */
58                 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_TxGainStage, BIT25, 1);
59
60                 /* Read Noise Floor Report */
61                 tmp4b = PHY_QueryBBReg(pDM_Odm->Adapter, 0x8f8, bMaskDWord);
62
63                 /* PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XAAGCCore1, bMaskByte0, TestInitialGain); */
64                 /* if (max_rf_path == 2) */
65                 /* PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBAGCCore1, bMaskByte0, TestInitialGain); */
66
67                 /* update idle time pwer report per 5us */
68                 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_TxGainStage, BIT25, 0);
69
70                 noise_data.value[RF_PATH_A] = (u8)(tmp4b&0xff);
71                 noise_data.value[RF_PATH_B]  = (u8)((tmp4b&0xff00)>>8);
72
73                 for (rf_path = RF_PATH_A; rf_path < max_rf_path; rf_path++) {
74                         noise_data.sval[rf_path] = (s8)noise_data.value[rf_path];
75                         noise_data.sval[rf_path] /= 2;
76                 }
77                 /* mdelay(10); */
78                 /* msleep(10); */
79
80                 for (rf_path = RF_PATH_A; rf_path < max_rf_path; rf_path++) {
81                         if ((noise_data.valid_cnt[rf_path] < ValidCnt) && (noise_data.sval[rf_path] < Valid_Max && noise_data.sval[rf_path] >= Valid_Min)) {
82                                 noise_data.valid_cnt[rf_path]++;
83                                 noise_data.sum[rf_path] += noise_data.sval[rf_path];
84                                 if (noise_data.valid_cnt[rf_path] == ValidCnt) {
85                                         valid_done++;
86                                 }
87
88                         }
89
90                 }
91
92                 /* printk("####### valid_done:%d #############\n", valid_done); */
93                 if ((valid_done == max_rf_path) || (jiffies_to_msecs(jiffies - start) > max_time)) {
94                         for (rf_path = RF_PATH_A; rf_path < max_rf_path; rf_path++) {
95                                 /* printk("%s PATH_%d - sum = %d, valid_cnt = %d\n", __func__, rf_path, noise_data.sum[rf_path], noise_data.valid_cnt[rf_path]); */
96                                 if (noise_data.valid_cnt[rf_path])
97                                         noise_data.sum[rf_path] /= noise_data.valid_cnt[rf_path];
98                                 else
99                                         noise_data.sum[rf_path]  = 0;
100                         }
101                         break;
102                 }
103         }
104         reg_c50 = (s32)PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XAAGCCore1, bMaskByte0);
105         reg_c50 &= ~BIT7;
106         pDM_Odm->noise_level.noise[RF_PATH_A] = -110 + reg_c50 + noise_data.sum[RF_PATH_A];
107         pDM_Odm->noise_level.noise_all += pDM_Odm->noise_level.noise[RF_PATH_A];
108
109         if (max_rf_path == 2) {
110                 reg_c58 = (s32)PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XBAGCCore1, bMaskByte0);
111                 reg_c58 &= ~BIT7;
112                 pDM_Odm->noise_level.noise[RF_PATH_B] = -110 + reg_c58 + noise_data.sum[RF_PATH_B];
113                 pDM_Odm->noise_level.noise_all += pDM_Odm->noise_level.noise[RF_PATH_B];
114         }
115         pDM_Odm->noise_level.noise_all /= max_rf_path;
116
117         /*  */
118         /*  Step 4. Recover the Dig */
119         /*  */
120         if (bPauseDIG)
121                 odm_PauseDIG(pDM_Odm, ODM_RESUME_DIG, IGIValue);
122
123         return pDM_Odm->noise_level.noise_all;
124
125 }
126
127 s16 ODM_InbandNoise_Monitor(void *pDM_VOID, u8 bPauseDIG, u8 IGIValue, u32 max_time)
128 {
129         return odm_InbandNoise_Monitor_NSeries(pDM_VOID, bPauseDIG, IGIValue, max_time);
130 }