net: wireless: rockchip_wlan: add rtl8723ds support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723ds / hal / phydm / phydm_acs.c
1 /******************************************************************************\r
2  *\r
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.\r
4  *                                        \r
5  * This program is free software; you can redistribute it and/or modify it\r
6  * under the terms of version 2 of the GNU General Public License as\r
7  * published by the Free Software Foundation.\r
8  *\r
9  * This program is distributed in the hope that it will be useful, but WITHOUT\r
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
12  * more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License along with\r
15  * this program; if not, write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA\r
17  *\r
18  *\r
19  ******************************************************************************/\r
20 \r
21 //============================================================\r
22 // include files\r
23 //============================================================\r
24 #include "mp_precomp.h"\r
25 #include "phydm_precomp.h"\r
26 \r
27 \r
28 u1Byte\r
29 ODM_GetAutoChannelSelectResult(\r
30         IN              PVOID                   pDM_VOID,\r
31         IN              u1Byte                  Band\r
32 )\r
33 {\r
34         PDM_ODM_T                               pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
35         PACS                                    pACS = &pDM_Odm->DM_ACS;\r
36 \r
37 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
38         if(Band == ODM_BAND_2_4G)\r
39         {\r
40                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[ACS] ODM_GetAutoChannelSelectResult(): CleanChannel_2G(%d)\n", pACS->CleanChannel_2G));\r
41                 return (u1Byte)pACS->CleanChannel_2G;   \r
42         }\r
43         else\r
44         {\r
45                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[ACS] ODM_GetAutoChannelSelectResult(): CleanChannel_5G(%d)\n", pACS->CleanChannel_5G));\r
46                 return (u1Byte)pACS->CleanChannel_5G;   \r
47         }\r
48 #else\r
49         return (u1Byte)pACS->CleanChannel_2G;\r
50 #endif\r
51 \r
52 }\r
53 \r
54 VOID\r
55 odm_AutoChannelSelectSetting(\r
56         IN              PVOID                   pDM_VOID,\r
57         IN              BOOLEAN                 IsEnable\r
58 )\r
59 {\r
60 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
61         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
62         u2Byte                                          period = 0x2710;// 40ms in default\r
63         u2Byte                                          NHMType = 0x7;\r
64 \r
65         ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectSetting()=========> \n"));\r
66 \r
67         if(IsEnable)\r
68         {//20 ms\r
69                 period = 0x1388;\r
70                 NHMType = 0x1;\r
71         }\r
72 \r
73         if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)\r
74         {\r
75                 //PHY parameters initialize for ac series\r
76                 ODM_Write2Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC+2, period);     //0x990[31:16]=0x2710   Time duration for NHM unit: 4us, 0x2710=40ms\r
77                 //ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC, BIT8|BIT9|BIT10, NHMType);   //0x994[9:8]=3                  enable CCX\r
78         }\r
79         else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES)\r
80         {\r
81                 //PHY parameters initialize for n series\r
82                 ODM_Write2Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11N+2, period);      //0x894[31:16]=0x2710   Time duration for NHM unit: 4us, 0x2710=40ms\r
83                 //ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, NHMType);    //0x890[9:8]=3                  enable CCX              \r
84         }\r
85 #endif\r
86 }\r
87 \r
88 VOID\r
89 odm_AutoChannelSelectInit(\r
90         IN              PVOID                   pDM_VOID\r
91 )\r
92 {\r
93 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
94         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
95         PACS                                            pACS = &pDM_Odm->DM_ACS;\r
96         u1Byte                                          i;\r
97 \r
98         if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT))\r
99                 return;\r
100 \r
101         if(pACS->bForceACSResult)\r
102                 return;\r
103 \r
104         ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectInit()=========> \n"));\r
105 \r
106         pACS->CleanChannel_2G = 1;\r
107         pACS->CleanChannel_5G = 36;\r
108 \r
109         for (i = 0; i < ODM_MAX_CHANNEL_2G; ++i)\r
110         {\r
111                 pACS->Channel_Info_2G[0][i] = 0;\r
112                 pACS->Channel_Info_2G[1][i] = 0;\r
113         }\r
114 \r
115         if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)\r
116         {\r
117                 for (i = 0; i < ODM_MAX_CHANNEL_5G; ++i)\r
118                 {\r
119                         pACS->Channel_Info_5G[0][i] = 0;\r
120                         pACS->Channel_Info_5G[1][i] = 0;\r
121                 }\r
122         }\r
123 #endif\r
124 }\r
125 \r
126 VOID\r
127 odm_AutoChannelSelectReset(\r
128         IN              PVOID                   pDM_VOID\r
129 )\r
130 {\r
131 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
132         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
133         PACS                                            pACS = &pDM_Odm->DM_ACS;\r
134 \r
135         if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT))\r
136                 return;\r
137 \r
138         if(pACS->bForceACSResult)\r
139                 return;\r
140 \r
141         ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectReset()=========> \n"));\r
142 \r
143         odm_AutoChannelSelectSetting(pDM_Odm,TRUE);// for 20ms measurement\r
144         Phydm_NHMCounterStatisticsReset(pDM_Odm);\r
145 #endif\r
146 }\r
147 \r
148 VOID\r
149 odm_AutoChannelSelect(\r
150         IN              PVOID                   pDM_VOID,\r
151         IN              u1Byte                  Channel\r
152 )\r
153 {\r
154 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))\r
155         PDM_ODM_T                                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
156         PACS                                            pACS = &pDM_Odm->DM_ACS;\r
157         u1Byte                                          ChannelIDX = 0, SearchIDX = 0;\r
158         u2Byte                                          MaxScore=0;\r
159 \r
160         if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT))\r
161         {\r
162                 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Return: SupportAbility ODM_BB_NHM_CNT is disabled\n"));\r
163                 return;\r
164         }\r
165 \r
166         if(pACS->bForceACSResult)\r
167         {\r
168                 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Force 2G clean channel = %d, 5G clean channel = %d\n",\r
169                         pACS->CleanChannel_2G, pACS->CleanChannel_5G));\r
170                 return;\r
171         }\r
172 \r
173         ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Channel = %d=========> \n", Channel));\r
174 \r
175         Phydm_GetNHMCounterStatistics(pDM_Odm);\r
176         odm_AutoChannelSelectSetting(pDM_Odm,FALSE);\r
177 \r
178         if(Channel >=1 && Channel <=14)\r
179         {\r
180                 ChannelIDX = Channel - 1;\r
181                 pACS->Channel_Info_2G[1][ChannelIDX]++;\r
182                 \r
183                 if(pACS->Channel_Info_2G[1][ChannelIDX] >= 2)\r
184                         pACS->Channel_Info_2G[0][ChannelIDX] = (pACS->Channel_Info_2G[0][ChannelIDX] >> 1) + \r
185                         (pACS->Channel_Info_2G[0][ChannelIDX] >> 2) + (pDM_Odm->NHM_cnt_0>>2);\r
186                 else\r
187                         pACS->Channel_Info_2G[0][ChannelIDX] = pDM_Odm->NHM_cnt_0;\r
188         \r
189                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): NHM_cnt_0 = %d \n", pDM_Odm->NHM_cnt_0));\r
190                 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
191 \r
192                 for(SearchIDX = 0; SearchIDX < ODM_MAX_CHANNEL_2G; SearchIDX++)\r
193                 {\r
194                         if(pACS->Channel_Info_2G[1][SearchIDX] != 0)\r
195                         {\r
196                                 if(pACS->Channel_Info_2G[0][SearchIDX] >= MaxScore)\r
197                                 {\r
198                                         MaxScore = pACS->Channel_Info_2G[0][SearchIDX];\r
199                                         pACS->CleanChannel_2G = SearchIDX+1;\r
200                                 }\r
201                         }\r
202                 }\r
203                 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("(1)odm_AutoChannelSelect(): 2G: CleanChannel_2G = %d, MaxScore = %d \n", \r
204                         pACS->CleanChannel_2G, MaxScore));\r
205 \r
206         }\r
207         else if(Channel >= 36)\r
208         {\r
209                 // Need to do\r
210                 pACS->CleanChannel_5G = Channel;\r
211         }\r
212 #endif\r
213 }\r
214 \r
215 #if ( DM_ODM_SUPPORT_TYPE & ODM_AP )\r
216 \r
217 VOID\r
218 phydm_AutoChannelSelectSettingAP(\r
219     IN  PVOID   pDM_VOID,\r
220     IN  u4Byte  setting,             // 0: STORE_DEFAULT_NHM_SETTING; 1: RESTORE_DEFAULT_NHM_SETTING, 2: ACS_NHM_SETTING\r
221     IN  u4Byte  acs_step\r
222 )\r
223 {\r
224     PDM_ODM_T           pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
225     prtl8192cd_priv       priv           = pDM_Odm->priv;\r
226     PACS                    pACS         = &pDM_Odm->DM_ACS;\r
227 \r
228     ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectSettingAP()=========> \n"));\r
229 \r
230     //3 Store Default Setting\r
231     if(setting == STORE_DEFAULT_NHM_SETTING)\r
232     {\r
233         ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("STORE_DEFAULT_NHM_SETTING\n"));\r
234     \r
235         if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)     // store Reg0x990, Reg0x994, Reg0x998, Reg0x99C, Reg0x9a0\r
236         {\r
237             pACS->Reg0x990 = ODM_Read4Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC);                // Reg0x990\r
238             pACS->Reg0x994 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC);           // Reg0x994\r
239             pACS->Reg0x998 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC);       // Reg0x998\r
240             pACS->Reg0x99C = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC);       // Reg0x99c\r
241             pACS->Reg0x9A0 = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_TH8_11AC);                   // Reg0x9a0, u1Byte            \r
242         }\r
243         else if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES)\r
244         {\r
245             pACS->Reg0x890 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N);             // Reg0x890\r
246             pACS->Reg0x894 = ODM_Read4Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11N);                  // Reg0x894\r
247             pACS->Reg0x898 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N);         // Reg0x898\r
248             pACS->Reg0x89C = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N);         // Reg0x89c\r
249             pACS->Reg0xE28 = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_TH8_11N);                     // Reg0xe28, u1Byte    \r
250         }\r
251     }\r
252 \r
253     //3 Restore Default Setting\r
254     else if(setting == RESTORE_DEFAULT_NHM_SETTING)\r
255     {\r
256         ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("RESTORE_DEFAULT_NHM_SETTING\n"));\r
257         \r
258         if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)     // store Reg0x990, Reg0x994, Reg0x998, Reg0x99C, Reg0x9a0\r
259         {\r
260             ODM_Write4Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC,          pACS->Reg0x990);\r
261             ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC,     pACS->Reg0x994);\r
262             ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, pACS->Reg0x998);\r
263             ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, pACS->Reg0x99C);\r
264             ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11AC,             pACS->Reg0x9A0);   \r
265         }\r
266         else if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES)\r
267         {\r
268             ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N,     pACS->Reg0x890);\r
269             ODM_Write4Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC,          pACS->Reg0x894);\r
270             ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, pACS->Reg0x898);\r
271             ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, pACS->Reg0x89C);\r
272             ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11N,             pACS->Reg0xE28); \r
273         }        \r
274     }\r
275 \r
276     //3 ACS Setting\r
277     else if(setting == ACS_NHM_SETTING)\r
278     {        \r
279         ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("ACS_NHM_SETTING\n"));\r
280         u2Byte  period;\r
281         period = 0x61a8;\r
282         pACS->ACS_Step = acs_step;\r
283             \r
284         if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)\r
285         {   \r
286             //4 Set NHM period, 0x990[31:16]=0x61a8, Time duration for NHM unit: 4us, 0x61a8=100ms\r
287             ODM_Write2Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC+2, period);\r
288             //4 Set NHM ignore_cca=1, ignore_txon=1, ccx_en=0\r
289             ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC,BIT8|BIT9|BIT10, 3);\r
290             \r
291             if(pACS->ACS_Step == 0)\r
292             {\r
293                 //4 Set IGI\r
294                 ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E);\r
295                 if (get_rf_mimo_mode(priv) != MIMO_1T1R)\r
296                                         ODM_SetBBReg(pDM_Odm,0xe50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E);\r
297                     \r
298                 //4 Set ACS NHM threshold\r
299                 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0x82786e64);\r
300                 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffff8c);\r
301                 ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11AC, 0xff);\r
302                 ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC+2, 0xffff);\r
303                 \r
304             }\r
305             else if(pACS->ACS_Step == 1)\r
306             {\r
307                 //4 Set IGI\r
308                 ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A);\r
309                 if (get_rf_mimo_mode(priv) != MIMO_1T1R)\r
310                                         ODM_SetBBReg(pDM_Odm,0xe50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A);\r
311 \r
312                 //4 Set ACS NHM threshold\r
313                 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0x5a50463c);\r
314                 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffff64);\r
315                 \r
316             }\r
317 \r
318         }\r
319         else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES)\r
320         {\r
321             //4 Set NHM period, 0x894[31:16]=0x61a8, Time duration for NHM unit: 4us, 0x61a8=100ms\r
322             ODM_Write2Byte(pDM_Odm, ODM_REG_CCX_PERIOD_11AC+2, period);\r
323             //4 Set NHM ignore_cca=1, ignore_txon=1, ccx_en=0\r
324             ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N,BIT8|BIT9|BIT10, 3);\r
325             \r
326             if(pACS->ACS_Step == 0)\r
327             {\r
328                 //4 Set IGI\r
329                 ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E);\r
330                 if (get_rf_mimo_mode(priv) != MIMO_1T1R)\r
331                                         ODM_SetBBReg(pDM_Odm,0xc58,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E);\r
332             \r
333                 //4 Set ACS NHM threshold\r
334                 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0x82786e64);\r
335                 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffff8c);\r
336                 ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11N, 0xff);\r
337                 ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff);\r
338                 \r
339             }\r
340             else if(pACS->ACS_Step == 1)\r
341             {\r
342                 //4 Set IGI\r
343                 ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A);\r
344                 if (get_rf_mimo_mode(priv) != MIMO_1T1R)\r
345                                         ODM_SetBBReg(pDM_Odm,0xc58,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A);\r
346             \r
347                 //4 Set ACS NHM threshold\r
348                 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0x5a50463c);\r
349                 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffff64);\r
350 \r
351             }            \r
352         }\r
353     }   \r
354         \r
355 }\r
356 \r
357 VOID\r
358 phydm_GetNHMStatisticsAP(\r
359     IN  PVOID       pDM_VOID,\r
360     IN  u4Byte      idx,                // @ 2G, Real channel number = idx+1\r
361     IN  u4Byte      acs_step\r
362 )\r
363 {\r
364     PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
365     prtl8192cd_priv     priv    = pDM_Odm->priv;\r
366     PACS                  pACS    = &pDM_Odm->DM_ACS;\r
367     u4Byte                value32 = 0;\r
368     u1Byte                i;\r
369 \r
370     pACS->ACS_Step = acs_step;\r
371 \r
372     if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES)\r
373     {\r
374         //4 Check if NHM result is ready        \r
375         for (i=0; i<20; i++) {\r
376             \r
377             ODM_delay_ms(1);\r
378             if ( ODM_GetBBReg(pDM_Odm,rFPGA0_PSDReport,BIT17) )\r
379                 break;\r
380         }\r
381         \r
382         //4 Get NHM Statistics        \r
383         if ( pACS->ACS_Step==1 ) {\r
384             \r
385             value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT7_TO_CNT4_11N);\r
386             \r
387             pACS->NHM_Cnt[idx][9] = (value32 & bMaskByte1) >> 8;\r
388             pACS->NHM_Cnt[idx][8] = (value32 & bMaskByte0);\r
389 \r
390             value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11N);    // ODM_REG_NHM_CNT3_TO_CNT0_11N\r
391 \r
392             pACS->NHM_Cnt[idx][7] = (value32 & bMaskByte3) >> 24;\r
393             pACS->NHM_Cnt[idx][6] = (value32 & bMaskByte2) >> 16;\r
394             pACS->NHM_Cnt[idx][5] = (value32 & bMaskByte1) >> 8;\r
395 \r
396         } else if (pACS->ACS_Step==2) {\r
397         \r
398             value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11N);   // ODM_REG_NHM_CNT3_TO_CNT0_11N\r
399 \r
400             pACS->NHM_Cnt[idx][4] = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_CNT7_TO_CNT4_11N);            \r
401             pACS->NHM_Cnt[idx][3] = (value32 & bMaskByte3) >> 24;\r
402             pACS->NHM_Cnt[idx][2] = (value32 & bMaskByte2) >> 16;\r
403             pACS->NHM_Cnt[idx][1] = (value32 & bMaskByte1) >> 8;\r
404             pACS->NHM_Cnt[idx][0] = (value32 & bMaskByte0);\r
405         }\r
406     }\r
407     else if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)\r
408     {\r
409         //4 Check if NHM result is ready        \r
410         for (i=0; i<20; i++) {\r
411             \r
412                 ODM_delay_ms(1);\r
413                 if (ODM_GetBBReg(pDM_Odm, ODM_REG_NHM_DUR_READY_11AC, BIT16))\r
414                         break;\r
415         }\r
416     \r
417         if ( pACS->ACS_Step==1 ) {\r
418             \r
419             value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT7_TO_CNT4_11AC);\r
420             \r
421             pACS->NHM_Cnt[idx][9] = (value32 & bMaskByte1) >> 8;\r
422             pACS->NHM_Cnt[idx][8] = (value32 & bMaskByte0);\r
423 \r
424             value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11AC);     // ODM_REG_NHM_CNT3_TO_CNT0_11AC\r
425 \r
426             pACS->NHM_Cnt[idx][7] = (value32 & bMaskByte3) >> 24;\r
427             pACS->NHM_Cnt[idx][6] = (value32 & bMaskByte2) >> 16;\r
428             pACS->NHM_Cnt[idx][5] = (value32 & bMaskByte1) >> 8;\r
429 \r
430         } else if (pACS->ACS_Step==2) {\r
431         \r
432             value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11AC);      // ODM_REG_NHM_CNT3_TO_CNT0_11AC\r
433 \r
434             pACS->NHM_Cnt[idx][4] = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_CNT7_TO_CNT4_11AC);            \r
435             pACS->NHM_Cnt[idx][3] = (value32 & bMaskByte3) >> 24;\r
436             pACS->NHM_Cnt[idx][2] = (value32 & bMaskByte2) >> 16;\r
437             pACS->NHM_Cnt[idx][1] = (value32 & bMaskByte1) >> 8;\r
438             pACS->NHM_Cnt[idx][0] = (value32 & bMaskByte0);\r
439         }            \r
440     }\r
441 \r
442 }\r
443 \r
444 \r
445 //#define ACS_DEBUG_INFO //acs debug default off\r
446 /*\r
447 int phydm_AutoChannelSelectAP( \r
448     IN   PVOID   pDM_VOID,\r
449     IN   u4Byte  ACS_Type,                      // 0: RXCount_Type, 1:NHM_Type\r
450     IN   u4Byte  available_chnl_num        // amount of all channels\r
451     )\r
452 {\r
453     PDM_ODM_T               pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
454         PACS                    pACS    = &pDM_Odm->DM_ACS;\r
455     prtl8192cd_priv                     priv    = pDM_Odm->priv;\r
456     \r
457     static u4Byte           score2G[MAX_2G_CHANNEL_NUM], score5G[MAX_5G_CHANNEL_NUM];\r
458     u4Byte                  score[MAX_BSS_NUM], use_nhm = 0;\r
459     u4Byte                  minScore=0xffffffff;\r
460     u4Byte                  tmpScore, tmpIdx=0;\r
461     u4Byte                  traffic_check = 0;\r
462     u4Byte                  fa_count_weighting = 1;\r
463     int                     i, j, idx=0, idx_2G_end=-1, idx_5G_begin=-1, minChan=0;\r
464         struct bss_desc *pBss=NULL;\r
465 \r
466 #ifdef _DEBUG_RTL8192CD_\r
467         char tmpbuf[400];\r
468         int len=0;\r
469 #endif\r
470 \r
471         memset(score2G, '\0', sizeof(score2G));\r
472         memset(score5G, '\0', sizeof(score5G));\r
473 \r
474         for (i=0; i<priv->available_chnl_num; i++) {\r
475                 if (priv->available_chnl[i] <= 14)\r
476                         idx_2G_end = i;\r
477                 else\r
478                         break;\r
479         }\r
480 \r
481         for (i=0; i<priv->available_chnl_num; i++) {\r
482                 if (priv->available_chnl[i] > 14) {\r
483                         idx_5G_begin = i;\r
484                         break;\r
485                 }\r
486         }\r
487 \r
488 // DELETE\r
489 #ifndef CONFIG_RTL_NEW_AUTOCH\r
490         for (i=0; i<priv->site_survey->count; i++) {\r
491                 pBss = &priv->site_survey->bss[i];\r
492                 for (idx=0; idx<priv->available_chnl_num; idx++) {\r
493                         if (pBss->channel == priv->available_chnl[idx]) {\r
494                                 if (pBss->channel <= 14)\r
495                                         setChannelScore(idx, score2G, 0, MAX_2G_CHANNEL_NUM-1);\r
496                                 else\r
497                                         score5G[idx - idx_5G_begin] += 5;\r
498                                 break;\r
499                         }\r
500                 }\r
501         }\r
502 #endif\r
503 \r
504         if (idx_2G_end >= 0)\r
505                 for (i=0; i<=idx_2G_end; i++)\r
506                         score[i] = score2G[i];\r
507         if (idx_5G_begin >= 0)\r
508                 for (i=idx_5G_begin; i<priv->available_chnl_num; i++)\r
509                         score[i] = score5G[i - idx_5G_begin];\r
510                 \r
511 #ifdef CONFIG_RTL_NEW_AUTOCH\r
512         {\r
513                 u4Byte y, ch_begin=0, ch_end= priv->available_chnl_num;\r
514 \r
515                 u4Byte do_ap_check = 1, ap_ratio = 0;\r
516                 \r
517                 if (idx_2G_end >= 0) \r
518                         ch_end = idx_2G_end+1;\r
519                 if (idx_5G_begin >= 0)  \r
520                         ch_begin = idx_5G_begin;\r
521 \r
522 #ifdef ACS_DEBUG_INFO//for debug\r
523                 printk("\n");\r
524                 for (y=ch_begin; y<ch_end; y++)\r
525                         printk("1. init: chnl[%d] 20M_rx[%d] 40M_rx[%d] fa_cnt[%d] score[%d]\n",\r
526                                 priv->available_chnl[y], \r
527                                 priv->chnl_ss_mac_rx_count[y], \r
528                                 priv->chnl_ss_mac_rx_count_40M[y],\r
529                                 priv->chnl_ss_fa_count[y],\r
530                                 score[y]);\r
531                 printk("\n");\r
532 #endif\r
533 \r
534 #if defined(CONFIG_RTL_88E_SUPPORT) || defined(CONFIG_WLAN_HAL_8192EE)\r
535         if( pDM_Odm->SupportICType&(ODM_RTL8188E|ODM_RTL8192E)&& priv->pmib->dot11RFEntry.acs_type )\r
536                 {\r
537                         u4Byte tmp_score[MAX_BSS_NUM];\r
538                         memcpy(tmp_score, score, sizeof(score));\r
539                         if (find_clean_channel(priv, ch_begin, ch_end, tmp_score)) {\r
540                                 //memcpy(score, tmp_score, sizeof(score));\r
541 #ifdef _DEBUG_RTL8192CD_\r
542                                 printk("!! Found clean channel, select minimum FA channel\n");\r
543 #endif\r
544                                 goto USE_CLN_CH;\r
545                         }\r
546 #ifdef _DEBUG_RTL8192CD_\r
547                         printk("!! Not found clean channel, use NHM algorithm\n");\r
548 #endif\r
549                         use_nhm = 1;\r
550 USE_CLN_CH:\r
551                         for (y=ch_begin; y<ch_end; y++) {\r
552                                 for (i=0; i<=9; i++) {\r
553                                         u4Byte val32 = priv->nhm_cnt[y][i];\r
554                                         for (j=0; j<i; j++)\r
555                                                 val32 *= 3;\r
556                                         score[y] += val32;\r
557                                 }\r
558 \r
559 #ifdef _DEBUG_RTL8192CD_                                \r
560                                 printk("nhm_cnt_%d: H<-[ %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d]->L, score: %d\n", \r
561                                         y+1, priv->nhm_cnt[y][9], priv->nhm_cnt[y][8], priv->nhm_cnt[y][7], \r
562                                         priv->nhm_cnt[y][6], priv->nhm_cnt[y][5], priv->nhm_cnt[y][4],\r
563                                         priv->nhm_cnt[y][3], priv->nhm_cnt[y][2], priv->nhm_cnt[y][1],\r
564                                         priv->nhm_cnt[y][0], score[y]);\r
565 #endif\r
566                         }\r
567 \r
568                         if (!use_nhm)\r
569                                 memcpy(score, tmp_score, sizeof(score));\r
570                         \r
571                         goto choose_ch;\r
572                 }\r
573 #endif\r
574 \r
575             // For each channel, weighting behind channels with MAC RX counter\r
576             //For each channel, weighting the channel with FA counter\r
577 \r
578                 for (y=ch_begin; y<ch_end; y++) {\r
579                         score[y] += 8 * priv->chnl_ss_mac_rx_count[y];\r
580                         if (priv->chnl_ss_mac_rx_count[y] > 30)\r
581                                 do_ap_check = 0;\r
582                         if( priv->chnl_ss_mac_rx_count[y] > MAC_RX_COUNT_THRESHOLD )\r
583                                 traffic_check = 1;\r
584                         \r
585 #ifdef RTK_5G_SUPPORT\r
586                         if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G)\r
587 #endif\r
588                         {\r
589                                 if ((int)(y-4) >= (int)ch_begin)\r
590                                         score[y-4] += 2 * priv->chnl_ss_mac_rx_count[y];                                \r
591                                 if ((int)(y-3) >= (int)ch_begin)\r
592                                         score[y-3] += 8 * priv->chnl_ss_mac_rx_count[y];\r
593                                 if ((int)(y-2) >= (int)ch_begin)\r
594                                         score[y-2] += 8 * priv->chnl_ss_mac_rx_count[y];\r
595                                 if ((int)(y-1) >= (int)ch_begin)\r
596                                         score[y-1] += 10 * priv->chnl_ss_mac_rx_count[y];\r
597                                 if ((int)(y+1) < (int)ch_end)\r
598                                         score[y+1] += 10 * priv->chnl_ss_mac_rx_count[y];\r
599                                 if ((int)(y+2) < (int)ch_end)\r
600                                         score[y+2] += 8 * priv->chnl_ss_mac_rx_count[y];\r
601                                 if ((int)(y+3) < (int)ch_end)\r
602                                         score[y+3] += 8 * priv->chnl_ss_mac_rx_count[y];\r
603                                 if ((int)(y+4) < (int)ch_end)\r
604                                         score[y+4] += 2 * priv->chnl_ss_mac_rx_count[y];\r
605                         }\r
606 \r
607                         //this is for CH_LOAD caculation\r
608                         if( priv->chnl_ss_cca_count[y] > priv->chnl_ss_fa_count[y])\r
609                                 priv->chnl_ss_cca_count[y]-= priv->chnl_ss_fa_count[y];\r
610                         else\r
611                                 priv->chnl_ss_cca_count[y] = 0;\r
612                 }\r
613 \r
614 #ifdef ACS_DEBUG_INFO//for debug\r
615                 printk("\n");\r
616                 for (y=ch_begin; y<ch_end; y++)\r
617                         printk("2. after 20M check: chnl[%d] score[%d]\n",priv->available_chnl[y], score[y]);\r
618                 printk("\n");\r
619 #endif  \r
620 \r
621                 for (y=ch_begin; y<ch_end; y++) {\r
622                         if (priv->chnl_ss_mac_rx_count_40M[y]) {\r
623                                 score[y] += 5 * priv->chnl_ss_mac_rx_count_40M[y];\r
624                                 if (priv->chnl_ss_mac_rx_count_40M[y] > 30)\r
625                                         do_ap_check = 0;\r
626                                 if( priv->chnl_ss_mac_rx_count_40M[y] > MAC_RX_COUNT_THRESHOLD )\r
627                                         traffic_check = 1;\r
628                                 \r
629 #ifdef RTK_5G_SUPPORT\r
630                                 if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G)\r
631 #endif\r
632                                 {\r
633                                         if ((int)(y-6) >= (int)ch_begin)\r
634                                                 score[y-6] += 1 * priv->chnl_ss_mac_rx_count_40M[y];\r
635                                         if ((int)(y-5) >= (int)ch_begin)\r
636                                                 score[y-5] += 4 * priv->chnl_ss_mac_rx_count_40M[y];\r
637                                         if ((int)(y-4) >= (int)ch_begin)\r
638                                                 score[y-4] += 4 * priv->chnl_ss_mac_rx_count_40M[y];\r
639                                         if ((int)(y-3) >= (int)ch_begin)\r
640                                                 score[y-3] += 5 * priv->chnl_ss_mac_rx_count_40M[y];\r
641                                         if ((int)(y-2) >= (int)ch_begin)\r
642                                                 score[y-2] += (5 * priv->chnl_ss_mac_rx_count_40M[y])/2;\r
643                                         if ((int)(y-1) >= (int)ch_begin)\r
644                                                 score[y-1] += 5 * priv->chnl_ss_mac_rx_count_40M[y];\r
645                                         if ((int)(y+1) < (int)ch_end)\r
646                                                 score[y+1] += 5 * priv->chnl_ss_mac_rx_count_40M[y];\r
647                                         if ((int)(y+2) < (int)ch_end)\r
648                                                 score[y+2] += (5 * priv->chnl_ss_mac_rx_count_40M[y])/2;\r
649                                         if ((int)(y+3) < (int)ch_end)\r
650                                                 score[y+3] += 5 * priv->chnl_ss_mac_rx_count_40M[y];\r
651                                         if ((int)(y+4) < (int)ch_end)\r
652                                                 score[y+4] += 4 * priv->chnl_ss_mac_rx_count_40M[y];\r
653                                         if ((int)(y+5) < (int)ch_end)\r
654                                                 score[y+5] += 4 * priv->chnl_ss_mac_rx_count_40M[y];\r
655                                         if ((int)(y+6) < (int)ch_end)\r
656                                                 score[y+6] += 1 * priv->chnl_ss_mac_rx_count_40M[y];\r
657                                 }\r
658                         }\r
659                 }\r
660 \r
661 #ifdef ACS_DEBUG_INFO//for debug\r
662                 printk("\n");\r
663                 for (y=ch_begin; y<ch_end; y++)\r
664                         printk("3. after 40M check: chnl[%d] score[%d]\n",priv->available_chnl[y], score[y]);\r
665                 printk("\n");\r
666                 printk("4. do_ap_check=%d traffic_check=%d\n", do_ap_check, traffic_check);\r
667                 printk("\n");\r
668 #endif\r
669 \r
670                 if( traffic_check == 0)\r
671                         fa_count_weighting = 5;\r
672                 else\r
673                         fa_count_weighting = 1;\r
674 \r
675                 for (y=ch_begin; y<ch_end; y++) {\r
676                         score[y] += fa_count_weighting * priv->chnl_ss_fa_count[y];\r
677                 }\r
678 \r
679 #ifdef ACS_DEBUG_INFO//for debug\r
680                 printk("\n");\r
681                 for (y=ch_begin; y<ch_end; y++)\r
682                         printk("5. after fa check: chnl[%d] score[%d]\n",priv->available_chnl[y], score[y]);\r
683                 printk("\n");\r
684 #endif                  \r
685 \r
686                 if (do_ap_check) {\r
687                         for (i=0; i<priv->site_survey->count; i++) {                            \r
688                                 pBss = &priv->site_survey->bss[i];\r
689                                 for (y=ch_begin; y<ch_end; y++) {\r
690                                         if (pBss->channel == priv->available_chnl[y]) {\r
691                                                 if (pBss->channel <= 14) {\r
692 #ifdef ACS_DEBUG_INFO//for debug\r
693                                                 printk("\n");\r
694                                                 printk("chnl[%d] has ap rssi=%d bw[0x%02x]\n",\r
695                                                         pBss->channel, pBss->rssi, pBss->t_stamp[1]);\r
696                                                 printk("\n");\r
697 #endif\r
698                                                         if (pBss->rssi > 60)\r
699                                                                 ap_ratio = 4;\r
700                                                         else if (pBss->rssi > 35)\r
701                                                                 ap_ratio = 2;\r
702                                                         else\r
703                                                                 ap_ratio = 1;\r
704                                                         \r
705                                                         if ((pBss->t_stamp[1] & 0x6) == 0) {\r
706                                                                 score[y] += 50 * ap_ratio;\r
707                                                                 if ((int)(y-4) >= (int)ch_begin)\r
708                                                                         score[y-4] += 10 * ap_ratio;\r
709                                                                 if ((int)(y-3) >= (int)ch_begin)\r
710                                                                         score[y-3] += 20 * ap_ratio;\r
711                                                                 if ((int)(y-2) >= (int)ch_begin)\r
712                                                                         score[y-2] += 30 * ap_ratio;\r
713                                                                 if ((int)(y-1) >= (int)ch_begin)\r
714                                                                         score[y-1] += 40 * ap_ratio;\r
715                                                                 if ((int)(y+1) < (int)ch_end)\r
716                                                                         score[y+1] += 40 * ap_ratio;\r
717                                                                 if ((int)(y+2) < (int)ch_end)\r
718                                                                         score[y+2] += 30 * ap_ratio;\r
719                                                                 if ((int)(y+3) < (int)ch_end)\r
720                                                                         score[y+3] += 20 * ap_ratio;\r
721                                                                 if ((int)(y+4) < (int)ch_end)\r
722                                                                         score[y+4] += 10 * ap_ratio;\r
723                                                         }       \r
724                                                         else if ((pBss->t_stamp[1] & 0x4) == 0) {\r
725                                                                 score[y] += 50 * ap_ratio;\r
726                                                                 if ((int)(y-3) >= (int)ch_begin)\r
727                                                                         score[y-3] += 20 * ap_ratio;\r
728                                                                 if ((int)(y-2) >= (int)ch_begin)\r
729                                                                         score[y-2] += 30 * ap_ratio;\r
730                                                                 if ((int)(y-1) >= (int)ch_begin)\r
731                                                                         score[y-1] += 40 * ap_ratio;\r
732                                                                 if ((int)(y+1) < (int)ch_end)\r
733                                                                         score[y+1] += 50 * ap_ratio;\r
734                                                                 if ((int)(y+2) < (int)ch_end)\r
735                                                                         score[y+2] += 50 * ap_ratio;\r
736                                                                 if ((int)(y+3) < (int)ch_end)\r
737                                                                         score[y+3] += 50 * ap_ratio;\r
738                                                                 if ((int)(y+4) < (int)ch_end)\r
739                                                                         score[y+4] += 50 * ap_ratio;\r
740                                                                 if ((int)(y+5) < (int)ch_end)\r
741                                                                         score[y+5] += 40 * ap_ratio;\r
742                                                                 if ((int)(y+6) < (int)ch_end)\r
743                                                                         score[y+6] += 30 * ap_ratio;\r
744                                                                 if ((int)(y+7) < (int)ch_end)\r
745                                                                         score[y+7] += 20 * ap_ratio;    \r
746                                                         }       \r
747                                                         else {\r
748                                                                 score[y] += 50 * ap_ratio;\r
749                                                                 if ((int)(y-7) >= (int)ch_begin)\r
750                                                                         score[y-7] += 20 * ap_ratio;\r
751                                                                 if ((int)(y-6) >= (int)ch_begin)\r
752                                                                         score[y-6] += 30 * ap_ratio;\r
753                                                                 if ((int)(y-5) >= (int)ch_begin)\r
754                                                                         score[y-5] += 40 * ap_ratio;\r
755                                                                 if ((int)(y-4) >= (int)ch_begin)\r
756                                                                         score[y-4] += 50 * ap_ratio;\r
757                                                                 if ((int)(y-3) >= (int)ch_begin)\r
758                                                                         score[y-3] += 50 * ap_ratio;\r
759                                                                 if ((int)(y-2) >= (int)ch_begin)\r
760                                                                         score[y-2] += 50 * ap_ratio;\r
761                                                                 if ((int)(y-1) >= (int)ch_begin)\r
762                                                                         score[y-1] += 50 * ap_ratio;\r
763                                                                 if ((int)(y+1) < (int)ch_end)\r
764                                                                         score[y+1] += 40 * ap_ratio;\r
765                                                                 if ((int)(y+2) < (int)ch_end)\r
766                                                                         score[y+2] += 30 * ap_ratio;\r
767                                                                 if ((int)(y+3) < (int)ch_end)\r
768                                                                         score[y+3] += 20 * ap_ratio;\r
769                                                         }       \r
770                                                 }       \r
771                                                 else {\r
772                                                         if ((pBss->t_stamp[1] & 0x6) == 0) {\r
773                                                                 score[y] += 500;\r
774                                                         }\r
775                                                         else if ((pBss->t_stamp[1] & 0x4) == 0) {\r
776                                                                 score[y] += 500;\r
777                                                                 if ((int)(y+1) < (int)ch_end)\r
778                                                                         score[y+1] += 500;\r
779                                                         }\r
780                                                         else {  \r
781                                                                 score[y] += 500;\r
782                                                                 if ((int)(y-1) >= (int)ch_begin)\r
783                                                                         score[y-1] += 500;\r
784                                                         }\r
785                                                 }\r
786                                                 break;\r
787                                         }\r
788                                 }\r
789                         }\r
790                 }\r
791 \r
792 #ifdef ACS_DEBUG_INFO//for debug\r
793                 printk("\n");\r
794                 for (y=ch_begin; y<ch_end; y++)\r
795                         printk("6. after ap check: chnl[%d]:%d\n", priv->available_chnl[y],score[y]);\r
796                 printk("\n");\r
797 #endif          \r
798 \r
799 #ifdef  SS_CH_LOAD_PROC\r
800 \r
801                 // caculate noise level -- suggested by wilson\r
802                 for (y=ch_begin; y<ch_end; y++)  {\r
803                         int fa_lv=0, cca_lv=0;\r
804                         if (priv->chnl_ss_fa_count[y]>1000) {\r
805                                 fa_lv = 100;\r
806                         } else if (priv->chnl_ss_fa_count[y]>500) {\r
807                                 fa_lv = 34 * (priv->chnl_ss_fa_count[y]-500) / 500 + 66;\r
808                         } else if (priv->chnl_ss_fa_count[y]>200) {\r
809                                 fa_lv = 33 * (priv->chnl_ss_fa_count[y] - 200) / 300 + 33;\r
810                         } else if (priv->chnl_ss_fa_count[y]>100) {\r
811                                 fa_lv = 18 * (priv->chnl_ss_fa_count[y] - 100) / 100 + 15;\r
812                         } else {\r
813                                 fa_lv = 15 * priv->chnl_ss_fa_count[y] / 100;\r
814                         } \r
815                         if (priv->chnl_ss_cca_count[y]>400) {\r
816                                 cca_lv = 100;\r
817                         } else if (priv->chnl_ss_cca_count[y]>200) {\r
818                                 cca_lv = 34 * (priv->chnl_ss_cca_count[y] - 200) / 200 + 66;\r
819                         } else if (priv->chnl_ss_cca_count[y]>80) {\r
820                                 cca_lv = 33 * (priv->chnl_ss_cca_count[y] - 80) / 120 + 33;\r
821                         } else if (priv->chnl_ss_cca_count[y]>40) {\r
822                                 cca_lv = 18 * (priv->chnl_ss_cca_count[y] - 40) / 40 + 15;\r
823                         } else {\r
824                                 cca_lv = 15 * priv->chnl_ss_cca_count[y] / 40;\r
825                         }\r
826 \r
827                         priv->chnl_ss_load[y] = (((fa_lv > cca_lv)? fa_lv : cca_lv)*75+((score[y]>100)?100:score[y])*25)/100;\r
828 \r
829                         DEBUG_INFO("ch:%d f=%d (%d), c=%d (%d), fl=%d, cl=%d, sc=%d, cu=%d\n", \r
830                                         priv->available_chnl[y],\r
831                                         priv->chnl_ss_fa_count[y], fa_thd,\r
832                                         priv->chnl_ss_cca_count[y], cca_thd,\r
833                                         fa_lv, \r
834                                         cca_lv,\r
835                                         score[y],                                       \r
836                                         priv->chnl_ss_load[y]);\r
837                         \r
838                 }               \r
839 #endif          \r
840         }\r
841 #endif\r
842 \r
843 choose_ch:\r
844 \r
845 #ifdef DFS\r
846         // heavy weighted DFS channel\r
847         if (idx_5G_begin >= 0){\r
848                 for (i=idx_5G_begin; i<priv->available_chnl_num; i++) {\r
849                         if (!priv->pmib->dot11DFSEntry.disable_DFS && is_DFS_channel(priv->available_chnl[i]) \r
850                         && (score[i]!= 0xffffffff)){\r
851                                         score[i] += 1600; \r
852                 }\r
853         }\r
854         }\r
855 #endif\r
856 \r
857 \r
858 //prevent Auto Channel selecting wrong channel in 40M mode-----------------\r
859         if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N)\r
860                 && priv->pshare->is_40m_bw) {\r
861 #if 0\r
862                 if (GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset == 1) {\r
863                         //Upper Primary Channel, cannot select the two lowest channels\r
864                         if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) {\r
865                                 score[0] = 0xffffffff;\r
866                                 score[1] = 0xffffffff;\r
867                                 score[2] = 0xffffffff;\r
868                                 score[3] = 0xffffffff;\r
869                                 score[4] = 0xffffffff;\r
870 \r
871                                 score[13] = 0xffffffff;\r
872                                 score[12] = 0xffffffff;\r
873                                 score[11] = 0xffffffff;\r
874                         }\r
875 \r
876 //                      if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) {\r
877 //                              score[idx_5G_begin] = 0xffffffff;\r
878 //                              score[idx_5G_begin + 1] = 0xffffffff;\r
879 //                      }\r
880                 }\r
881                 else if (GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset == 2) {\r
882                         //Lower Primary Channel, cannot select the two highest channels\r
883                         if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) {\r
884                                 score[0] = 0xffffffff;\r
885                                 score[1] = 0xffffffff;\r
886                                 score[2] = 0xffffffff;\r
887 \r
888                                 score[13] = 0xffffffff;\r
889                                 score[12] = 0xffffffff;\r
890                                 score[11] = 0xffffffff;\r
891                                 score[10] = 0xffffffff;\r
892                                 score[9] = 0xffffffff;\r
893                         }\r
894 \r
895 //                      if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) {\r
896 //                              score[priv->available_chnl_num - 2] = 0xffffffff;\r
897 //                              score[priv->available_chnl_num - 1] = 0xffffffff;\r
898 //                      }\r
899                 }\r
900 #endif\r
901                 for (i=0; i<=idx_2G_end; ++i)\r
902                         if (priv->available_chnl[i] == 14)\r
903                                 score[i] = 0xffffffff;          // mask chan14\r
904 \r
905 #ifdef RTK_5G_SUPPORT\r
906                 if (idx_5G_begin >= 0) {\r
907                         for (i=idx_5G_begin; i<priv->available_chnl_num; i++) {\r
908                                 int ch = priv->available_chnl[i];\r
909                                 if(priv->available_chnl[i] > 144) \r
910                                         --ch;\r
911                                 if((ch%4) || ch==140 || ch == 164 )     //mask ch 140, ch 165, ch 184...\r
912                                         score[i] = 0xffffffff;\r
913                         }\r
914                 }\r
915 #endif\r
916 \r
917                 \r
918         }\r
919 \r
920         if (priv->pmib->dot11RFEntry.disable_ch1213) {\r
921                 for (i=0; i<=idx_2G_end; ++i) {\r
922                         int ch = priv->available_chnl[i];\r
923                         if ((ch == 12) || (ch == 13))\r
924                                 score[i] = 0xffffffff;\r
925                 }\r
926         }\r
927 \r
928         if (((priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_GLOBAL) ||\r
929                         (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_WORLD_WIDE)) &&\r
930                  (idx_2G_end >= 11) && (idx_2G_end < 14)) {\r
931                 score[13] = 0xffffffff; // mask chan14\r
932                 score[12] = 0xffffffff; // mask chan13\r
933                 score[11] = 0xffffffff; // mask chan12\r
934         }\r
935         \r
936 //------------------------------------------------------------------\r
937 \r
938 #ifdef _DEBUG_RTL8192CD_\r
939         for (i=0; i<priv->available_chnl_num; i++) {\r
940                 len += sprintf(tmpbuf+len, "ch%d:%u ", priv->available_chnl[i], score[i]);              \r
941         }\r
942         strcat(tmpbuf, "\n");\r
943         panic_printk("%s", tmpbuf);\r
944 \r
945 #endif\r
946 \r
947         if ( (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G)\r
948                 && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80)) \r
949         {\r
950                 for (i=0; i<priv->available_chnl_num; i++) {\r
951                         if (is80MChannel(priv->available_chnl, priv->available_chnl_num, priv->available_chnl[i])) {\r
952                                 tmpScore = 0;\r
953                                 for (j=0; j<4; j++) {\r
954                                         if ((tmpScore != 0xffffffff) && (score[i+j] != 0xffffffff))\r
955                                                 tmpScore += score[i+j];\r
956                                         else\r
957                                                 tmpScore = 0xffffffff;\r
958                                 }\r
959                                 tmpScore = tmpScore / 4;\r
960                                 if (minScore > tmpScore) {\r
961                                         minScore = tmpScore;\r
962 \r
963                                         tmpScore = 0xffffffff;\r
964                                         for (j=0; j<4; j++) {\r
965                                                 if (score[i+j] < tmpScore) {\r
966                                                         tmpScore = score[i+j];\r
967                                                         tmpIdx = i+j;\r
968                                                 }\r
969                                         }\r
970 \r
971                                         idx = tmpIdx;\r
972                                 }\r
973                                 i += 3;\r
974                         }\r
975                 }\r
976                 if (minScore == 0xffffffff) {\r
977                         // there is no 80M channels\r
978                         priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20;\r
979                         for (i=0; i<priv->available_chnl_num; i++) {\r
980                                 if (score[i] < minScore) {\r
981                                         minScore = score[i];\r
982                                         idx = i;\r
983                                 }\r
984                         }\r
985                 }\r
986         }\r
987         else if( (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G)\r
988                         && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40))\r
989         {\r
990                 for (i=0; i<priv->available_chnl_num; i++) {\r
991                         if(is40MChannel(priv->available_chnl,priv->available_chnl_num,priv->available_chnl[i])) {\r
992                                 tmpScore = 0;\r
993                                 for(j=0;j<2;j++) {\r
994                                         if ((tmpScore != 0xffffffff) && (score[i+j] != 0xffffffff))\r
995                                                 tmpScore += score[i+j];\r
996                                         else\r
997                                                 tmpScore = 0xffffffff;\r
998                                 }\r
999                                 tmpScore = tmpScore / 2;\r
1000                                 if(minScore > tmpScore) {\r
1001                                         minScore = tmpScore;\r
1002 \r
1003                                         tmpScore = 0xffffffff;\r
1004                                         for (j=0; j<2; j++) {\r
1005                                                 if (score[i+j] < tmpScore) {\r
1006                                                         tmpScore = score[i+j];\r
1007                                                         tmpIdx = i+j;\r
1008                                                 }\r
1009                                         }\r
1010 \r
1011                                         idx = tmpIdx;\r
1012                                 }\r
1013                                 i += 1;\r
1014                         }\r
1015                 }\r
1016                 if (minScore == 0xffffffff) {\r
1017                         // there is no 40M channels\r
1018                         priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20;\r
1019                         for (i=0; i<priv->available_chnl_num; i++) {\r
1020                                 if (score[i] < minScore) {\r
1021                                         minScore = score[i];\r
1022                                         idx = i;\r
1023                                 }\r
1024                         }\r
1025                 }\r
1026         }\r
1027         else if( (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G)\r
1028                         && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40)\r
1029                         && (priv->available_chnl_num >= 8) )\r
1030         {\r
1031                 u4Byte groupScore[14];\r
1032 \r
1033                 memset(groupScore, 0xff , sizeof(groupScore));\r
1034                 for (i=0; i<priv->available_chnl_num-4; i++) {\r
1035                         if (score[i] != 0xffffffff && score[i+4] != 0xffffffff) {\r
1036                                 groupScore[i] = score[i] + score[i+4];\r
1037                                 DEBUG_INFO("groupScore, ch %d,%d: %d\n", i+1, i+5, groupScore[i]);\r
1038                                 if (groupScore[i] < minScore) {\r
1039 #ifdef AUTOCH_SS_SPEEDUP\r
1040                                         if(priv->pmib->miscEntry.autoch_1611_enable)\r
1041                                         {\r
1042                                                 if(priv->available_chnl[i]==1 || priv->available_chnl[i]==6 || priv->available_chnl[i]==11)\r
1043                                                 {\r
1044                                                         minScore = groupScore[i];\r
1045                                                         idx = i;\r
1046                                                 }\r
1047                                         }\r
1048                                         else\r
1049 #endif\r
1050                                         {                                       \r
1051                                                 minScore = groupScore[i];\r
1052                                                 idx = i;\r
1053                                         }\r
1054                                 }\r
1055                         }\r
1056                 }\r
1057 \r
1058                 if (score[idx] < score[idx+4]) {\r
1059                         GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;\r
1060                         priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_ABOVE;                        \r
1061                 } else {\r
1062                         idx = idx + 4;\r
1063                         GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;\r
1064                         priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_BELOW;                        \r
1065                 }\r
1066         }\r
1067         else \r
1068         {\r
1069                 for (i=0; i<priv->available_chnl_num; i++) {\r
1070                         if (score[i] < minScore) {\r
1071 #ifdef AUTOCH_SS_SPEEDUP\r
1072                                 if(priv->pmib->miscEntry.autoch_1611_enable)\r
1073                                 {\r
1074                                         if(priv->available_chnl[i]==1 || priv->available_chnl[i]==6 || priv->available_chnl[i]==11)\r
1075                                         {\r
1076                                                 minScore = score[i];\r
1077                                                 idx = i;\r
1078                                         }\r
1079                                 }\r
1080                                 else\r
1081 #endif\r
1082                                 {                               \r
1083                                         minScore = score[i];\r
1084                                         idx = i;\r
1085                                 }\r
1086                         }\r
1087                 }\r
1088         }\r
1089 \r
1090         if (IS_A_CUT_8881A(priv) &&\r
1091                 (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80)) {\r
1092                 if ((priv->available_chnl[idx] == 36) ||\r
1093                         (priv->available_chnl[idx] == 52) ||\r
1094                         (priv->available_chnl[idx] == 100) ||\r
1095                         (priv->available_chnl[idx] == 116) ||\r
1096                         (priv->available_chnl[idx] == 132) ||\r
1097                         (priv->available_chnl[idx] == 149) ||\r
1098                         (priv->available_chnl[idx] == 165))\r
1099                         idx++;\r
1100                 else if ((priv->available_chnl[idx] == 48) ||\r
1101                         (priv->available_chnl[idx] == 64) ||\r
1102                         (priv->available_chnl[idx] == 112) ||\r
1103                         (priv->available_chnl[idx] == 128) ||\r
1104                         (priv->available_chnl[idx] == 144) ||\r
1105                         (priv->available_chnl[idx] == 161) ||\r
1106                         (priv->available_chnl[idx] == 177))\r
1107                         idx--;\r
1108         }\r
1109 \r
1110         minChan = priv->available_chnl[idx];\r
1111 \r
1112         // skip channel 14 if don't support ofdm\r
1113         if ((priv->pmib->dot11RFEntry.disable_ch14_ofdm) &&\r
1114                         (minChan == 14)) {\r
1115                 score[idx] = 0xffffffff;\r
1116                 \r
1117                 minScore = 0xffffffff;\r
1118                 for (i=0; i<priv->available_chnl_num; i++) {\r
1119                         if (score[i] < minScore) {\r
1120                                 minScore = score[i];\r
1121                                 idx = i;\r
1122                         }\r
1123                 }\r
1124                 minChan = priv->available_chnl[idx];\r
1125         }\r
1126 \r
1127 #if 0\r
1128         //Check if selected channel available for 80M/40M BW or NOT ?\r
1129         if(priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G)\r
1130         {\r
1131                 if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80)\r
1132                 {\r
1133                         if(!is80MChannel(priv->available_chnl,priv->available_chnl_num,minChan))\r
1134                         {\r
1135                                 //printk("BW=80M, selected channel = %d is unavaliable! reduce to 40M\n", minChan);\r
1136                                 //priv->pmib->dot11nConfigEntry.dot11nUse40M = HT_CHANNEL_WIDTH_20_40;\r
1137                                 priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20_40;\r
1138                         }\r
1139                 }\r
1140                         \r
1141                 if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40)\r
1142                 {\r
1143                         if(!is40MChannel(priv->available_chnl,priv->available_chnl_num,minChan))\r
1144                         {\r
1145                                 //printk("BW=40M, selected channel = %d is unavaliable! reduce to 20M\n", minChan);\r
1146                                 //priv->pmib->dot11nConfigEntry.dot11nUse40M = HT_CHANNEL_WIDTH_20;\r
1147                                 priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20;\r
1148                         }\r
1149                 }\r
1150         }\r
1151 #endif\r
1152 \r
1153 #ifdef CONFIG_RTL_NEW_AUTOCH\r
1154         RTL_W32(RXERR_RPT, RXERR_RPT_RST);\r
1155 #endif\r
1156 \r
1157 // auto adjust contro-sideband\r
1158         if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N)\r
1159                         && (priv->pshare->is_40m_bw ==1 || priv->pshare->is_40m_bw ==2)) {\r
1160 \r
1161 #ifdef RTK_5G_SUPPORT\r
1162                 if (priv->pmib->dot11RFEntry.phyBandSelect & PHY_BAND_5G) {\r
1163                         if( (minChan>144) ? ((minChan-1)%8) : (minChan%8)) {\r
1164                                 GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;\r
1165                                 priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_ABOVE;\r
1166                         } else {\r
1167                                 GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;\r
1168                                 priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_BELOW;\r
1169                         }\r
1170 \r
1171                 } else\r
1172 #endif          \r
1173                 {\r
1174 #if 0\r
1175 #ifdef CONFIG_RTL_NEW_AUTOCH\r
1176                         unsigned int ch_max;\r
1177 \r
1178                         if (priv->available_chnl[idx_2G_end] >= 13)\r
1179                                 ch_max = 13;\r
1180                         else\r
1181                                 ch_max = priv->available_chnl[idx_2G_end];\r
1182 \r
1183                         if ((minChan >= 5) && (minChan <= (ch_max-5))) {\r
1184                                 if (score[minChan+4] > score[minChan-4]) { // what if some channels were cancelled?\r
1185                                         GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;\r
1186                                         priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_BELOW;\r
1187                                 } else {\r
1188                                         GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;\r
1189                                         priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_ABOVE;\r
1190                                 }\r
1191                         } else\r
1192 #endif\r
1193                         {\r
1194                                 if (minChan < 5) {\r
1195                                         GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;\r
1196                                         priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_ABOVE;\r
1197                                 }\r
1198                                 else if (minChan > 7) {\r
1199                                         GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;\r
1200                                         priv->pshare->offset_2nd_chan   = HT_2NDCH_OFFSET_BELOW;\r
1201                                 }\r
1202                         }\r
1203 #endif\r
1204                 }\r
1205         }\r
1206 //-----------------------\r
1207 \r
1208 #if defined(__ECOS) && defined(CONFIG_SDIO_HCI)\r
1209         panic_printk("Auto channel choose ch:%d\n", minChan);\r
1210 #else\r
1211 #ifdef _DEBUG_RTL8192CD_\r
1212         panic_printk("Auto channel choose ch:%d\n", minChan);\r
1213 #endif\r
1214 #endif\r
1215 #ifdef ACS_DEBUG_INFO//for debug\r
1216         printk("7. minChan:%d 2nd_offset:%d\n", minChan, priv->pshare->offset_2nd_chan);\r
1217 #endif\r
1218 \r
1219         return minChan;\r
1220 }\r
1221 */\r
1222 \r
1223 #endif\r
1224 \r
1225 \r
1226 \r