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