489bc49806fe6ef0e33967bfe8aafc049e5c513e
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bu / hal / OUTSRC / phydm_CfoTracking.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  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #include "Mp_Precomp.h"
21 #include "phydm_precomp.h"
22
23 VOID
24 odm_SetCrystalCap(
25         IN              PVOID                                   pDM_VOID,
26         IN              u1Byte                                  CrystalCap
27 )
28 {
29         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;
30         PCFO_TRACKING                           pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);
31         BOOLEAN                                         bEEPROMCheck;
32 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
33         PADAPTER                                        Adapter = pDM_Odm->Adapter;
34         HAL_DATA_TYPE                           *pHalData = GET_HAL_DATA(Adapter);
35
36         bEEPROMCheck = (pHalData->EEPROMVersion >= 0x01)?TRUE:FALSE;
37 #else
38         bEEPROMCheck = TRUE;
39 #endif
40
41         if(pCfoTrack->CrystalCap == CrystalCap)
42                 return;
43
44         pCfoTrack->CrystalCap = CrystalCap;
45
46         if(pDM_Odm->SupportICType & ODM_RTL8192D)
47         {
48                 ODM_SetBBReg(pDM_Odm, REG_AFE_XTAL_CTRL, 0x000000F0, CrystalCap & 0x0F);
49                 ODM_SetBBReg(pDM_Odm, REG_AFE_PLL_CTRL, 0xF0000000, ((CrystalCap & 0xF0) >> 4));
50         }
51         else if(pDM_Odm->SupportICType & ODM_RTL8188E)
52         {
53                 // write 0x24[22:17] = 0x24[16:11] = CrystalCap
54                 CrystalCap = CrystalCap & 0x3F;
55                 ODM_SetBBReg(pDM_Odm, REG_AFE_XTAL_CTRL, 0x007ff800, (CrystalCap | (CrystalCap << 6)));
56         }
57         else if(pDM_Odm->SupportICType & ODM_RTL8812)
58         {
59                 // write 0x2C[30:25] = 0x2C[24:19] = CrystalCap
60                 CrystalCap = CrystalCap & 0x3F;
61                 ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0x7FF80000, (CrystalCap | (CrystalCap << 6)));
62         }       
63         else if (((pDM_Odm->SupportICType & ODM_RTL8723A) && bEEPROMCheck) ||
64                 (pDM_Odm->SupportICType & ODM_RTL8723B) ||(pDM_Odm->SupportICType & ODM_RTL8192E) ||
65                 (pDM_Odm->SupportICType & ODM_RTL8821))
66         {
67                 // 0x2C[23:18] = 0x2C[17:12] = CrystalCap
68                 CrystalCap = CrystalCap & 0x3F;
69                 ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0x00FFF000, (CrystalCap | (CrystalCap << 6)));  
70         }
71         else if(pDM_Odm->SupportICType & ODM_RTL8821B)
72         {
73                 // write 0x28[6:1] = 0x24[30:25] = CrystalCap
74                 CrystalCap = CrystalCap & 0x3F;
75                 ODM_SetBBReg(pDM_Odm, REG_AFE_XTAL_CTRL, 0x7E000000, CrystalCap);
76                 ODM_SetBBReg(pDM_Odm, REG_AFE_PLL_CTRL, 0x7E, CrystalCap);      
77         }
78         else if(pDM_Odm->SupportICType & ODM_RTL8814A)
79         {
80                 // write 0x2C[26:21] = 0x2C[20:15] = CrystalCap
81                 CrystalCap = CrystalCap & 0x3F;
82                 ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0x07FF8000, (CrystalCap | (CrystalCap << 6)));
83         }
84         else 
85         {
86                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_SetCrystalCap(): Use default setting.\n"));
87                 ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0xFFF000, (CrystalCap | (CrystalCap << 6)));
88         }
89
90         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_SetCrystalCap(): CrystalCap = 0x%x\n", CrystalCap));
91 }
92
93 u1Byte
94 odm_GetDefaultCrytaltalCap(
95         IN              PVOID                                   pDM_VOID
96 )
97 {
98         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;
99         u1Byte                                          CrystalCap = 0x20;
100
101 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
102         PADAPTER                                        Adapter = pDM_Odm->Adapter;
103         HAL_DATA_TYPE                           *pHalData = GET_HAL_DATA(Adapter);
104
105         CrystalCap = pHalData->CrystalCap;
106 #else
107         prtl8192cd_priv priv            = pDM_Odm->priv;
108
109         if(priv->pmib->dot11RFEntry.xcap > 0)
110                 CrystalCap = priv->pmib->dot11RFEntry.xcap;
111 #endif
112
113         CrystalCap = CrystalCap & 0x3f;
114
115         return CrystalCap;
116 }
117
118 VOID
119 odm_SetATCStatus(
120         IN              PVOID                                   pDM_VOID,
121         IN              BOOLEAN                                 ATCStatus
122 )
123 {
124         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;
125         PCFO_TRACKING                           pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);
126
127         if(pCfoTrack->bATCStatus == ATCStatus)
128                 return;
129         
130         ODM_SetBBReg(pDM_Odm, ODM_REG(BB_ATC,pDM_Odm), ODM_BIT(BB_ATC,pDM_Odm), ATCStatus);
131         pCfoTrack->bATCStatus = ATCStatus;
132 }
133
134 BOOLEAN
135 odm_GetATCStatus(
136         IN              PVOID                                   pDM_VOID
137 )
138 {
139         BOOLEAN                                         ATCStatus;
140         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;
141
142         ATCStatus = (BOOLEAN)ODM_GetBBReg(pDM_Odm, ODM_REG(BB_ATC,pDM_Odm), ODM_BIT(BB_ATC,pDM_Odm));
143         return ATCStatus;
144 }
145
146 VOID
147 ODM_CfoTrackingReset(
148         IN              PVOID                                   pDM_VOID
149 )
150 {
151         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;
152         PCFO_TRACKING                           pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);
153         u1Byte                                          CrystalCap;
154
155         pCfoTrack->DefXCap = odm_GetDefaultCrytaltalCap(pDM_Odm);
156         pCfoTrack->bAdjust = TRUE;
157         
158 #if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
159         odm_SetCrystalCap(pDM_Odm, pCfoTrack->DefXCap);
160         odm_SetATCStatus(pDM_Odm, TRUE);
161 #else
162         if(pCfoTrack->CrystalCap > pCfoTrack->DefXCap)
163         {
164                 for(CrystalCap = pCfoTrack->CrystalCap; CrystalCap >= pCfoTrack->DefXCap; CrystalCap--)
165                         odm_SetCrystalCap(pDM_Odm, CrystalCap);
166         }
167         else
168         {
169                 for(CrystalCap = pCfoTrack->CrystalCap; CrystalCap <= pCfoTrack->DefXCap; CrystalCap++)
170                         odm_SetCrystalCap(pDM_Odm, CrystalCap);
171         }
172 #endif
173 }
174
175 VOID
176 ODM_CfoTrackingInit(
177         IN              PVOID                                   pDM_VOID
178 )
179 {
180         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;
181         PCFO_TRACKING                           pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);
182       
183         pCfoTrack->DefXCap = pCfoTrack->CrystalCap = odm_GetDefaultCrytaltalCap(pDM_Odm);
184         pCfoTrack->bATCStatus = odm_GetATCStatus(pDM_Odm);
185         pCfoTrack->bAdjust = TRUE;
186         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking_init()=========> \n"));
187         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking_init(): bATCStatus = %d, CrystalCap = 0x%x \n",pCfoTrack->bATCStatus, pCfoTrack->DefXCap));
188 }
189
190 VOID
191 ODM_CfoTracking(
192         IN              PVOID                                   pDM_VOID
193 )
194 {
195         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;
196         PCFO_TRACKING                           pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);
197         int                                                     CFO_kHz_A, CFO_kHz_B, CFO_ave = 0;
198         int                                                     CFO_ave_diff;
199         int                                                     CrystalCap = (int)pCfoTrack->CrystalCap;
200         u1Byte                                          Adjust_Xtal = 1;
201
202         //4 Support ability
203         if(!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING))
204         {
205                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Return: SupportAbility ODM_BB_CFO_TRACKING is disabled\n"));
206                 return;
207         }
208
209         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking()=========> \n"));
210
211         if(!pDM_Odm->bLinked || !pDM_Odm->bOneEntryOnly)
212         {       
213                 //4 No link or more than one entry
214                 ODM_CfoTrackingReset(pDM_Odm);
215                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Reset: bLinked = %d, bOneEntryOnly = %d\n", 
216                         pDM_Odm->bLinked, pDM_Odm->bOneEntryOnly));
217         }
218         else
219         {
220                 //3 1. CFO Tracking
221                 //4 1.1 No new packet
222                 if(pCfoTrack->packetCount == pCfoTrack->packetCount_pre)
223                 {
224                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): packet counter doesn't change\n"));
225                         return;
226                 }
227                 pCfoTrack->packetCount_pre = pCfoTrack->packetCount;
228         
229                 //4 1.2 Calculate CFO
230                 CFO_kHz_A =  (int)(pCfoTrack->CFO_tail[0] * 3125)  / 1280;
231                 CFO_kHz_B =  (int)(pCfoTrack->CFO_tail[1] * 3125)  / 1280;
232                 
233                 if(pDM_Odm->RFType < ODM_2T2R)
234                         CFO_ave = CFO_kHz_A;
235                 else
236                         CFO_ave = (int)(CFO_kHz_A + CFO_kHz_B) >> 1;
237                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): CFO_kHz_A = %dkHz, CFO_kHz_B = %dkHz, CFO_ave = %dkHz\n", 
238                                                 CFO_kHz_A, CFO_kHz_B, CFO_ave));
239
240                 //4 1.3 Avoid abnormal large CFO
241                 CFO_ave_diff = (pCfoTrack->CFO_ave_pre >= CFO_ave)?(pCfoTrack->CFO_ave_pre - CFO_ave):(CFO_ave - pCfoTrack->CFO_ave_pre);
242                 if(CFO_ave_diff > 20 && pCfoTrack->largeCFOHit == 0 && !pCfoTrack->bAdjust)
243                 {
244                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): first large CFO hit\n"));
245                         pCfoTrack->largeCFOHit = 1;
246                         return;
247                 }
248                 else
249                         pCfoTrack->largeCFOHit = 0;
250                 pCfoTrack->CFO_ave_pre = CFO_ave;
251
252                 //4 1.4 Dynamic Xtal threshold
253                 if(pCfoTrack->bAdjust == FALSE)
254                 {
255                         if(CFO_ave > CFO_TH_XTAL_HIGH || CFO_ave < (-CFO_TH_XTAL_HIGH))
256                                 pCfoTrack->bAdjust = TRUE;
257                 }
258                 else
259                 {
260                         if(CFO_ave < CFO_TH_XTAL_LOW && CFO_ave > (-CFO_TH_XTAL_LOW))
261                                 pCfoTrack->bAdjust = FALSE;
262                 }
263
264 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
265                 //4 1.5 BT case: Disable CFO tracking
266                 if(pDM_Odm->bBtEnabled)
267                 {
268                         pCfoTrack->bAdjust = FALSE;
269                         odm_SetCrystalCap(pDM_Odm, pCfoTrack->DefXCap);
270                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Disable CFO tracking for BT!!\n"));
271                 }
272
273                 //4 1.6 Big jump 
274                 if(pCfoTrack->bAdjust)
275                 {
276                         if(CFO_ave > CFO_TH_XTAL_LOW)
277                                 Adjust_Xtal =  Adjust_Xtal + ((CFO_ave - CFO_TH_XTAL_LOW) >> 2);
278                         else if(CFO_ave < (-CFO_TH_XTAL_LOW))
279                                 Adjust_Xtal =  Adjust_Xtal + ((CFO_TH_XTAL_LOW - CFO_ave) >> 2);
280
281                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Crystal cap offset = %d\n", Adjust_Xtal));
282                 }
283 #endif
284
285                 //4 1.7 Adjust Crystal Cap.
286                 if(pCfoTrack->bAdjust)
287                 {
288                         if(CFO_ave > CFO_TH_XTAL_LOW)
289                                 CrystalCap = CrystalCap + Adjust_Xtal;
290                         else if(CFO_ave < (-CFO_TH_XTAL_LOW))
291                                 CrystalCap = CrystalCap - Adjust_Xtal;
292
293                         if(CrystalCap > 0x3f)
294                                 CrystalCap = 0x3f;
295                         else if (CrystalCap < 0)
296                                 CrystalCap = 0;
297
298                         odm_SetCrystalCap(pDM_Odm, (u1Byte)CrystalCap);
299                 }
300                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Crystal cap = 0x%x, Default Crystal cap = 0x%x\n", 
301                         pCfoTrack->CrystalCap, pCfoTrack->DefXCap));
302
303 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
304                 if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)
305                         return;
306                 
307                 //3 2. Dynamic ATC switch
308                 if(CFO_ave < CFO_TH_ATC && CFO_ave > -CFO_TH_ATC)
309                 {
310                         odm_SetATCStatus(pDM_Odm, FALSE);
311                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Disable ATC!!\n"));
312                 }
313                 else
314                 {
315                         odm_SetATCStatus(pDM_Odm, TRUE);
316                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Enable ATC!!\n"));
317                 }
318 #endif
319         }
320 }
321
322 VOID
323 ODM_ParsingCFO(
324         IN              PVOID                   pDM_VOID,
325         IN              PVOID                   pPktinfo_VOID,
326         IN              s1Byte*                         pcfotail
327         )
328 {
329         PDM_ODM_T                               pDM_Odm = (PDM_ODM_T)pDM_VOID;
330         PODM_PACKET_INFO_T              pPktinfo = (PODM_PACKET_INFO_T)pPktinfo_VOID;
331         PCFO_TRACKING                   pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);
332         u1Byte                                  i;
333
334         if(!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING))
335                 return;
336
337 #if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
338         if(pPktinfo->bPacketMatchBSSID)
339 #else
340         if(pPktinfo->StationID != 0)
341 #endif
342         {                               
343                 //3 Update CFO report for path-A & path-B
344                 // Only paht-A and path-B have CFO tail and short CFO
345                 for(i = ODM_RF_PATH_A; i <= ODM_RF_PATH_B; i++)   
346                 {
347                         pCfoTrack->CFO_tail[i] = (int)pcfotail[i];
348                 }
349
350                 //3 Update packet counter
351                 if(pCfoTrack->packetCount == 0xffffffff)
352                         pCfoTrack->packetCount = 0;
353                 else
354                         pCfoTrack->packetCount++;
355         }
356 }
357