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