net: wireless: rockchip_wlan: add rtl8723ds support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723ds / 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|ODM_RTL8821C)) {\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 #if RTL8821C_SUPPORT\r
170         /* Crystal cap. control by WiFi */\r
171         if (pDM_Odm->SupportICType & ODM_RTL8821C)\r
172                 ODM_SetBBReg(pDM_Odm, 0x10, 0x40, 0x1);\r
173 #endif\r
174 }\r
175 \r
176 VOID\r
177 ODM_CfoTracking(\r
178         IN              PVOID                                   pDM_VOID\r
179 )\r
180 {\r
181         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
182         PCFO_TRACKING                           pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);\r
183         s4Byte                                          CFO_ave = 0;\r
184         u4Byte                                          CFO_rpt_sum, CFO_kHz_avg[4] = {0};\r
185         s4Byte                                          CFO_ave_diff;\r
186         s1Byte                                          CrystalCap = pCfoTrack->CrystalCap;\r
187         u1Byte                                          Adjust_Xtal = 1, i, valid_path_cnt = 0;\r
188 \r
189         //4 Support ability\r
190         if(!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING))\r
191         {\r
192                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Return: SupportAbility ODM_BB_CFO_TRACKING is disabled\n"));\r
193                 return;\r
194         }\r
195 \r
196         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking()=========> \n"));\r
197 \r
198         if(!pDM_Odm->bLinked || !pDM_Odm->bOneEntryOnly)\r
199         {       \r
200                 //4 No link or more than one entry\r
201                 ODM_CfoTrackingReset(pDM_Odm);\r
202                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Reset: bLinked = %d, bOneEntryOnly = %d\n", \r
203                         pDM_Odm->bLinked, pDM_Odm->bOneEntryOnly));\r
204         }\r
205         else\r
206         {\r
207                 //3 1. CFO Tracking\r
208                 //4 1.1 No new packet\r
209                 if(pCfoTrack->packetCount == pCfoTrack->packetCount_pre)\r
210                 {\r
211                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): packet counter doesn't change\n"));\r
212                         return;\r
213                 }\r
214                 pCfoTrack->packetCount_pre = pCfoTrack->packetCount;\r
215         \r
216                 //4 1.2 Calculate CFO\r
217                 for (i = 0; i < pDM_Odm->num_rf_path; i++) {\r
218                 \r
219                         if (pCfoTrack->CFO_cnt[i] == 0)\r
220                                 continue;\r
221 \r
222                         valid_path_cnt++;\r
223                         CFO_rpt_sum = (u4Byte)((pCfoTrack->CFO_tail[i] < 0) ? (0 - pCfoTrack->CFO_tail[i]) :  pCfoTrack->CFO_tail[i]);\r
224                         CFO_kHz_avg[i] = CFO_HW_RPT_2_MHZ(CFO_rpt_sum) / pCfoTrack->CFO_cnt[i];\r
225         \r
226                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("[Path %d] CFO_rpt_sum = (( %d )), CFO_cnt = (( %d )) , CFO_avg= (( %s%d )) kHz\n",\r
227                                 i, CFO_rpt_sum, pCfoTrack->CFO_cnt[i],((pCfoTrack->CFO_tail[i] < 0) ? "-" : " ") ,CFO_kHz_avg[i]));\r
228                 }\r
229                 \r
230                 for (i = 0; i < valid_path_cnt; i++) {\r
231                         \r
232                         //ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("path [%d], pCfoTrack->CFO_tail = %d\n", i, pCfoTrack->CFO_tail[i]));     \r
233                         if (pCfoTrack->CFO_tail[i] < 0) {\r
234                                 CFO_ave += (0-(s4Byte)CFO_kHz_avg[i]);\r
235                                 //ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("CFO_ave = %d\n", CFO_ave));      \r
236                         }\r
237                         else\r
238                                 CFO_ave += (s4Byte)CFO_kHz_avg[i];\r
239                 }\r
240 \r
241                 if (valid_path_cnt >= 2)\r
242                         CFO_ave = CFO_ave / valid_path_cnt;\r
243                         \r
244                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("valid_path_cnt = ((%d)), CFO_ave = ((%d kHz))\n", valid_path_cnt, CFO_ave));\r
245 \r
246                 /*reset counter*/\r
247                 for (i = 0; i < pDM_Odm->num_rf_path; i++) {\r
248                         pCfoTrack->CFO_tail[i] = 0;\r
249                         pCfoTrack->CFO_cnt[i] = 0;\r
250                 }\r
251 \r
252                 //4 1.3 Avoid abnormal large CFO\r
253                 CFO_ave_diff = (pCfoTrack->CFO_ave_pre >= CFO_ave)?(pCfoTrack->CFO_ave_pre - CFO_ave):(CFO_ave - pCfoTrack->CFO_ave_pre);\r
254                 if(CFO_ave_diff > 20 && pCfoTrack->largeCFOHit == 0 && !pCfoTrack->bAdjust)\r
255                 {\r
256                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): first large CFO hit\n"));\r
257                         pCfoTrack->largeCFOHit = 1;\r
258                         return;\r
259                 }\r
260                 else\r
261                         pCfoTrack->largeCFOHit = 0;\r
262                 pCfoTrack->CFO_ave_pre = CFO_ave;\r
263 \r
264                 //4 1.4 Dynamic Xtal threshold\r
265                 if(pCfoTrack->bAdjust == FALSE)\r
266                 {\r
267                         if(CFO_ave > CFO_TH_XTAL_HIGH || CFO_ave < (-CFO_TH_XTAL_HIGH))\r
268                                 pCfoTrack->bAdjust = TRUE;\r
269                 }\r
270                 else\r
271                 {\r
272                         if(CFO_ave < CFO_TH_XTAL_LOW && CFO_ave > (-CFO_TH_XTAL_LOW))\r
273                                 pCfoTrack->bAdjust = FALSE;\r
274                 }\r
275 \r
276 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
277                 //4 1.5 BT case: Disable CFO tracking\r
278                 if(pDM_Odm->bBtEnabled)\r
279                 {\r
280                         pCfoTrack->bAdjust = FALSE;\r
281                         odm_SetCrystalCap(pDM_Odm, pCfoTrack->DefXCap);\r
282                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Disable CFO tracking for BT!!\n"));\r
283                 }\r
284 /*\r
285                 //4 1.6 Big jump \r
286                 if(pCfoTrack->bAdjust)\r
287                 {\r
288                         if(CFO_ave > CFO_TH_XTAL_LOW)\r
289                                 Adjust_Xtal =  Adjust_Xtal + ((CFO_ave - CFO_TH_XTAL_LOW) >> 2);\r
290                         else if(CFO_ave < (-CFO_TH_XTAL_LOW))\r
291                                 Adjust_Xtal =  Adjust_Xtal + ((CFO_TH_XTAL_LOW - CFO_ave) >> 2);\r
292 \r
293                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Crystal cap offset = %d\n", Adjust_Xtal));\r
294                 }\r
295 */\r
296 #endif\r
297                 \r
298                 //4 1.7 Adjust Crystal Cap.\r
299                 if(pCfoTrack->bAdjust)\r
300                 {\r
301                         if(CFO_ave > CFO_TH_XTAL_LOW)\r
302                                 CrystalCap = CrystalCap + Adjust_Xtal;\r
303                         else if(CFO_ave < (-CFO_TH_XTAL_LOW))\r
304                                 CrystalCap = CrystalCap - Adjust_Xtal;\r
305 \r
306                         if(CrystalCap > 0x3f)\r
307                                 CrystalCap = 0x3f;\r
308                         else if (CrystalCap < 0)\r
309                                 CrystalCap = 0;\r
310 \r
311                         odm_SetCrystalCap(pDM_Odm, (u1Byte)CrystalCap);\r
312                 }\r
313                 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
314                         pCfoTrack->CrystalCap, pCfoTrack->DefXCap));\r
315 \r
316 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
317                 if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)\r
318                         return;\r
319                 \r
320                 //3 2. Dynamic ATC switch\r
321                 if(CFO_ave < CFO_TH_ATC && CFO_ave > -CFO_TH_ATC)\r
322                 {\r
323                         odm_SetATCStatus(pDM_Odm, FALSE);\r
324                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Disable ATC!!\n"));\r
325                 }\r
326                 else\r
327                 {\r
328                         odm_SetATCStatus(pDM_Odm, TRUE);\r
329                         ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Enable ATC!!\n"));\r
330                 }\r
331 #endif\r
332         }\r
333 }\r
334 \r
335 VOID\r
336 ODM_ParsingCFO(\r
337         IN              PVOID                   pDM_VOID,\r
338         IN              PVOID                   pPktinfo_VOID,\r
339         IN              s1Byte*                 pcfotail,\r
340         IN              u1Byte                  num_ss\r
341         )\r
342 {\r
343         PDM_ODM_T                               pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
344         PODM_PACKET_INFO_T              pPktinfo = (PODM_PACKET_INFO_T)pPktinfo_VOID;\r
345         PCFO_TRACKING                   pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);\r
346         u1Byte                                  i;\r
347 \r
348         if(!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING))\r
349                 return;\r
350 \r
351 #if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
352         if(pPktinfo->bPacketMatchBSSID)\r
353 #else\r
354         if(pPktinfo->StationID != 0)\r
355 #endif\r
356         {\r
357                 if (num_ss > pDM_Odm->num_rf_path) /*For fool proof*/\r
358                         num_ss = pDM_Odm->num_rf_path;\r
359 \r
360                 /*ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("num_ss = ((%d)),  pDM_Odm->num_rf_path = ((%d))\n", num_ss,  pDM_Odm->num_rf_path));*/\r
361 \r
362                 \r
363                 //3 Update CFO report for path-A & path-B\r
364                 // Only paht-A and path-B have CFO tail and short CFO\r
365                 for(i = 0; i < num_ss; i++)\r
366                 {\r
367                         pCfoTrack->CFO_tail[i] += pcfotail[i];\r
368                         pCfoTrack->CFO_cnt[i] ++;\r
369                         /*ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("[ID %d][path %d][Rate 0x%x] CFO_tail = ((%d)), CFO_tail_sum = ((%d)), CFO_cnt = ((%d))\n", \r
370                                 pPktinfo->StationID, i, pPktinfo->DataRate, pcfotail[i], pCfoTrack->CFO_tail[i], pCfoTrack->CFO_cnt[i]));\r
371                         */\r
372                 }\r
373 \r
374                 //3 Update packet counter\r
375                 if(pCfoTrack->packetCount == 0xffffffff)\r
376                         pCfoTrack->packetCount = 0;\r
377                 else\r
378                         pCfoTrack->packetCount++;\r
379         }\r
380 }\r
381 \r