1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
14 ******************************************************************************/
16 #include "odm_precomp.h"
18 static void odm_SetCrystalCap(void *pDM_VOID, u8 CrystalCap)
20 PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
21 PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
23 struct adapter *Adapter = pDM_Odm->Adapter;
24 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
26 bEEPROMCheck = (pHalData->EEPROMVersion >= 0x01) ? true : false;
28 if (pCfoTrack->CrystalCap == CrystalCap)
31 pCfoTrack->CrystalCap = CrystalCap;
33 /* 0x2C[23:18] = 0x2C[17:12] = CrystalCap */
34 CrystalCap = CrystalCap & 0x3F;
39 (CrystalCap | (CrystalCap << 6))
44 ODM_COMP_CFO_TRACKING,
47 "odm_SetCrystalCap(): CrystalCap = 0x%x\n",
53 static u8 odm_GetDefaultCrytaltalCap(void *pDM_VOID)
55 PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
58 struct adapter *Adapter = pDM_Odm->Adapter;
59 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
61 CrystalCap = pHalData->CrystalCap;
63 CrystalCap = CrystalCap & 0x3f;
68 static void odm_SetATCStatus(void *pDM_VOID, bool ATCStatus)
70 PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
71 PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
73 if (pCfoTrack->bATCStatus == ATCStatus)
78 ODM_REG(BB_ATC, pDM_Odm),
79 ODM_BIT(BB_ATC, pDM_Odm),
82 pCfoTrack->bATCStatus = ATCStatus;
85 static bool odm_GetATCStatus(void *pDM_VOID)
88 PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
90 ATCStatus = (bool)PHY_QueryBBReg(
92 ODM_REG(BB_ATC, pDM_Odm),
93 ODM_BIT(BB_ATC, pDM_Odm)
98 void ODM_CfoTrackingReset(void *pDM_VOID)
100 PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
101 PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
103 pCfoTrack->DefXCap = odm_GetDefaultCrytaltalCap(pDM_Odm);
104 pCfoTrack->bAdjust = true;
106 odm_SetCrystalCap(pDM_Odm, pCfoTrack->DefXCap);
107 odm_SetATCStatus(pDM_Odm, true);
110 void ODM_CfoTrackingInit(void *pDM_VOID)
112 PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
113 PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
116 pCfoTrack->CrystalCap = odm_GetDefaultCrytaltalCap(pDM_Odm);
117 pCfoTrack->bATCStatus = odm_GetATCStatus(pDM_Odm);
118 pCfoTrack->bAdjust = true;
121 ODM_COMP_CFO_TRACKING,
123 ("ODM_CfoTracking_init() =========>\n")
127 ODM_COMP_CFO_TRACKING,
130 "ODM_CfoTracking_init(): bATCStatus = %d, CrystalCap = 0x%x\n",
131 pCfoTrack->bATCStatus,
137 void ODM_CfoTracking(void *pDM_VOID)
139 PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
140 PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
141 int CFO_kHz_A, CFO_kHz_B, CFO_ave = 0;
143 int CrystalCap = (int)pCfoTrack->CrystalCap;
146 /* 4 Support ability */
147 if (!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING)) {
150 ODM_COMP_CFO_TRACKING,
152 ("ODM_CfoTracking(): Return: SupportAbility ODM_BB_CFO_TRACKING is disabled\n")
159 ODM_COMP_CFO_TRACKING,
161 ("ODM_CfoTracking() =========>\n")
164 if (!pDM_Odm->bLinked || !pDM_Odm->bOneEntryOnly) {
165 /* 4 No link or more than one entry */
166 ODM_CfoTrackingReset(pDM_Odm);
169 ODM_COMP_CFO_TRACKING,
172 "ODM_CfoTracking(): Reset: bLinked = %d, bOneEntryOnly = %d\n",
174 pDM_Odm->bOneEntryOnly
178 /* 3 1. CFO Tracking */
179 /* 4 1.1 No new packet */
180 if (pCfoTrack->packetCount == pCfoTrack->packetCount_pre) {
183 ODM_COMP_CFO_TRACKING,
186 "ODM_CfoTracking(): packet counter doesn't change\n"
191 pCfoTrack->packetCount_pre = pCfoTrack->packetCount;
193 /* 4 1.2 Calculate CFO */
194 CFO_kHz_A = (int)(pCfoTrack->CFO_tail[0] * 3125) / 1280;
195 CFO_kHz_B = (int)(pCfoTrack->CFO_tail[1] * 3125) / 1280;
197 if (pDM_Odm->RFType < ODM_2T2R)
200 CFO_ave = (int)(CFO_kHz_A + CFO_kHz_B) >> 1;
203 ODM_COMP_CFO_TRACKING,
206 "ODM_CfoTracking(): CFO_kHz_A = %dkHz, CFO_kHz_B = %dkHz, CFO_ave = %dkHz\n",
213 /* 4 1.3 Avoid abnormal large CFO */
215 (pCfoTrack->CFO_ave_pre >= CFO_ave) ?
216 (pCfoTrack->CFO_ave_pre-CFO_ave) :
217 (CFO_ave-pCfoTrack->CFO_ave_pre);
221 pCfoTrack->largeCFOHit == 0 &&
224 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): first large CFO hit\n"));
225 pCfoTrack->largeCFOHit = 1;
228 pCfoTrack->largeCFOHit = 0;
229 pCfoTrack->CFO_ave_pre = CFO_ave;
231 /* 4 1.4 Dynamic Xtal threshold */
232 if (pCfoTrack->bAdjust == false) {
233 if (CFO_ave > CFO_TH_XTAL_HIGH || CFO_ave < (-CFO_TH_XTAL_HIGH))
234 pCfoTrack->bAdjust = true;
236 if (CFO_ave < CFO_TH_XTAL_LOW && CFO_ave > (-CFO_TH_XTAL_LOW))
237 pCfoTrack->bAdjust = false;
240 /* 4 1.5 BT case: Disable CFO tracking */
241 if (pDM_Odm->bBtEnabled) {
242 pCfoTrack->bAdjust = false;
243 odm_SetCrystalCap(pDM_Odm, pCfoTrack->DefXCap);
246 ODM_COMP_CFO_TRACKING,
248 ("ODM_CfoTracking(): Disable CFO tracking for BT!!\n")
253 if (pCfoTrack->bAdjust) {
254 if (CFO_ave > CFO_TH_XTAL_LOW)
255 Adjust_Xtal = Adjust_Xtal+((CFO_ave-CFO_TH_XTAL_LOW)>>2);
256 else if (CFO_ave < (-CFO_TH_XTAL_LOW))
257 Adjust_Xtal = Adjust_Xtal+((CFO_TH_XTAL_LOW-CFO_ave)>>2);
261 ODM_COMP_CFO_TRACKING,
264 "ODM_CfoTracking(): Crystal cap offset = %d\n",
270 /* 4 1.7 Adjust Crystal Cap. */
271 if (pCfoTrack->bAdjust) {
272 if (CFO_ave > CFO_TH_XTAL_LOW)
273 CrystalCap = CrystalCap + Adjust_Xtal;
274 else if (CFO_ave < (-CFO_TH_XTAL_LOW))
275 CrystalCap = CrystalCap - Adjust_Xtal;
277 if (CrystalCap > 0x3f)
279 else if (CrystalCap < 0)
282 odm_SetCrystalCap(pDM_Odm, (u8)CrystalCap);
286 ODM_COMP_CFO_TRACKING,
289 "ODM_CfoTracking(): Crystal cap = 0x%x, Default Crystal cap = 0x%x\n",
290 pCfoTrack->CrystalCap,
295 /* 3 2. Dynamic ATC switch */
296 if (CFO_ave < CFO_TH_ATC && CFO_ave > -CFO_TH_ATC) {
297 odm_SetATCStatus(pDM_Odm, false);
300 ODM_COMP_CFO_TRACKING,
302 ("ODM_CfoTracking(): Disable ATC!!\n")
305 odm_SetATCStatus(pDM_Odm, true);
308 ODM_COMP_CFO_TRACKING,
310 ("ODM_CfoTracking(): Enable ATC!!\n")
316 void ODM_ParsingCFO(void *pDM_VOID, void *pPktinfo_VOID, s8 *pcfotail)
318 PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
319 PODM_PACKET_INFO_T pPktinfo = (PODM_PACKET_INFO_T)pPktinfo_VOID;
320 PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack;
323 if (!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING))
326 if (pPktinfo->StationID != 0) {
327 /* 3 Update CFO report for path-A & path-B */
328 /* Only paht-A and path-B have CFO tail and short CFO */
329 for (i = ODM_RF_PATH_A; i <= ODM_RF_PATH_B; i++)
330 pCfoTrack->CFO_tail[i] = (int)pcfotail[i];
332 /* 3 Update packet counter */
333 if (pCfoTrack->packetCount == 0xffffffff)
334 pCfoTrack->packetCount = 0;
336 pCfoTrack->packetCount++;