OSDN Git Service

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