net: wireless: rockchip: add rtl8822be pcie wifi driver
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8822be / hal / phydm / phydm_acs.c
diff --git a/drivers/net/wireless/rockchip_wlan/rtl8822be/hal/phydm/phydm_acs.c b/drivers/net/wireless/rockchip_wlan/rtl8822be/hal/phydm/phydm_acs.c
new file mode 100644 (file)
index 0000000..5227a3a
--- /dev/null
@@ -0,0 +1,1226 @@
+/******************************************************************************\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
+\r
+//============================================================\r
+// include files\r
+//============================================================\r
+#include "mp_precomp.h"\r
+#include "phydm_precomp.h"\r
+\r
+\r
+u1Byte\r
+ODM_GetAutoChannelSelectResult(\r
+       IN              PVOID                   pDM_VOID,\r
+       IN              u1Byte                  Band\r
+)\r
+{\r
+       PDM_ODM_T                               pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PACS                                    pACS = &pDM_Odm->DM_ACS;\r
+\r
+#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+       if(Band == ODM_BAND_2_4G)\r
+       {\r
+               ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[ACS] ODM_GetAutoChannelSelectResult(): CleanChannel_2G(%d)\n", pACS->CleanChannel_2G));\r
+               return (u1Byte)pACS->CleanChannel_2G;   \r
+       }\r
+       else\r
+       {\r
+               ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[ACS] ODM_GetAutoChannelSelectResult(): CleanChannel_5G(%d)\n", pACS->CleanChannel_5G));\r
+               return (u1Byte)pACS->CleanChannel_5G;   \r
+       }\r
+#else\r
+       return (u1Byte)pACS->CleanChannel_2G;\r
+#endif\r
+\r
+}\r
+\r
+VOID\r
+odm_AutoChannelSelectSetting(\r
+       IN              PVOID                   pDM_VOID,\r
+       IN              BOOLEAN                 IsEnable\r
+)\r
+{\r
+#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+       PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       u2Byte                                          period = 0x2710;// 40ms in default\r
+       u2Byte                                          NHMType = 0x7;\r
+\r
+       ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectSetting()=========> \n"));\r
+\r
+       if(IsEnable)\r
+       {//20 ms\r
+               period = 0x1388;\r
+               NHMType = 0x1;\r
+       }\r
+\r
+       if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)\r
+       {\r
+               //PHY parameters initialize for ac series\r
+               ODM_Write2Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC+2, period);     //0x990[31:16]=0x2710   Time duration for NHM unit: 4us, 0x2710=40ms\r
+               //ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC, BIT8|BIT9|BIT10, NHMType);   //0x994[9:8]=3                  enable CCX\r
+       }\r
+       else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES)\r
+       {\r
+               //PHY parameters initialize for n series\r
+               ODM_Write2Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11N+2, period);      //0x894[31:16]=0x2710   Time duration for NHM unit: 4us, 0x2710=40ms\r
+               //ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, NHMType);    //0x890[9:8]=3                  enable CCX              \r
+       }\r
+#endif\r
+}\r
+\r
+VOID\r
+odm_AutoChannelSelectInit(\r
+       IN              PVOID                   pDM_VOID\r
+)\r
+{\r
+#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+       PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PACS                                            pACS = &pDM_Odm->DM_ACS;\r
+       u1Byte                                          i;\r
+\r
+       if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT))\r
+               return;\r
+\r
+       if(pACS->bForceACSResult)\r
+               return;\r
+\r
+       ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectInit()=========> \n"));\r
+\r
+       pACS->CleanChannel_2G = 1;\r
+       pACS->CleanChannel_5G = 36;\r
+\r
+       for (i = 0; i < ODM_MAX_CHANNEL_2G; ++i)\r
+       {\r
+               pACS->Channel_Info_2G[0][i] = 0;\r
+               pACS->Channel_Info_2G[1][i] = 0;\r
+       }\r
+\r
+       if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)\r
+       {\r
+               for (i = 0; i < ODM_MAX_CHANNEL_5G; ++i)\r
+               {\r
+                       pACS->Channel_Info_5G[0][i] = 0;\r
+                       pACS->Channel_Info_5G[1][i] = 0;\r
+               }\r
+       }\r
+#endif\r
+}\r
+\r
+VOID\r
+odm_AutoChannelSelectReset(\r
+       IN              PVOID                   pDM_VOID\r
+)\r
+{\r
+#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+       PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PACS                                            pACS = &pDM_Odm->DM_ACS;\r
+\r
+       if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT))\r
+               return;\r
+\r
+       if(pACS->bForceACSResult)\r
+               return;\r
+\r
+       ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectReset()=========> \n"));\r
+\r
+       odm_AutoChannelSelectSetting(pDM_Odm,TRUE);// for 20ms measurement\r
+       Phydm_NHMCounterStatisticsReset(pDM_Odm);\r
+#endif\r
+}\r
+\r
+VOID\r
+odm_AutoChannelSelect(\r
+       IN              PVOID                   pDM_VOID,\r
+       IN              u1Byte                  Channel\r
+)\r
+{\r
+#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
+       PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PACS                                            pACS = &pDM_Odm->DM_ACS;\r
+       u1Byte                                          ChannelIDX = 0, SearchIDX = 0;\r
+       u2Byte                                          MaxScore=0;\r
+\r
+       if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT))\r
+       {\r
+               ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Return: SupportAbility ODM_BB_NHM_CNT is disabled\n"));\r
+               return;\r
+       }\r
+\r
+       if(pACS->bForceACSResult)\r
+       {\r
+               ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Force 2G clean channel = %d, 5G clean channel = %d\n",\r
+                       pACS->CleanChannel_2G, pACS->CleanChannel_5G));\r
+               return;\r
+       }\r
+\r
+       ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Channel = %d=========> \n", Channel));\r
+\r
+       Phydm_GetNHMCounterStatistics(pDM_Odm);\r
+       odm_AutoChannelSelectSetting(pDM_Odm,FALSE);\r
+\r
+       if(Channel >=1 && Channel <=14)\r
+       {\r
+               ChannelIDX = Channel - 1;\r
+               pACS->Channel_Info_2G[1][ChannelIDX]++;\r
+               \r
+               if(pACS->Channel_Info_2G[1][ChannelIDX] >= 2)\r
+                       pACS->Channel_Info_2G[0][ChannelIDX] = (pACS->Channel_Info_2G[0][ChannelIDX] >> 1) + \r
+                       (pACS->Channel_Info_2G[0][ChannelIDX] >> 2) + (pDM_Odm->NHM_cnt_0>>2);\r
+               else\r
+                       pACS->Channel_Info_2G[0][ChannelIDX] = pDM_Odm->NHM_cnt_0;\r
+       \r
+               ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): NHM_cnt_0 = %d \n", pDM_Odm->NHM_cnt_0));\r
+               ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Channel_Info[0][%d] = %d, Channel_Info[1][%d] = %d\n", ChannelIDX, pACS->Channel_Info_2G[0][ChannelIDX], ChannelIDX, pACS->Channel_Info_2G[1][ChannelIDX]));\r
+\r
+               for(SearchIDX = 0; SearchIDX < ODM_MAX_CHANNEL_2G; SearchIDX++)\r
+               {\r
+                       if(pACS->Channel_Info_2G[1][SearchIDX] != 0)\r
+                       {\r
+                               if(pACS->Channel_Info_2G[0][SearchIDX] >= MaxScore)\r
+                               {\r
+                                       MaxScore = pACS->Channel_Info_2G[0][SearchIDX];\r
+                                       pACS->CleanChannel_2G = SearchIDX+1;\r
+                               }\r
+                       }\r
+               }\r
+               ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("(1)odm_AutoChannelSelect(): 2G: CleanChannel_2G = %d, MaxScore = %d \n", \r
+                       pACS->CleanChannel_2G, MaxScore));\r
+\r
+       }\r
+       else if(Channel >= 36)\r
+       {\r
+               // Need to do\r
+               pACS->CleanChannel_5G = Channel;\r
+       }\r
+#endif\r
+}\r
+\r
+#if ( DM_ODM_SUPPORT_TYPE & ODM_AP )\r
+\r
+VOID\r
+phydm_AutoChannelSelectSettingAP(\r
+    IN  PVOID   pDM_VOID,\r
+    IN  u4Byte  setting,             // 0: STORE_DEFAULT_NHM_SETTING; 1: RESTORE_DEFAULT_NHM_SETTING, 2: ACS_NHM_SETTING\r
+    IN  u4Byte  acs_step\r
+)\r
+{\r
+    PDM_ODM_T           pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+    prtl8192cd_priv       priv           = pDM_Odm->priv;\r
+    PACS                    pACS         = &pDM_Odm->DM_ACS;\r
+\r
+    ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectSettingAP()=========> \n"));\r
+\r
+    //3 Store Default Setting\r
+    if(setting == STORE_DEFAULT_NHM_SETTING)\r
+    {\r
+        ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("STORE_DEFAULT_NHM_SETTING\n"));\r
+    \r
+        if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)     // store Reg0x990, Reg0x994, Reg0x998, Reg0x99C, Reg0x9a0\r
+        {\r
+            pACS->Reg0x990 = ODM_Read4Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC);                // Reg0x990\r
+            pACS->Reg0x994 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC);           // Reg0x994\r
+            pACS->Reg0x998 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC);       // Reg0x998\r
+            pACS->Reg0x99C = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC);       // Reg0x99c\r
+            pACS->Reg0x9A0 = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_TH8_11AC);                   // Reg0x9a0, u1Byte            \r
+        }\r
+        else if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES)\r
+        {\r
+            pACS->Reg0x890 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N);             // Reg0x890\r
+            pACS->Reg0x894 = ODM_Read4Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11N);                  // Reg0x894\r
+            pACS->Reg0x898 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N);         // Reg0x898\r
+            pACS->Reg0x89C = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N);         // Reg0x89c\r
+            pACS->Reg0xE28 = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_TH8_11N);                     // Reg0xe28, u1Byte    \r
+        }\r
+    }\r
+\r
+    //3 Restore Default Setting\r
+    else if(setting == RESTORE_DEFAULT_NHM_SETTING)\r
+    {\r
+        ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("RESTORE_DEFAULT_NHM_SETTING\n"));\r
+        \r
+        if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)     // store Reg0x990, Reg0x994, Reg0x998, Reg0x99C, Reg0x9a0\r
+        {\r
+            ODM_Write4Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC,          pACS->Reg0x990);\r
+            ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC,     pACS->Reg0x994);\r
+            ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, pACS->Reg0x998);\r
+            ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, pACS->Reg0x99C);\r
+            ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11AC,             pACS->Reg0x9A0);   \r
+        }\r
+        else if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES)\r
+        {\r
+            ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N,     pACS->Reg0x890);\r
+            ODM_Write4Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC,          pACS->Reg0x894);\r
+            ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, pACS->Reg0x898);\r
+            ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, pACS->Reg0x89C);\r
+            ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11N,             pACS->Reg0xE28); \r
+        }        \r
+    }\r
+\r
+    //3 ACS Setting\r
+    else if(setting == ACS_NHM_SETTING)\r
+    {        \r
+        ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("ACS_NHM_SETTING\n"));\r
+        u2Byte  period;\r
+        period = 0x61a8;\r
+        pACS->ACS_Step = acs_step;\r
+            \r
+        if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)\r
+        {   \r
+            //4 Set NHM period, 0x990[31:16]=0x61a8, Time duration for NHM unit: 4us, 0x61a8=100ms\r
+            ODM_Write2Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC+2, period);\r
+            //4 Set NHM ignore_cca=1, ignore_txon=1, ccx_en=0\r
+            ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC,BIT8|BIT9|BIT10, 3);\r
+            \r
+            if(pACS->ACS_Step == 0)\r
+            {\r
+                //4 Set IGI\r
+                ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E);\r
+                if (get_rf_mimo_mode(priv) != MIMO_1T1R)\r
+                                       ODM_SetBBReg(pDM_Odm,0xe50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E);\r
+                    \r
+                //4 Set ACS NHM threshold\r
+                ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0x82786e64);\r
+                ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffff8c);\r
+                ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11AC, 0xff);\r
+                ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC+2, 0xffff);\r
+                \r
+            }\r
+            else if(pACS->ACS_Step == 1)\r
+            {\r
+                //4 Set IGI\r
+                ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A);\r
+                if (get_rf_mimo_mode(priv) != MIMO_1T1R)\r
+                                       ODM_SetBBReg(pDM_Odm,0xe50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A);\r
+\r
+                //4 Set ACS NHM threshold\r
+                ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0x5a50463c);\r
+                ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffff64);\r
+                \r
+            }\r
+\r
+        }\r
+        else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES)\r
+        {\r
+            //4 Set NHM period, 0x894[31:16]=0x61a8, Time duration for NHM unit: 4us, 0x61a8=100ms\r
+            ODM_Write2Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC+2, period);\r
+            //4 Set NHM ignore_cca=1, ignore_txon=1, ccx_en=0\r
+            ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N,BIT8|BIT9|BIT10, 3);\r
+            \r
+            if(pACS->ACS_Step == 0)\r
+            {\r
+                //4 Set IGI\r
+                ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E);\r
+                if (get_rf_mimo_mode(priv) != MIMO_1T1R)\r
+                                       ODM_SetBBReg(pDM_Odm,0xc58,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E);\r
+            \r
+                //4 Set ACS NHM threshold\r
+                ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0x82786e64);\r
+                ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffff8c);\r
+                ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11N, 0xff);\r
+                ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff);\r
+                \r
+            }\r
+            else if(pACS->ACS_Step == 1)\r
+            {\r
+                //4 Set IGI\r
+                ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A);\r
+                if (get_rf_mimo_mode(priv) != MIMO_1T1R)\r
+                                       ODM_SetBBReg(pDM_Odm,0xc58,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A);\r
+            \r
+                //4 Set ACS NHM threshold\r
+                ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0x5a50463c);\r
+                ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffff64);\r
+\r
+            }            \r
+        }\r
+    }  \r
+       \r
+}\r
+\r
+VOID\r
+phydm_GetNHMStatisticsAP(\r
+    IN  PVOID       pDM_VOID,\r
+    IN  u4Byte      idx,                // @ 2G, Real channel number = idx+1\r
+    IN  u4Byte      acs_step\r
+)\r
+{\r
+    PDM_ODM_T      pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+    prtl8192cd_priv     priv    = pDM_Odm->priv;\r
+    PACS                  pACS    = &pDM_Odm->DM_ACS;\r
+    u4Byte                value32 = 0;\r
+    u1Byte                i;\r
+\r
+    pACS->ACS_Step = acs_step;\r
+\r
+    if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES)\r
+    {\r
+        //4 Check if NHM result is ready        \r
+        for (i=0; i<20; i++) {\r
+            \r
+            ODM_delay_ms(1);\r
+            if ( ODM_GetBBReg(pDM_Odm,rFPGA0_PSDReport,BIT17) )\r
+                break;\r
+        }\r
+        \r
+        //4 Get NHM Statistics        \r
+        if ( pACS->ACS_Step==1 ) {\r
+            \r
+            value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT7_TO_CNT4_11N);\r
+            \r
+            pACS->NHM_Cnt[idx][9] = (value32 & bMaskByte1) >> 8;\r
+            pACS->NHM_Cnt[idx][8] = (value32 & bMaskByte0);\r
+\r
+            value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11N);    // ODM_REG_NHM_CNT3_TO_CNT0_11N\r
+\r
+            pACS->NHM_Cnt[idx][7] = (value32 & bMaskByte3) >> 24;\r
+            pACS->NHM_Cnt[idx][6] = (value32 & bMaskByte2) >> 16;\r
+            pACS->NHM_Cnt[idx][5] = (value32 & bMaskByte1) >> 8;\r
+\r
+        } else if (pACS->ACS_Step==2) {\r
+        \r
+            value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11N);   // ODM_REG_NHM_CNT3_TO_CNT0_11N\r
+\r
+            pACS->NHM_Cnt[idx][4] = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_CNT7_TO_CNT4_11N);            \r
+            pACS->NHM_Cnt[idx][3] = (value32 & bMaskByte3) >> 24;\r
+            pACS->NHM_Cnt[idx][2] = (value32 & bMaskByte2) >> 16;\r
+            pACS->NHM_Cnt[idx][1] = (value32 & bMaskByte1) >> 8;\r
+            pACS->NHM_Cnt[idx][0] = (value32 & bMaskByte0);\r
+        }\r
+    }\r
+    else if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)\r
+    {\r
+        //4 Check if NHM result is ready        \r
+        for (i=0; i<20; i++) {\r
+            \r
+               ODM_delay_ms(1);\r
+               if (ODM_GetBBReg(pDM_Odm, ODM_REG_NHM_DUR_READY_11AC, BIT16))\r
+                       break;\r
+        }\r
+    \r
+        if ( pACS->ACS_Step==1 ) {\r
+            \r
+            value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT7_TO_CNT4_11AC);\r
+            \r
+            pACS->NHM_Cnt[idx][9] = (value32 & bMaskByte1) >> 8;\r
+            pACS->NHM_Cnt[idx][8] = (value32 & bMaskByte0);\r
+\r
+            value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11AC);     // ODM_REG_NHM_CNT3_TO_CNT0_11AC\r
+\r
+            pACS->NHM_Cnt[idx][7] = (value32 & bMaskByte3) >> 24;\r
+            pACS->NHM_Cnt[idx][6] = (value32 & bMaskByte2) >> 16;\r
+            pACS->NHM_Cnt[idx][5] = (value32 & bMaskByte1) >> 8;\r
+\r
+        } else if (pACS->ACS_Step==2) {\r
+        \r
+            value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11AC);      // ODM_REG_NHM_CNT3_TO_CNT0_11AC\r
+\r
+            pACS->NHM_Cnt[idx][4] = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_CNT7_TO_CNT4_11AC);            \r
+            pACS->NHM_Cnt[idx][3] = (value32 & bMaskByte3) >> 24;\r
+            pACS->NHM_Cnt[idx][2] = (value32 & bMaskByte2) >> 16;\r
+            pACS->NHM_Cnt[idx][1] = (value32 & bMaskByte1) >> 8;\r
+            pACS->NHM_Cnt[idx][0] = (value32 & bMaskByte0);\r
+        }            \r
+    }\r
+\r
+}\r
+\r
+\r
+//#define ACS_DEBUG_INFO //acs debug default off\r
+/*\r
+int phydm_AutoChannelSelectAP( \r
+    IN   PVOID   pDM_VOID,\r
+    IN   u4Byte  ACS_Type,                      // 0: RXCount_Type, 1:NHM_Type\r
+    IN   u4Byte  available_chnl_num        // amount of all channels\r
+    )\r
+{\r
+    PDM_ODM_T               pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PACS                    pACS    = &pDM_Odm->DM_ACS;\r
+    prtl8192cd_priv                    priv    = pDM_Odm->priv;\r
+    \r
+    static u4Byte           score2G[MAX_2G_CHANNEL_NUM], score5G[MAX_5G_CHANNEL_NUM];\r
+    u4Byte                  score[MAX_BSS_NUM], use_nhm = 0;\r
+    u4Byte                  minScore=0xffffffff;\r
+    u4Byte                  tmpScore, tmpIdx=0;\r
+    u4Byte                  traffic_check = 0;\r
+    u4Byte                  fa_count_weighting = 1;\r
+    int                     i, j, idx=0, idx_2G_end=-1, idx_5G_begin=-1, minChan=0;\r
+       struct bss_desc *pBss=NULL;\r
+\r
+#ifdef _DEBUG_RTL8192CD_\r
+       char tmpbuf[400];\r
+       int len=0;\r
+#endif\r
+\r
+       memset(score2G, '\0', sizeof(score2G));\r
+       memset(score5G, '\0', sizeof(score5G));\r
+\r
+       for (i=0; i<priv->available_chnl_num; i++) {\r
+               if (priv->available_chnl[i] <= 14)\r
+                       idx_2G_end = i;\r
+               else\r
+                       break;\r
+       }\r
+\r
+       for (i=0; i<priv->available_chnl_num; i++) {\r
+               if (priv->available_chnl[i] > 14) {\r
+                       idx_5G_begin = i;\r
+                       break;\r
+               }\r
+       }\r
+\r
+// DELETE\r
+#ifndef CONFIG_RTL_NEW_AUTOCH\r
+       for (i=0; i<priv->site_survey->count; i++) {\r
+               pBss = &priv->site_survey->bss[i];\r
+               for (idx=0; idx<priv->available_chnl_num; idx++) {\r
+                       if (pBss->channel == priv->available_chnl[idx]) {\r
+                               if (pBss->channel <= 14)\r
+                                       setChannelScore(idx, score2G, 0, MAX_2G_CHANNEL_NUM-1);\r
+                               else\r
+                                       score5G[idx - idx_5G_begin] += 5;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+#endif\r
+\r
+       if (idx_2G_end >= 0)\r
+               for (i=0; i<=idx_2G_end; i++)\r
+                       score[i] = score2G[i];\r
+       if (idx_5G_begin >= 0)\r
+               for (i=idx_5G_begin; i<priv->available_chnl_num; i++)\r
+                       score[i] = score5G[i - idx_5G_begin];\r
+               \r
+#ifdef CONFIG_RTL_NEW_AUTOCH\r
+       {\r
+               u4Byte y, ch_begin=0, ch_end= priv->available_chnl_num;\r
+\r
+               u4Byte do_ap_check = 1, ap_ratio = 0;\r
+               \r
+               if (idx_2G_end >= 0) \r
+                       ch_end = idx_2G_end+1;\r
+               if (idx_5G_begin >= 0)  \r
+                       ch_begin = idx_5G_begin;\r
+\r
+#ifdef ACS_DEBUG_INFO//for debug\r
+               printk("\n");\r
+               for (y=ch_begin; y<ch_end; y++)\r
+                       printk("1. init: chnl[%d] 20M_rx[%d] 40M_rx[%d] fa_cnt[%d] score[%d]\n",\r
+                               priv->available_chnl[y], \r
+                               priv->chnl_ss_mac_rx_count[y], \r
+                               priv->chnl_ss_mac_rx_count_40M[y],\r
+                               priv->chnl_ss_fa_count[y],\r
+                               score[y]);\r
+               printk("\n");\r
+#endif\r
+\r
+#if defined(CONFIG_RTL_88E_SUPPORT) || defined(CONFIG_WLAN_HAL_8192EE)\r
+        if( pDM_Odm->SupportICType&(ODM_RTL8188E|ODM_RTL8192E)&& priv->pmib->dot11RFEntry.acs_type )\r
+               {\r
+                       u4Byte tmp_score[MAX_BSS_NUM];\r
+                       memcpy(tmp_score, score, sizeof(score));\r
+                       if (find_clean_channel(priv, ch_begin, ch_end, tmp_score)) {\r
+                               //memcpy(score, tmp_score, sizeof(score));\r
+#ifdef _DEBUG_RTL8192CD_\r
+                               printk("!! Found clean channel, select minimum FA channel\n");\r
+#endif\r
+                               goto USE_CLN_CH;\r
+                       }\r
+#ifdef _DEBUG_RTL8192CD_\r
+                       printk("!! Not found clean channel, use NHM algorithm\n");\r
+#endif\r
+                       use_nhm = 1;\r
+USE_CLN_CH:\r
+                       for (y=ch_begin; y<ch_end; y++) {\r
+                               for (i=0; i<=9; i++) {\r
+                                       u4Byte val32 = priv->nhm_cnt[y][i];\r
+                                       for (j=0; j<i; j++)\r
+                                               val32 *= 3;\r
+                                       score[y] += val32;\r
+                               }\r
+\r
+#ifdef _DEBUG_RTL8192CD_                               \r
+                               printk("nhm_cnt_%d: H<-[ %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d]->L, score: %d\n", \r
+                                       y+1, priv->nhm_cnt[y][9], priv->nhm_cnt[y][8], priv->nhm_cnt[y][7], \r
+                                       priv->nhm_cnt[y][6], priv->nhm_cnt[y][5], priv->nhm_cnt[y][4],\r
+                                       priv->nhm_cnt[y][3], priv->nhm_cnt[y][2], priv->nhm_cnt[y][1],\r
+                                       priv->nhm_cnt[y][0], score[y]);\r
+#endif\r
+                       }\r
+\r
+                       if (!use_nhm)\r
+                               memcpy(score, tmp_score, sizeof(score));\r
+                       \r
+                       goto choose_ch;\r
+               }\r
+#endif\r
+\r
+            // For each channel, weighting behind channels with MAC RX counter\r
+            //For each channel, weighting the channel with FA counter\r
+\r
+               for (y=ch_begin; y<ch_end; y++) {\r
+                       score[y] += 8 * priv->chnl_ss_mac_rx_count[y];\r
+                       if (priv->chnl_ss_mac_rx_count[y] > 30)\r
+                               do_ap_check = 0;\r
+                       if( priv->chnl_ss_mac_rx_count[y] > MAC_RX_COUNT_THRESHOLD )\r
+                               traffic_check = 1;\r
+                       \r
+#ifdef RTK_5G_SUPPORT\r
+                       if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G)\r
+#endif\r
+                       {\r
+                               if ((int)(y-4) >= (int)ch_begin)\r
+                                       score[y-4] += 2 * priv->chnl_ss_mac_rx_count[y];                                \r
+                               if ((int)(y-3) >= (int)ch_begin)\r
+                                       score[y-3] += 8 * priv->chnl_ss_mac_rx_count[y];\r
+                               if ((int)(y-2) >= (int)ch_begin)\r
+                                       score[y-2] += 8 * priv->chnl_ss_mac_rx_count[y];\r
+                               if ((int)(y-1) >= (int)ch_begin)\r
+                                       score[y-1] += 10 * priv->chnl_ss_mac_rx_count[y];\r
+                               if ((int)(y+1) < (int)ch_end)\r
+                                       score[y+1] += 10 * priv->chnl_ss_mac_rx_count[y];\r
+                               if ((int)(y+2) < (int)ch_end)\r
+                                       score[y+2] += 8 * priv->chnl_ss_mac_rx_count[y];\r
+                               if ((int)(y+3) < (int)ch_end)\r
+                                       score[y+3] += 8 * priv->chnl_ss_mac_rx_count[y];\r
+                               if ((int)(y+4) < (int)ch_end)\r
+                                       score[y+4] += 2 * priv->chnl_ss_mac_rx_count[y];\r
+                       }\r
+\r
+                       //this is for CH_LOAD caculation\r
+                       if( priv->chnl_ss_cca_count[y] > priv->chnl_ss_fa_count[y])\r
+                               priv->chnl_ss_cca_count[y]-= priv->chnl_ss_fa_count[y];\r
+                       else\r
+                               priv->chnl_ss_cca_count[y] = 0;\r
+               }\r
+\r
+#ifdef ACS_DEBUG_INFO//for debug\r
+               printk("\n");\r
+               for (y=ch_begin; y<ch_end; y++)\r
+                       printk("2. after 20M check: chnl[%d] score[%d]\n",priv->available_chnl[y], score[y]);\r
+               printk("\n");\r
+#endif \r
+\r
+               for (y=ch_begin; y<ch_end; y++) {\r
+                       if (priv->chnl_ss_mac_rx_count_40M[y]) {\r
+                               score[y] += 5 * priv->chnl_ss_mac_rx_count_40M[y];\r
+                               if (priv->chnl_ss_mac_rx_count_40M[y] > 30)\r
+                                       do_ap_check = 0;\r
+                               if( priv->chnl_ss_mac_rx_count_40M[y] > MAC_RX_COUNT_THRESHOLD )\r
+                                       traffic_check = 1;\r
+                               \r
+#ifdef RTK_5G_SUPPORT\r
+                               if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G)\r
+#endif\r
+                               {\r
+                                       if ((int)(y-6) >= (int)ch_begin)\r
+                                               score[y-6] += 1 * priv->chnl_ss_mac_rx_count_40M[y];\r
+                                       if ((int)(y-5) >= (int)ch_begin)\r
+                                               score[y-5] += 4 * priv->chnl_ss_mac_rx_count_40M[y];\r
+                                       if ((int)(y-4) >= (int)ch_begin)\r
+                                               score[y-4] += 4 * priv->chnl_ss_mac_rx_count_40M[y];\r
+                                       if ((int)(y-3) >= (int)ch_begin)\r
+                                               score[y-3] += 5 * priv->chnl_ss_mac_rx_count_40M[y];\r
+                                       if ((int)(y-2) >= (int)ch_begin)\r
+                                               score[y-2] += (5 * priv->chnl_ss_mac_rx_count_40M[y])/2;\r
+                                       if ((int)(y-1) >= (int)ch_begin)\r
+                                               score[y-1] += 5 * priv->chnl_ss_mac_rx_count_40M[y];\r
+                                       if ((int)(y+1) < (int)ch_end)\r
+                                               score[y+1] += 5 * priv->chnl_ss_mac_rx_count_40M[y];\r
+                                       if ((int)(y+2) < (int)ch_end)\r
+                                               score[y+2] += (5 * priv->chnl_ss_mac_rx_count_40M[y])/2;\r
+                                       if ((int)(y+3) < (int)ch_end)\r
+                                               score[y+3] += 5 * priv->chnl_ss_mac_rx_count_40M[y];\r
+                                       if ((int)(y+4) < (int)ch_end)\r
+                                               score[y+4] += 4 * priv->chnl_ss_mac_rx_count_40M[y];\r
+                                       if ((int)(y+5) < (int)ch_end)\r
+                                               score[y+5] += 4 * priv->chnl_ss_mac_rx_count_40M[y];\r
+                                       if ((int)(y+6) < (int)ch_end)\r
+                                               score[y+6] += 1 * priv->chnl_ss_mac_rx_count_40M[y];\r
+                               }\r
+                       }\r
+               }\r
+\r
+#ifdef ACS_DEBUG_INFO//for debug\r
+               printk("\n");\r
+               for (y=ch_begin; y<ch_end; y++)\r
+                       printk("3. after 40M check: chnl[%d] score[%d]\n",priv->available_chnl[y], score[y]);\r
+               printk("\n");\r
+               printk("4. do_ap_check=%d traffic_check=%d\n", do_ap_check, traffic_check);\r
+               printk("\n");\r
+#endif\r
+\r
+               if( traffic_check == 0)\r
+                       fa_count_weighting = 5;\r
+               else\r
+                       fa_count_weighting = 1;\r
+\r
+               for (y=ch_begin; y<ch_end; y++) {\r
+                       score[y] += fa_count_weighting * priv->chnl_ss_fa_count[y];\r
+               }\r
+\r
+#ifdef ACS_DEBUG_INFO//for debug\r
+               printk("\n");\r
+               for (y=ch_begin; y<ch_end; y++)\r
+                       printk("5. after fa check: chnl[%d] score[%d]\n",priv->available_chnl[y], score[y]);\r
+               printk("\n");\r
+#endif                 \r
+\r
+               if (do_ap_check) {\r
+                       for (i=0; i<priv->site_survey->count; i++) {                            \r
+                               pBss = &priv->site_survey->bss[i];\r
+                               for (y=ch_begin; y<ch_end; y++) {\r
+                                       if (pBss->channel == priv->available_chnl[y]) {\r
+                                               if (pBss->channel <= 14) {\r
+#ifdef ACS_DEBUG_INFO//for debug\r
+                                               printk("\n");\r
+                                               printk("chnl[%d] has ap rssi=%d bw[0x%02x]\n",\r
+                                                       pBss->channel, pBss->rssi, pBss->t_stamp[1]);\r
+                                               printk("\n");\r
+#endif\r
+                                                       if (pBss->rssi > 60)\r
+                                                               ap_ratio = 4;\r
+                                                       else if (pBss->rssi > 35)\r
+                                                               ap_ratio = 2;\r
+                                                       else\r
+                                                               ap_ratio = 1;\r
+                                                       \r
+                                                       if ((pBss->t_stamp[1] & 0x6) == 0) {\r
+                                                               score[y] += 50 * ap_ratio;\r
+                                                               if ((int)(y-4) >= (int)ch_begin)\r
+                                                                       score[y-4] += 10 * ap_ratio;\r
+                                                               if ((int)(y-3) >= (int)ch_begin)\r
+                                                                       score[y-3] += 20 * ap_ratio;\r
+                                                               if ((int)(y-2) >= (int)ch_begin)\r
+                                                                       score[y-2] += 30 * ap_ratio;\r
+                                                               if ((int)(y-1) >= (int)ch_begin)\r
+                                                                       score[y-1] += 40 * ap_ratio;\r
+                                                               if ((int)(y+1) < (int)ch_end)\r
+                                                                       score[y+1] += 40 * ap_ratio;\r
+                                                               if ((int)(y+2) < (int)ch_end)\r
+                                                                       score[y+2] += 30 * ap_ratio;\r
+                                                               if ((int)(y+3) < (int)ch_end)\r
+                                                                       score[y+3] += 20 * ap_ratio;\r
+                                                               if ((int)(y+4) < (int)ch_end)\r
+                                                                       score[y+4] += 10 * ap_ratio;\r
+                                                       }       \r
+                                                       else if ((pBss->t_stamp[1] & 0x4) == 0) {\r
+                                                               score[y] += 50 * ap_ratio;\r
+                                                               if ((int)(y-3) >= (int)ch_begin)\r
+                                                                       score[y-3] += 20 * ap_ratio;\r
+                                                               if ((int)(y-2) >= (int)ch_begin)\r
+                                                                       score[y-2] += 30 * ap_ratio;\r
+                                                               if ((int)(y-1) >= (int)ch_begin)\r
+                                                                       score[y-1] += 40 * ap_ratio;\r
+                                                               if ((int)(y+1) < (int)ch_end)\r
+                                                                       score[y+1] += 50 * ap_ratio;\r
+                                                               if ((int)(y+2) < (int)ch_end)\r
+                                                                       score[y+2] += 50 * ap_ratio;\r
+                                                               if ((int)(y+3) < (int)ch_end)\r
+                                                                       score[y+3] += 50 * ap_ratio;\r
+                                                               if ((int)(y+4) < (int)ch_end)\r
+                                                                       score[y+4] += 50 * ap_ratio;\r
+                                                               if ((int)(y+5) < (int)ch_end)\r
+                                                                       score[y+5] += 40 * ap_ratio;\r
+                                                               if ((int)(y+6) < (int)ch_end)\r
+                                                                       score[y+6] += 30 * ap_ratio;\r
+                                                               if ((int)(y+7) < (int)ch_end)\r
+                                                                       score[y+7] += 20 * ap_ratio;    \r
+                                                       }       \r
+                                                       else {\r
+                                                               score[y] += 50 * ap_ratio;\r
+                                                               if ((int)(y-7) >= (int)ch_begin)\r
+                                                                       score[y-7] += 20 * ap_ratio;\r
+                                                               if ((int)(y-6) >= (int)ch_begin)\r
+                                                                       score[y-6] += 30 * ap_ratio;\r
+                                                               if ((int)(y-5) >= (int)ch_begin)\r
+                                                                       score[y-5] += 40 * ap_ratio;\r
+                                                               if ((int)(y-4) >= (int)ch_begin)\r
+                                                                       score[y-4] += 50 * ap_ratio;\r
+                                                               if ((int)(y-3) >= (int)ch_begin)\r
+                                                                       score[y-3] += 50 * ap_ratio;\r
+                                                               if ((int)(y-2) >= (int)ch_begin)\r
+                                                                       score[y-2] += 50 * ap_ratio;\r
+                                                               if ((int)(y-1) >= (int)ch_begin)\r
+                                                                       score[y-1] += 50 * ap_ratio;\r
+                                                               if ((int)(y+1) < (int)ch_end)\r
+                                                                       score[y+1] += 40 * ap_ratio;\r
+                                                               if ((int)(y+2) < (int)ch_end)\r
+                                                                       score[y+2] += 30 * ap_ratio;\r
+                                                               if ((int)(y+3) < (int)ch_end)\r
+                                                                       score[y+3] += 20 * ap_ratio;\r
+                                                       }       \r
+                                               }       \r
+                                               else {\r
+                                                       if ((pBss->t_stamp[1] & 0x6) == 0) {\r
+                                                               score[y] += 500;\r
+                                                       }\r
+                                                       else if ((pBss->t_stamp[1] & 0x4) == 0) {\r
+                                                               score[y] += 500;\r
+                                                               if ((int)(y+1) < (int)ch_end)\r
+                                                                       score[y+1] += 500;\r
+                                                       }\r
+                                                       else {  \r
+                                                               score[y] += 500;\r
+                                                               if ((int)(y-1) >= (int)ch_begin)\r
+                                                                       score[y-1] += 500;\r
+                                                       }\r
+                                               }\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+#ifdef ACS_DEBUG_INFO//for debug\r
+               printk("\n");\r
+               for (y=ch_begin; y<ch_end; y++)\r
+                       printk("6. after ap check: chnl[%d]:%d\n", priv->available_chnl[y],score[y]);\r
+               printk("\n");\r
+#endif         \r
+\r
+#ifdef         SS_CH_LOAD_PROC\r
+\r
+               // caculate noise level -- suggested by wilson\r
+               for (y=ch_begin; y<ch_end; y++)  {\r
+                       int fa_lv=0, cca_lv=0;\r
+                       if (priv->chnl_ss_fa_count[y]>1000) {\r
+                               fa_lv = 100;\r
+                       } else if (priv->chnl_ss_fa_count[y]>500) {\r
+                               fa_lv = 34 * (priv->chnl_ss_fa_count[y]-500) / 500 + 66;\r
+                       } else if (priv->chnl_ss_fa_count[y]>200) {\r
+                               fa_lv = 33 * (priv->chnl_ss_fa_count[y] - 200) / 300 + 33;\r
+                       } else if (priv->chnl_ss_fa_count[y]>100) {\r
+                               fa_lv = 18 * (priv->chnl_ss_fa_count[y] - 100) / 100 + 15;\r
+                       } else {\r
+                               fa_lv = 15 * priv->chnl_ss_fa_count[y] / 100;\r
+                       } \r
+                       if (priv->chnl_ss_cca_count[y]>400) {\r
+                               cca_lv = 100;\r
+                       } else if (priv->chnl_ss_cca_count[y]>200) {\r
+                               cca_lv = 34 * (priv->chnl_ss_cca_count[y] - 200) / 200 + 66;\r
+                       } else if (priv->chnl_ss_cca_count[y]>80) {\r
+                               cca_lv = 33 * (priv->chnl_ss_cca_count[y] - 80) / 120 + 33;\r
+                       } else if (priv->chnl_ss_cca_count[y]>40) {\r
+                               cca_lv = 18 * (priv->chnl_ss_cca_count[y] - 40) / 40 + 15;\r
+                       } else {\r
+                               cca_lv = 15 * priv->chnl_ss_cca_count[y] / 40;\r
+                       }\r
+\r
+                       priv->chnl_ss_load[y] = (((fa_lv > cca_lv)? fa_lv : cca_lv)*75+((score[y]>100)?100:score[y])*25)/100;\r
+\r
+                       DEBUG_INFO("ch:%d f=%d (%d), c=%d (%d), fl=%d, cl=%d, sc=%d, cu=%d\n", \r
+                                       priv->available_chnl[y],\r
+                                       priv->chnl_ss_fa_count[y], fa_thd,\r
+                                       priv->chnl_ss_cca_count[y], cca_thd,\r
+                                       fa_lv, \r
+                                       cca_lv,\r
+                                       score[y],                                       \r
+                                       priv->chnl_ss_load[y]);\r
+                       \r
+               }               \r
+#endif         \r
+       }\r
+#endif\r
+\r
+choose_ch:\r
+\r
+#ifdef DFS\r
+       // heavy weighted DFS channel\r
+       if (idx_5G_begin >= 0){\r
+               for (i=idx_5G_begin; i<priv->available_chnl_num; i++) {\r
+                       if (!priv->pmib->dot11DFSEntry.disable_DFS && is_DFS_channel(priv->available_chnl[i]) \r
+                       && (score[i]!= 0xffffffff)){\r
+                                       score[i] += 1600; \r
+               }\r
+       }\r
+       }\r
+#endif\r
+\r
+\r
+//prevent Auto Channel selecting wrong channel in 40M mode-----------------\r
+       if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N)\r
+               && priv->pshare->is_40m_bw) {\r
+#if 0\r
+               if (GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset == 1) {\r
+                       //Upper Primary Channel, cannot select the two lowest channels\r
+                       if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) {\r
+                               score[0] = 0xffffffff;\r
+                               score[1] = 0xffffffff;\r
+                               score[2] = 0xffffffff;\r
+                               score[3] = 0xffffffff;\r
+                               score[4] = 0xffffffff;\r
+\r
+                               score[13] = 0xffffffff;\r
+                               score[12] = 0xffffffff;\r
+                               score[11] = 0xffffffff;\r
+                       }\r
+\r
+//                     if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) {\r
+//                             score[idx_5G_begin] = 0xffffffff;\r
+//                             score[idx_5G_begin + 1] = 0xffffffff;\r
+//                     }\r
+               }\r
+               else if (GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset == 2) {\r
+                       //Lower Primary Channel, cannot select the two highest channels\r
+                       if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) {\r
+                               score[0] = 0xffffffff;\r
+                               score[1] = 0xffffffff;\r
+                               score[2] = 0xffffffff;\r
+\r
+                               score[13] = 0xffffffff;\r
+                               score[12] = 0xffffffff;\r
+                               score[11] = 0xffffffff;\r
+                               score[10] = 0xffffffff;\r
+                               score[9] = 0xffffffff;\r
+                       }\r
+\r
+//                     if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) {\r
+//                             score[priv->available_chnl_num - 2] = 0xffffffff;\r
+//                             score[priv->available_chnl_num - 1] = 0xffffffff;\r
+//                     }\r
+               }\r
+#endif\r
+               for (i=0; i<=idx_2G_end; ++i)\r
+                       if (priv->available_chnl[i] == 14)\r
+                               score[i] = 0xffffffff;          // mask chan14\r
+\r
+#ifdef RTK_5G_SUPPORT\r
+               if (idx_5G_begin >= 0) {\r
+                       for (i=idx_5G_begin; i<priv->available_chnl_num; i++) {\r
+                               int ch = priv->available_chnl[i];\r
+                               if(priv->available_chnl[i] > 144) \r
+                                       --ch;\r
+                               if((ch%4) || ch==140 || ch == 164 )     //mask ch 140, ch 165, ch 184...\r
+                                       score[i] = 0xffffffff;\r
+                       }\r
+               }\r
+#endif\r
+\r
+               \r
+       }\r
+\r
+       if (priv->pmib->dot11RFEntry.disable_ch1213) {\r
+               for (i=0; i<=idx_2G_end; ++i) {\r
+                       int ch = priv->available_chnl[i];\r
+                       if ((ch == 12) || (ch == 13))\r
+                               score[i] = 0xffffffff;\r
+               }\r
+       }\r
+\r
+       if (((priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_GLOBAL) ||\r
+                       (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_WORLD_WIDE)) &&\r
+                (idx_2G_end >= 11) && (idx_2G_end < 14)) {\r
+               score[13] = 0xffffffff; // mask chan14\r
+               score[12] = 0xffffffff; // mask chan13\r
+               score[11] = 0xffffffff; // mask chan12\r
+       }\r
+       \r
+//------------------------------------------------------------------\r
+\r
+#ifdef _DEBUG_RTL8192CD_\r
+       for (i=0; i<priv->available_chnl_num; i++) {\r
+               len += sprintf(tmpbuf+len, "ch%d:%u ", priv->available_chnl[i], score[i]);              \r
+       }\r
+       strcat(tmpbuf, "\n");\r
+       panic_printk("%s", tmpbuf);\r
+\r
+#endif\r
+\r
+       if ( (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G)\r
+               && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80)) \r
+       {\r
+               for (i=0; i<priv->available_chnl_num; i++) {\r
+                       if (is80MChannel(priv->available_chnl, priv->available_chnl_num, priv->available_chnl[i])) {\r
+                               tmpScore = 0;\r
+                               for (j=0; j<4; j++) {\r
+                                       if ((tmpScore != 0xffffffff) && (score[i+j] != 0xffffffff))\r
+                                               tmpScore += score[i+j];\r
+                                       else\r
+                                               tmpScore = 0xffffffff;\r
+                               }\r
+                               tmpScore = tmpScore / 4;\r
+                               if (minScore > tmpScore) {\r
+                                       minScore = tmpScore;\r
+\r
+                                       tmpScore = 0xffffffff;\r
+                                       for (j=0; j<4; j++) {\r
+                                               if (score[i+j] < tmpScore) {\r
+                                                       tmpScore = score[i+j];\r
+                                                       tmpIdx = i+j;\r
+                                               }\r
+                                       }\r
+\r
+                                       idx = tmpIdx;\r
+                               }\r
+                               i += 3;\r
+                       }\r
+               }\r
+               if (minScore == 0xffffffff) {\r
+                       // there is no 80M channels\r
+                       priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20;\r
+                       for (i=0; i<priv->available_chnl_num; i++) {\r
+                               if (score[i] < minScore) {\r
+                                       minScore = score[i];\r
+                                       idx = i;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       else if( (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G)\r
+                       && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40))\r
+       {\r
+               for (i=0; i<priv->available_chnl_num; i++) {\r
+                       if(is40MChannel(priv->available_chnl,priv->available_chnl_num,priv->available_chnl[i])) {\r
+                               tmpScore = 0;\r
+                               for(j=0;j<2;j++) {\r
+                                       if ((tmpScore != 0xffffffff) && (score[i+j] != 0xffffffff))\r
+                                               tmpScore += score[i+j];\r
+                                       else\r
+                                               tmpScore = 0xffffffff;\r
+                               }\r
+                               tmpScore = tmpScore / 2;\r
+                               if(minScore > tmpScore) {\r
+                                       minScore = tmpScore;\r
+\r
+                                       tmpScore = 0xffffffff;\r
+                                       for (j=0; j<2; j++) {\r
+                                               if (score[i+j] < tmpScore) {\r
+                                                       tmpScore = score[i+j];\r
+                                                       tmpIdx = i+j;\r
+                                               }\r
+                                       }\r
+\r
+                                       idx = tmpIdx;\r
+                               }\r
+                               i += 1;\r
+                       }\r
+               }\r
+               if (minScore == 0xffffffff) {\r
+                       // there is no 40M channels\r
+                       priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20;\r
+                       for (i=0; i<priv->available_chnl_num; i++) {\r
+                               if (score[i] < minScore) {\r
+                                       minScore = score[i];\r
+                                       idx = i;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       else if( (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G)\r
+                       && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40)\r
+                       && (priv->available_chnl_num >= 8) )\r
+       {\r
+               u4Byte groupScore[14];\r
+\r
+               memset(groupScore, 0xff , sizeof(groupScore));\r
+               for (i=0; i<priv->available_chnl_num-4; i++) {\r
+                       if (score[i] != 0xffffffff && score[i+4] != 0xffffffff) {\r
+                               groupScore[i] = score[i] + score[i+4];\r
+                               DEBUG_INFO("groupScore, ch %d,%d: %d\n", i+1, i+5, groupScore[i]);\r
+                               if (groupScore[i] < minScore) {\r
+#ifdef AUTOCH_SS_SPEEDUP\r
+                                       if(priv->pmib->miscEntry.autoch_1611_enable)\r
+                                       {\r
+                                               if(priv->available_chnl[i]==1 || priv->available_chnl[i]==6 || priv->available_chnl[i]==11)\r
+                                               {\r
+                                                       minScore = groupScore[i];\r
+                                                       idx = i;\r
+                                               }\r
+                                       }\r
+                                       else\r
+#endif\r
+                                       {                                       \r
+                                               minScore = groupScore[i];\r
+                                               idx = i;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               if (score[idx] < score[idx+4]) {\r
+                       GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;\r
+                       priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_ABOVE;                        \r
+               } else {\r
+                       idx = idx + 4;\r
+                       GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;\r
+                       priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_BELOW;                        \r
+               }\r
+       }\r
+       else \r
+       {\r
+               for (i=0; i<priv->available_chnl_num; i++) {\r
+                       if (score[i] < minScore) {\r
+#ifdef AUTOCH_SS_SPEEDUP\r
+                               if(priv->pmib->miscEntry.autoch_1611_enable)\r
+                               {\r
+                                       if(priv->available_chnl[i]==1 || priv->available_chnl[i]==6 || priv->available_chnl[i]==11)\r
+                                       {\r
+                                               minScore = score[i];\r
+                                               idx = i;\r
+                                       }\r
+                               }\r
+                               else\r
+#endif\r
+                               {                               \r
+                                       minScore = score[i];\r
+                                       idx = i;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       if (IS_A_CUT_8881A(priv) &&\r
+               (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80)) {\r
+               if ((priv->available_chnl[idx] == 36) ||\r
+                       (priv->available_chnl[idx] == 52) ||\r
+                       (priv->available_chnl[idx] == 100) ||\r
+                       (priv->available_chnl[idx] == 116) ||\r
+                       (priv->available_chnl[idx] == 132) ||\r
+                       (priv->available_chnl[idx] == 149) ||\r
+                       (priv->available_chnl[idx] == 165))\r
+                       idx++;\r
+               else if ((priv->available_chnl[idx] == 48) ||\r
+                       (priv->available_chnl[idx] == 64) ||\r
+                       (priv->available_chnl[idx] == 112) ||\r
+                       (priv->available_chnl[idx] == 128) ||\r
+                       (priv->available_chnl[idx] == 144) ||\r
+                       (priv->available_chnl[idx] == 161) ||\r
+                       (priv->available_chnl[idx] == 177))\r
+                       idx--;\r
+       }\r
+\r
+       minChan = priv->available_chnl[idx];\r
+\r
+       // skip channel 14 if don't support ofdm\r
+       if ((priv->pmib->dot11RFEntry.disable_ch14_ofdm) &&\r
+                       (minChan == 14)) {\r
+               score[idx] = 0xffffffff;\r
+               \r
+               minScore = 0xffffffff;\r
+               for (i=0; i<priv->available_chnl_num; i++) {\r
+                       if (score[i] < minScore) {\r
+                               minScore = score[i];\r
+                               idx = i;\r
+                       }\r
+               }\r
+               minChan = priv->available_chnl[idx];\r
+       }\r
+\r
+#if 0\r
+       //Check if selected channel available for 80M/40M BW or NOT ?\r
+       if(priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G)\r
+       {\r
+               if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80)\r
+               {\r
+                       if(!is80MChannel(priv->available_chnl,priv->available_chnl_num,minChan))\r
+                       {\r
+                               //printk("BW=80M, selected channel = %d is unavaliable! reduce to 40M\n", minChan);\r
+                               //priv->pmib->dot11nConfigEntry.dot11nUse40M = HT_CHANNEL_WIDTH_20_40;\r
+                               priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20_40;\r
+                       }\r
+               }\r
+                       \r
+               if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40)\r
+               {\r
+                       if(!is40MChannel(priv->available_chnl,priv->available_chnl_num,minChan))\r
+                       {\r
+                               //printk("BW=40M, selected channel = %d is unavaliable! reduce to 20M\n", minChan);\r
+                               //priv->pmib->dot11nConfigEntry.dot11nUse40M = HT_CHANNEL_WIDTH_20;\r
+                               priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20;\r
+                       }\r
+               }\r
+       }\r
+#endif\r
+\r
+#ifdef CONFIG_RTL_NEW_AUTOCH\r
+       RTL_W32(RXERR_RPT, RXERR_RPT_RST);\r
+#endif\r
+\r
+// auto adjust contro-sideband\r
+       if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N)\r
+                       && (priv->pshare->is_40m_bw ==1 || priv->pshare->is_40m_bw ==2)) {\r
+\r
+#ifdef RTK_5G_SUPPORT\r
+               if (priv->pmib->dot11RFEntry.phyBandSelect & PHY_BAND_5G) {\r
+                       if( (minChan>144) ? ((minChan-1)%8) : (minChan%8)) {\r
+                               GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;\r
+                               priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_ABOVE;\r
+                       } else {\r
+                               GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;\r
+                               priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_BELOW;\r
+                       }\r
+\r
+               } else\r
+#endif         \r
+               {\r
+#if 0\r
+#ifdef CONFIG_RTL_NEW_AUTOCH\r
+                       unsigned int ch_max;\r
+\r
+                       if (priv->available_chnl[idx_2G_end] >= 13)\r
+                               ch_max = 13;\r
+                       else\r
+                               ch_max = priv->available_chnl[idx_2G_end];\r
+\r
+                       if ((minChan >= 5) && (minChan <= (ch_max-5))) {\r
+                               if (score[minChan+4] > score[minChan-4]) { // what if some channels were cancelled?\r
+                                       GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;\r
+                                       priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_BELOW;\r
+                               } else {\r
+                                       GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;\r
+                                       priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_ABOVE;\r
+                               }\r
+                       } else\r
+#endif\r
+                       {\r
+                               if (minChan < 5) {\r
+                                       GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;\r
+                                       priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_ABOVE;\r
+                               }\r
+                               else if (minChan > 7) {\r
+                                       GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;\r
+                                       priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_BELOW;\r
+                               }\r
+                       }\r
+#endif\r
+               }\r
+       }\r
+//-----------------------\r
+\r
+#if defined(__ECOS) && defined(CONFIG_SDIO_HCI)\r
+       panic_printk("Auto channel choose ch:%d\n", minChan);\r
+#else\r
+#ifdef _DEBUG_RTL8192CD_\r
+       panic_printk("Auto channel choose ch:%d\n", minChan);\r
+#endif\r
+#endif\r
+#ifdef ACS_DEBUG_INFO//for debug\r
+       printk("7. minChan:%d 2nd_offset:%d\n", minChan, priv->pshare->offset_2nd_chan);\r
+#endif\r
+\r
+       return minChan;\r
+}\r
+*/\r
+\r
+#endif\r
+\r
+\r
+\r