net: wireless: rockchip_wlan: add rtl8188fu support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188fu / hal / phydm / phydm_cfotracking.c
diff --git a/drivers/net/wireless/rockchip_wlan/rtl8188fu/hal/phydm/phydm_cfotracking.c b/drivers/net/wireless/rockchip_wlan/rtl8188fu/hal/phydm/phydm_cfotracking.c
new file mode 100644 (file)
index 0000000..64e2965
--- /dev/null
@@ -0,0 +1,347 @@
+/******************************************************************************\r
+ *\r
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.\r
+ *                                        \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms of version 2 of the GNU General Public License as\r
+ * published by the Free Software Foundation.\r
+ *\r
+ * This program is distributed in the hope that it will be useful, but WITHOUT\r
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ * more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA\r
+ *\r
+ *\r
+ ******************************************************************************/\r
+#include "mp_precomp.h"\r
+#include "phydm_precomp.h"\r
+\r
+VOID\r
+odm_SetCrystalCap(\r
+       IN              PVOID                                   pDM_VOID,\r
+       IN              u1Byte                                  CrystalCap\r
+)\r
+{\r
+#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+       PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PCFO_TRACKING                           pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);\r
+       BOOLEAN                                         bEEPROMCheck;\r
+#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+       PADAPTER                                        Adapter = pDM_Odm->Adapter;\r
+       HAL_DATA_TYPE                           *pHalData = GET_HAL_DATA(Adapter);\r
+\r
+       bEEPROMCheck = (pHalData->EEPROMVersion >= 0x01)?TRUE:FALSE;\r
+#else\r
+       bEEPROMCheck = TRUE;\r
+#endif\r
+\r
+       if(pCfoTrack->CrystalCap == CrystalCap)\r
+               return;\r
+\r
+       pCfoTrack->CrystalCap = CrystalCap;\r
+\r
+       if (pDM_Odm->SupportICType & (ODM_RTL8188E | ODM_RTL8188F)) {\r
+               /* write 0x24[22:17] = 0x24[16:11] = CrystalCap */\r
+               CrystalCap = CrystalCap & 0x3F;\r
+               ODM_SetBBReg(pDM_Odm, REG_AFE_XTAL_CTRL, 0x007ff800, (CrystalCap|(CrystalCap << 6)));\r
+       } else if (pDM_Odm->SupportICType & ODM_RTL8812) {\r
+               /* write 0x2C[30:25] = 0x2C[24:19] = CrystalCap */\r
+               CrystalCap = CrystalCap & 0x3F;\r
+               ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0x7FF80000, (CrystalCap|(CrystalCap << 6)));\r
+       } else if (((pDM_Odm->SupportICType & ODM_RTL8723A) && bEEPROMCheck) ||\r
+               (pDM_Odm->SupportICType & (ODM_RTL8703B|ODM_RTL8723B|ODM_RTL8192E|ODM_RTL8821))) {\r
+               /* 0x2C[23:18] = 0x2C[17:12] = CrystalCap */\r
+               CrystalCap = CrystalCap & 0x3F;\r
+               ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0x00FFF000, (CrystalCap|(CrystalCap << 6)));    \r
+       } else if (pDM_Odm->SupportICType & ODM_RTL8821B) {\r
+               /* write 0x28[6:1] = 0x24[30:25] = CrystalCap */\r
+               CrystalCap = CrystalCap & 0x3F;\r
+               ODM_SetBBReg(pDM_Odm, REG_AFE_XTAL_CTRL, 0x7E000000, CrystalCap);\r
+               ODM_SetBBReg(pDM_Odm, REG_AFE_PLL_CTRL, 0x7E, CrystalCap);\r
+       } else if (pDM_Odm->SupportICType & ODM_RTL8814A) {\r
+               /* write 0x2C[26:21] = 0x2C[20:15] = CrystalCap */\r
+               CrystalCap = CrystalCap & 0x3F;\r
+               ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0x07FF8000, (CrystalCap|(CrystalCap << 6)));\r
+       } else if (pDM_Odm->SupportICType & ODM_RTL8822B) {\r
+               /* write 0x24[30:25] = 0x28[6:1] = CrystalCap */\r
+               CrystalCap = CrystalCap & 0x3F;\r
+               ODM_SetBBReg(pDM_Odm, REG_AFE_XTAL_CTRL, 0x7e000000, CrystalCap);\r
+               ODM_SetBBReg(pDM_Odm, REG_AFE_PLL_CTRL, 0x7e, CrystalCap);\r
+       } else {\r
+               ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_SetCrystalCap(): Use default setting.\n"));\r
+               ODM_SetBBReg(pDM_Odm, REG_MAC_PHY_CTRL, 0xFFF000, (CrystalCap|(CrystalCap << 6)));\r
+       }\r
+\r
+       ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_SetCrystalCap(): CrystalCap = 0x%x\n", CrystalCap));\r
+#endif\r
+}\r
+\r
+u1Byte\r
+odm_GetDefaultCrytaltalCap(\r
+       IN              PVOID                                   pDM_VOID\r
+)\r
+{\r
+       PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       u1Byte                                          CrystalCap = 0x20;\r
+\r
+#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+       PADAPTER                                        Adapter = pDM_Odm->Adapter;\r
+       HAL_DATA_TYPE                           *pHalData = GET_HAL_DATA(Adapter);\r
+\r
+       CrystalCap = pHalData->CrystalCap;\r
+#else\r
+       prtl8192cd_priv priv            = pDM_Odm->priv;\r
+\r
+       if(priv->pmib->dot11RFEntry.xcap > 0)\r
+               CrystalCap = priv->pmib->dot11RFEntry.xcap;\r
+#endif\r
+\r
+       CrystalCap = CrystalCap & 0x3f;\r
+\r
+       return CrystalCap;\r
+}\r
+\r
+VOID\r
+odm_SetATCStatus(\r
+       IN              PVOID                                   pDM_VOID,\r
+       IN              BOOLEAN                                 ATCStatus\r
+)\r
+{\r
+       PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PCFO_TRACKING                           pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);\r
+\r
+       if(pCfoTrack->bATCStatus == ATCStatus)\r
+               return;\r
+       \r
+       ODM_SetBBReg(pDM_Odm, ODM_REG(BB_ATC,pDM_Odm), ODM_BIT(BB_ATC,pDM_Odm), ATCStatus);\r
+       pCfoTrack->bATCStatus = ATCStatus;\r
+}\r
+\r
+BOOLEAN\r
+odm_GetATCStatus(\r
+       IN              PVOID                                   pDM_VOID\r
+)\r
+{\r
+       BOOLEAN                                         ATCStatus;\r
+       PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+\r
+       ATCStatus = (BOOLEAN)ODM_GetBBReg(pDM_Odm, ODM_REG(BB_ATC,pDM_Odm), ODM_BIT(BB_ATC,pDM_Odm));\r
+       return ATCStatus;\r
+}\r
+\r
+VOID\r
+ODM_CfoTrackingReset(\r
+       IN              PVOID                                   pDM_VOID\r
+)\r
+{\r
+       PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PCFO_TRACKING                           pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);\r
+\r
+       pCfoTrack->DefXCap = odm_GetDefaultCrytaltalCap(pDM_Odm);\r
+       pCfoTrack->bAdjust = TRUE;\r
+\r
+       if(pCfoTrack->CrystalCap > pCfoTrack->DefXCap)\r
+       {\r
+               odm_SetCrystalCap(pDM_Odm, pCfoTrack->CrystalCap - 1);\r
+               ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD,\r
+                       ("ODM_CfoTrackingReset(): approch default value (0x%x)\n", pCfoTrack->CrystalCap));\r
+       } else if (pCfoTrack->CrystalCap < pCfoTrack->DefXCap)\r
+       {\r
+               odm_SetCrystalCap(pDM_Odm, pCfoTrack->CrystalCap + 1);\r
+               ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD,\r
+                       ("ODM_CfoTrackingReset(): approch default value (0x%x)\n", pCfoTrack->CrystalCap));\r
+       }\r
+\r
+       #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+       odm_SetATCStatus(pDM_Odm, TRUE);\r
+       #endif\r
+}\r
+\r
+VOID\r
+ODM_CfoTrackingInit(\r
+       IN              PVOID                                   pDM_VOID\r
+)\r
+{\r
+       PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PCFO_TRACKING                           pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);\r
+\r
+       pCfoTrack->DefXCap = pCfoTrack->CrystalCap = odm_GetDefaultCrytaltalCap(pDM_Odm);\r
+       pCfoTrack->bATCStatus = odm_GetATCStatus(pDM_Odm);\r
+       pCfoTrack->bAdjust = TRUE;\r
+       ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking_init()=========> \n"));\r
+       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
+}\r
+\r
+VOID\r
+ODM_CfoTracking(\r
+       IN              PVOID                                   pDM_VOID\r
+)\r
+{\r
+       PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PCFO_TRACKING                           pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);\r
+       int                                                     CFO_kHz_A, CFO_kHz_B, CFO_ave = 0;\r
+       int                                                     CFO_ave_diff;\r
+       int                                                     CrystalCap = (int)pCfoTrack->CrystalCap;\r
+       u1Byte                                          Adjust_Xtal = 1;\r
+\r
+       //4 Support ability\r
+       if(!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING))\r
+       {\r
+               ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Return: SupportAbility ODM_BB_CFO_TRACKING is disabled\n"));\r
+               return;\r
+       }\r
+\r
+       ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking()=========> \n"));\r
+\r
+       if(!pDM_Odm->bLinked || !pDM_Odm->bOneEntryOnly)\r
+       {       \r
+               //4 No link or more than one entry\r
+               ODM_CfoTrackingReset(pDM_Odm);\r
+               ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Reset: bLinked = %d, bOneEntryOnly = %d\n", \r
+                       pDM_Odm->bLinked, pDM_Odm->bOneEntryOnly));\r
+       }\r
+       else\r
+       {\r
+               //3 1. CFO Tracking\r
+               //4 1.1 No new packet\r
+               if(pCfoTrack->packetCount == pCfoTrack->packetCount_pre)\r
+               {\r
+                       ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): packet counter doesn't change\n"));\r
+                       return;\r
+               }\r
+               pCfoTrack->packetCount_pre = pCfoTrack->packetCount;\r
+       \r
+               //4 1.2 Calculate CFO\r
+               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
+               CFO_kHz_B =  (int)((pCfoTrack->CFO_tail[1] * 3125)  / 10)>>7;\r
+               \r
+               if(pDM_Odm->RFType < ODM_2T2R)\r
+                       CFO_ave = CFO_kHz_A;\r
+               else\r
+                       CFO_ave = (int)(CFO_kHz_A + CFO_kHz_B) >> 1;\r
+               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
+                                               CFO_kHz_A, CFO_kHz_B, CFO_ave));\r
+\r
+               //4 1.3 Avoid abnormal large CFO\r
+               CFO_ave_diff = (pCfoTrack->CFO_ave_pre >= CFO_ave)?(pCfoTrack->CFO_ave_pre - CFO_ave):(CFO_ave - pCfoTrack->CFO_ave_pre);\r
+               if(CFO_ave_diff > 20 && pCfoTrack->largeCFOHit == 0 && !pCfoTrack->bAdjust)\r
+               {\r
+                       ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): first large CFO hit\n"));\r
+                       pCfoTrack->largeCFOHit = 1;\r
+                       return;\r
+               }\r
+               else\r
+                       pCfoTrack->largeCFOHit = 0;\r
+               pCfoTrack->CFO_ave_pre = CFO_ave;\r
+\r
+               //4 1.4 Dynamic Xtal threshold\r
+               if(pCfoTrack->bAdjust == FALSE)\r
+               {\r
+                       if(CFO_ave > CFO_TH_XTAL_HIGH || CFO_ave < (-CFO_TH_XTAL_HIGH))\r
+                               pCfoTrack->bAdjust = TRUE;\r
+               }\r
+               else\r
+               {\r
+                       if(CFO_ave < CFO_TH_XTAL_LOW && CFO_ave > (-CFO_TH_XTAL_LOW))\r
+                               pCfoTrack->bAdjust = FALSE;\r
+               }\r
+\r
+#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+               //4 1.5 BT case: Disable CFO tracking\r
+               if(pDM_Odm->bBtEnabled)\r
+               {\r
+                       pCfoTrack->bAdjust = FALSE;\r
+                       odm_SetCrystalCap(pDM_Odm, pCfoTrack->DefXCap);\r
+                       ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Disable CFO tracking for BT!!\n"));\r
+               }\r
+/*\r
+               //4 1.6 Big jump \r
+               if(pCfoTrack->bAdjust)\r
+               {\r
+                       if(CFO_ave > CFO_TH_XTAL_LOW)\r
+                               Adjust_Xtal =  Adjust_Xtal + ((CFO_ave - CFO_TH_XTAL_LOW) >> 2);\r
+                       else if(CFO_ave < (-CFO_TH_XTAL_LOW))\r
+                               Adjust_Xtal =  Adjust_Xtal + ((CFO_TH_XTAL_LOW - CFO_ave) >> 2);\r
+\r
+                       ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Crystal cap offset = %d\n", Adjust_Xtal));\r
+               }\r
+*/\r
+#endif\r
+               \r
+               //4 1.7 Adjust Crystal Cap.\r
+               if(pCfoTrack->bAdjust)\r
+               {\r
+                       if(CFO_ave > CFO_TH_XTAL_LOW)\r
+                               CrystalCap = CrystalCap + Adjust_Xtal;\r
+                       else if(CFO_ave < (-CFO_TH_XTAL_LOW))\r
+                               CrystalCap = CrystalCap - Adjust_Xtal;\r
+\r
+                       if(CrystalCap > 0x3f)\r
+                               CrystalCap = 0x3f;\r
+                       else if (CrystalCap < 0)\r
+                               CrystalCap = 0;\r
+\r
+                       odm_SetCrystalCap(pDM_Odm, (u1Byte)CrystalCap);\r
+               }\r
+               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
+                       pCfoTrack->CrystalCap, pCfoTrack->DefXCap));\r
+\r
+#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+               if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)\r
+                       return;\r
+               \r
+               //3 2. Dynamic ATC switch\r
+               if(CFO_ave < CFO_TH_ATC && CFO_ave > -CFO_TH_ATC)\r
+               {\r
+                       odm_SetATCStatus(pDM_Odm, FALSE);\r
+                       ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Disable ATC!!\n"));\r
+               }\r
+               else\r
+               {\r
+                       odm_SetATCStatus(pDM_Odm, TRUE);\r
+                       ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking(): Enable ATC!!\n"));\r
+               }\r
+#endif\r
+       }\r
+}\r
+\r
+VOID\r
+ODM_ParsingCFO(\r
+       IN              PVOID                   pDM_VOID,\r
+       IN              PVOID                   pPktinfo_VOID,\r
+       IN              s1Byte*                         pcfotail\r
+       )\r
+{\r
+       PDM_ODM_T                               pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PODM_PACKET_INFO_T              pPktinfo = (PODM_PACKET_INFO_T)pPktinfo_VOID;\r
+       PCFO_TRACKING                   pCfoTrack = (PCFO_TRACKING)PhyDM_Get_Structure( pDM_Odm, PHYDM_CFOTRACK);\r
+       u1Byte                                  i;\r
+\r
+       if(!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING))\r
+               return;\r
+\r
+#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+       if(pPktinfo->bPacketMatchBSSID)\r
+#else\r
+       if(pPktinfo->StationID != 0)\r
+#endif\r
+       {                               \r
+               //3 Update CFO report for path-A & path-B\r
+               // Only paht-A and path-B have CFO tail and short CFO\r
+               for(i = ODM_RF_PATH_A; i <= ODM_RF_PATH_B; i++)   \r
+               {\r
+                       pCfoTrack->CFO_tail[i] = (int)pcfotail[i];\r
+               }\r
+\r
+               //3 Update packet counter\r
+               if(pCfoTrack->packetCount == 0xffffffff)\r
+                       pCfoTrack->packetCount = 0;\r
+               else\r
+                       pCfoTrack->packetCount++;\r
+       }\r
+}\r
+\r