1 /******************************************************************************
\r
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
\r
5 * This program is free software; you can redistribute it and/or modify it
\r
6 * under the terms of version 2 of the GNU General Public License as
\r
7 * published by the Free Software Foundation.
\r
9 * This program is distributed in the hope that it will be useful, but WITHOUT
\r
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
14 * You should have received a copy of the GNU General Public License along with
\r
15 * this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
\r
19 ******************************************************************************/
\r
21 //============================================================
\r
23 //============================================================
\r
24 #include "mp_precomp.h"
\r
25 #include "phydm_precomp.h"
\r
29 ODM_GetAutoChannelSelectResult(
\r
34 PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
\r
35 PACS pACS = &pDM_Odm->DM_ACS;
\r
37 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
\r
38 if(Band == ODM_BAND_2_4G)
\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
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
49 return (u1Byte)pACS->CleanChannel_2G;
\r
55 odm_AutoChannelSelectSetting(
\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
65 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectSetting()=========> \n"));
\r
73 if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)
\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
79 else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES)
\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
89 odm_AutoChannelSelectInit(
\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
98 if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT))
\r
101 if(pACS->bForceACSResult)
\r
104 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectInit()=========> \n"));
\r
106 pACS->CleanChannel_2G = 1;
\r
107 pACS->CleanChannel_5G = 36;
\r
109 for (i = 0; i < ODM_MAX_CHANNEL_2G; ++i)
\r
111 pACS->Channel_Info_2G[0][i] = 0;
\r
112 pACS->Channel_Info_2G[1][i] = 0;
\r
115 if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)
\r
117 for (i = 0; i < ODM_MAX_CHANNEL_5G; ++i)
\r
119 pACS->Channel_Info_5G[0][i] = 0;
\r
120 pACS->Channel_Info_5G[1][i] = 0;
\r
127 odm_AutoChannelSelectReset(
\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
135 if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT))
\r
138 if(pACS->bForceACSResult)
\r
141 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectReset()=========> \n"));
\r
143 odm_AutoChannelSelectSetting(pDM_Odm,TRUE);// for 20ms measurement
\r
144 Phydm_NHMCounterStatisticsReset(pDM_Odm);
\r
149 odm_AutoChannelSelect(
\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
160 if(!(pDM_Odm->SupportAbility & ODM_BB_NHM_CNT))
\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
166 if(pACS->bForceACSResult)
\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
173 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelect(): Channel = %d=========> \n", Channel));
\r
175 Phydm_GetNHMCounterStatistics(pDM_Odm);
\r
176 odm_AutoChannelSelectSetting(pDM_Odm,FALSE);
\r
178 if(Channel >=1 && Channel <=14)
\r
180 ChannelIDX = Channel - 1;
\r
181 pACS->Channel_Info_2G[1][ChannelIDX]++;
\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
187 pACS->Channel_Info_2G[0][ChannelIDX] = pDM_Odm->NHM_cnt_0;
\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
192 for(SearchIDX = 0; SearchIDX < ODM_MAX_CHANNEL_2G; SearchIDX++)
\r
194 if(pACS->Channel_Info_2G[1][SearchIDX] != 0)
\r
196 if(pACS->Channel_Info_2G[0][SearchIDX] >= MaxScore)
\r
198 MaxScore = pACS->Channel_Info_2G[0][SearchIDX];
\r
199 pACS->CleanChannel_2G = SearchIDX+1;
\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
207 else if(Channel >= 36)
\r
210 pACS->CleanChannel_5G = Channel;
\r
215 #if ( DM_ODM_SUPPORT_TYPE & ODM_AP )
\r
218 phydm_AutoChannelSelectSettingAP(
\r
220 IN u4Byte setting, // 0: STORE_DEFAULT_NHM_SETTING; 1: RESTORE_DEFAULT_NHM_SETTING, 2: ACS_NHM_SETTING
\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
228 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectSettingAP()=========> \n"));
\r
230 //3 Store Default Setting
\r
231 if(setting == STORE_DEFAULT_NHM_SETTING)
\r
233 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("STORE_DEFAULT_NHM_SETTING\n"));
\r
235 if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) // store Reg0x990, Reg0x994, Reg0x998, Reg0x99C, Reg0x9a0
\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
243 else if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES)
\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
253 //3 Restore Default Setting
\r
254 else if(setting == RESTORE_DEFAULT_NHM_SETTING)
\r
256 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("RESTORE_DEFAULT_NHM_SETTING\n"));
\r
258 if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) // store Reg0x990, Reg0x994, Reg0x998, Reg0x99C, Reg0x9a0
\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
266 else if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES)
\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
277 else if(setting == ACS_NHM_SETTING)
\r
279 ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("ACS_NHM_SETTING\n"));
\r
282 pACS->ACS_Step = acs_step;
\r
284 if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)
\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
291 if(pACS->ACS_Step == 0)
\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
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
305 else if(pACS->ACS_Step == 1)
\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
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
319 else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES)
\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
326 if(pACS->ACS_Step == 0)
\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
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
340 else if(pACS->ACS_Step == 1)
\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
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
358 phydm_GetNHMStatisticsAP(
\r
360 IN u4Byte idx, // @ 2G, Real channel number = idx+1
\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
370 pACS->ACS_Step = acs_step;
\r
372 if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES)
\r
374 //4 Check if NHM result is ready
\r
375 for (i=0; i<20; i++) {
\r
378 if ( ODM_GetBBReg(pDM_Odm,rFPGA0_PSDReport,BIT17) )
\r
382 //4 Get NHM Statistics
\r
383 if ( pACS->ACS_Step==1 ) {
\r
385 value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT7_TO_CNT4_11N);
\r
387 pACS->NHM_Cnt[idx][9] = (value32 & bMaskByte1) >> 8;
\r
388 pACS->NHM_Cnt[idx][8] = (value32 & bMaskByte0);
\r
390 value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11N); // ODM_REG_NHM_CNT3_TO_CNT0_11N
\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
396 } else if (pACS->ACS_Step==2) {
\r
398 value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11N); // ODM_REG_NHM_CNT3_TO_CNT0_11N
\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
407 else if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)
\r
409 //4 Check if NHM result is ready
\r
410 for (i=0; i<20; i++) {
\r
413 if (ODM_GetBBReg(pDM_Odm, ODM_REG_NHM_DUR_READY_11AC, BIT16))
\r
417 if ( pACS->ACS_Step==1 ) {
\r
419 value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT7_TO_CNT4_11AC);
\r
421 pACS->NHM_Cnt[idx][9] = (value32 & bMaskByte1) >> 8;
\r
422 pACS->NHM_Cnt[idx][8] = (value32 & bMaskByte0);
\r
424 value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11AC); // ODM_REG_NHM_CNT3_TO_CNT0_11AC
\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
430 } else if (pACS->ACS_Step==2) {
\r
432 value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11AC); // ODM_REG_NHM_CNT3_TO_CNT0_11AC
\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
445 //#define ACS_DEBUG_INFO //acs debug default off
\r
447 int phydm_AutoChannelSelectAP(
\r
449 IN u4Byte ACS_Type, // 0: RXCount_Type, 1:NHM_Type
\r
450 IN u4Byte available_chnl_num // amount of all channels
\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
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
466 #ifdef _DEBUG_RTL8192CD_
\r
471 memset(score2G, '\0', sizeof(score2G));
\r
472 memset(score5G, '\0', sizeof(score5G));
\r
474 for (i=0; i<priv->available_chnl_num; i++) {
\r
475 if (priv->available_chnl[i] <= 14)
\r
481 for (i=0; i<priv->available_chnl_num; i++) {
\r
482 if (priv->available_chnl[i] > 14) {
\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
497 score5G[idx - idx_5G_begin] += 5;
\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
511 #ifdef CONFIG_RTL_NEW_AUTOCH
\r
513 u4Byte y, ch_begin=0, ch_end= priv->available_chnl_num;
\r
515 u4Byte do_ap_check = 1, ap_ratio = 0;
\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
522 #ifdef ACS_DEBUG_INFO//for debug
\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
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
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
546 #ifdef _DEBUG_RTL8192CD_
\r
547 printk("!! Not found clean channel, use NHM algorithm\n");
\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
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
569 memcpy(score, tmp_score, sizeof(score));
\r
575 // For each channel, weighting behind channels with MAC RX counter
\r
576 //For each channel, weighting the channel with FA counter
\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
582 if( priv->chnl_ss_mac_rx_count[y] > MAC_RX_COUNT_THRESHOLD )
\r
585 #ifdef RTK_5G_SUPPORT
\r
586 if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G)
\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
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
611 priv->chnl_ss_cca_count[y] = 0;
\r
614 #ifdef ACS_DEBUG_INFO//for debug
\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
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
626 if( priv->chnl_ss_mac_rx_count_40M[y] > MAC_RX_COUNT_THRESHOLD )
\r
629 #ifdef RTK_5G_SUPPORT
\r
630 if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G)
\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
661 #ifdef ACS_DEBUG_INFO//for debug
\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
666 printk("4. do_ap_check=%d traffic_check=%d\n", do_ap_check, traffic_check);
\r
670 if( traffic_check == 0)
\r
671 fa_count_weighting = 5;
\r
673 fa_count_weighting = 1;
\r
675 for (y=ch_begin; y<ch_end; y++) {
\r
676 score[y] += fa_count_weighting * priv->chnl_ss_fa_count[y];
\r
679 #ifdef ACS_DEBUG_INFO//for debug
\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
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
694 printk("chnl[%d] has ap rssi=%d bw[0x%02x]\n",
\r
695 pBss->channel, pBss->rssi, pBss->t_stamp[1]);
\r
698 if (pBss->rssi > 60)
\r
700 else if (pBss->rssi > 35)
\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
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
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
772 if ((pBss->t_stamp[1] & 0x6) == 0) {
\r
775 else if ((pBss->t_stamp[1] & 0x4) == 0) {
\r
777 if ((int)(y+1) < (int)ch_end)
\r
782 if ((int)(y-1) >= (int)ch_begin)
\r
792 #ifdef ACS_DEBUG_INFO//for debug
\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
799 #ifdef SS_CH_LOAD_PROC
\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
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
813 fa_lv = 15 * priv->chnl_ss_fa_count[y] / 100;
\r
815 if (priv->chnl_ss_cca_count[y]>400) {
\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
824 cca_lv = 15 * priv->chnl_ss_cca_count[y] / 40;
\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
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
836 priv->chnl_ss_load[y]);
\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
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
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
871 score[13] = 0xffffffff;
\r
872 score[12] = 0xffffffff;
\r
873 score[11] = 0xffffffff;
\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
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
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
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
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
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
911 if((ch%4) || ch==140 || ch == 164 ) //mask ch 140, ch 165, ch 184...
\r
912 score[i] = 0xffffffff;
\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
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
936 //------------------------------------------------------------------
\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
942 strcat(tmpbuf, "\n");
\r
943 panic_printk("%s", tmpbuf);
\r
947 if ( (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G)
\r
948 && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80))
\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
953 for (j=0; j<4; j++) {
\r
954 if ((tmpScore != 0xffffffff) && (score[i+j] != 0xffffffff))
\r
955 tmpScore += score[i+j];
\r
957 tmpScore = 0xffffffff;
\r
959 tmpScore = tmpScore / 4;
\r
960 if (minScore > tmpScore) {
\r
961 minScore = tmpScore;
\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
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
987 else if( (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G)
\r
988 && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40))
\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
994 if ((tmpScore != 0xffffffff) && (score[i+j] != 0xffffffff))
\r
995 tmpScore += score[i+j];
\r
997 tmpScore = 0xffffffff;
\r
999 tmpScore = tmpScore / 2;
\r
1000 if(minScore > tmpScore) {
\r
1001 minScore = tmpScore;
\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
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
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
1031 u4Byte groupScore[14];
\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
1042 if(priv->available_chnl[i]==1 || priv->available_chnl[i]==6 || priv->available_chnl[i]==11)
\r
1044 minScore = groupScore[i];
\r
1051 minScore = groupScore[i];
\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
1063 GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;
\r
1064 priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW;
\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
1074 if(priv->available_chnl[i]==1 || priv->available_chnl[i]==6 || priv->available_chnl[i]==11)
\r
1076 minScore = score[i];
\r
1083 minScore = score[i];
\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
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
1110 minChan = priv->available_chnl[idx];
\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
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
1124 minChan = priv->available_chnl[idx];
\r
1128 //Check if selected channel available for 80M/40M BW or NOT ?
\r
1129 if(priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G)
\r
1131 if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80)
\r
1133 if(!is80MChannel(priv->available_chnl,priv->available_chnl_num,minChan))
\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
1141 if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40)
\r
1143 if(!is40MChannel(priv->available_chnl,priv->available_chnl_num,minChan))
\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
1153 #ifdef CONFIG_RTL_NEW_AUTOCH
\r
1154 RTL_W32(RXERR_RPT, RXERR_RPT_RST);
\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
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
1167 GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;
\r
1168 priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW;
\r
1175 #ifdef CONFIG_RTL_NEW_AUTOCH
\r
1176 unsigned int ch_max;
\r
1178 if (priv->available_chnl[idx_2G_end] >= 13)
\r
1181 ch_max = priv->available_chnl[idx_2G_end];
\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
1188 GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;
\r
1189 priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE;
\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
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
1206 //-----------------------
\r
1208 #if defined(__ECOS) && defined(CONFIG_SDIO_HCI)
\r
1209 panic_printk("Auto channel choose ch:%d\n", minChan);
\r
1211 #ifdef _DEBUG_RTL8192CD_
\r
1212 panic_printk("Auto channel choose ch:%d\n", minChan);
\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