1 /******************************************************************************
\r
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
\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
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
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
19 ******************************************************************************/
\r
20 #include "mp_precomp.h"
\r
21 #include "phydm_precomp.h"
\r
26 IN u1Byte CrystalCap
\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
37 bEEPROMCheck = (pHalData->EEPROMVersion >= 0x01)?TRUE:FALSE;
\r
39 bEEPROMCheck = TRUE;
\r
42 if(pCfoTrack->CrystalCap == CrystalCap)
\r
45 pCfoTrack->CrystalCap = CrystalCap;
\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
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
79 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_SetCrystalCap(): CrystalCap = 0x%x\n", CrystalCap));
\r
84 odm_GetDefaultCrytaltalCap(
\r
88 PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
\r
89 u1Byte CrystalCap = 0x20;
\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
95 CrystalCap = pHalData->CrystalCap;
\r
97 prtl8192cd_priv priv = pDM_Odm->priv;
\r
99 if(priv->pmib->dot11RFEntry.xcap > 0)
\r
100 CrystalCap = priv->pmib->dot11RFEntry.xcap;
\r
103 CrystalCap = CrystalCap & 0x3f;
\r
111 IN BOOLEAN ATCStatus
\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
117 if(pCfoTrack->bATCStatus == ATCStatus)
\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
130 PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
\r
132 ATCStatus = (BOOLEAN)ODM_GetBBReg(pDM_Odm, ODM_REG(BB_ATC,pDM_Odm), ODM_BIT(BB_ATC,pDM_Odm));
\r
137 ODM_CfoTrackingReset(
\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
144 pCfoTrack->DefXCap = odm_GetDefaultCrytaltalCap(pDM_Odm);
\r
145 pCfoTrack->bAdjust = TRUE;
\r
147 if(pCfoTrack->CrystalCap > pCfoTrack->DefXCap)
\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
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
159 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
\r
160 odm_SetATCStatus(pDM_Odm, TRUE);
\r
165 ODM_CfoTrackingInit(
\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
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
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
188 int CrystalCap = (int)pCfoTrack->CrystalCap;
\r
189 u1Byte Adjust_Xtal = 1;
\r
191 //4 Support ability
\r
192 if(!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING))
\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
198 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking()=========> \n"));
\r
200 if(!pDM_Odm->bLinked || !pDM_Odm->bOneEntryOnly)
\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
209 //3 1. CFO Tracking
\r
210 //4 1.1 No new packet
\r
211 if(pCfoTrack->packetCount == pCfoTrack->packetCount_pre)
\r
213 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): packet counter doesn't change\n"));
\r
216 pCfoTrack->packetCount_pre = pCfoTrack->packetCount;
\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
222 if(pDM_Odm->RFType < ODM_2T2R)
\r
223 CFO_ave = CFO_kHz_A;
\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
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
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
238 pCfoTrack->largeCFOHit = 0;
\r
239 pCfoTrack->CFO_ave_pre = CFO_ave;
\r
241 //4 1.4 Dynamic Xtal threshold
\r
242 if(pCfoTrack->bAdjust == FALSE)
\r
244 if(CFO_ave > CFO_TH_XTAL_HIGH || CFO_ave < (-CFO_TH_XTAL_HIGH))
\r
245 pCfoTrack->bAdjust = TRUE;
\r
249 if(CFO_ave < CFO_TH_XTAL_LOW && CFO_ave > (-CFO_TH_XTAL_LOW))
\r
250 pCfoTrack->bAdjust = FALSE;
\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
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
263 if(pCfoTrack->bAdjust)
\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
270 ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Crystal cap offset = %d\n", Adjust_Xtal));
\r
275 //4 1.7 Adjust Crystal Cap.
\r
276 if(pCfoTrack->bAdjust)
\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
283 if(CrystalCap > 0x3f)
\r
285 else if (CrystalCap < 0)
\r
288 odm_SetCrystalCap(pDM_Odm, (u1Byte)CrystalCap);
\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
293 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
\r
294 if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)
\r
297 //3 2. Dynamic ATC switch
\r
298 if(CFO_ave < CFO_TH_ATC && CFO_ave > -CFO_TH_ATC)
\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
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
315 IN PVOID pPktinfo_VOID,
\r
316 IN s1Byte* pcfotail
\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
324 if(!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING))
\r
327 #if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
\r
328 if(pPktinfo->bPacketMatchBSSID)
\r
330 if(pPktinfo->StationID != 0)
\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
337 pCfoTrack->CFO_tail[i] = (int)pcfotail[i];
\r
340 //3 Update packet counter
\r
341 if(pCfoTrack->packetCount == 0xffffffff)
\r
342 pCfoTrack->packetCount = 0;
\r
344 pCfoTrack->packetCount++;
\r