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
25 #include "../odm_precomp.h"
\r
27 #if (RTL8188E_SUPPORT == 1)
\r
30 ODM_DIG_LowerBound_88E(
\r
31 IN PDM_ODM_T pDM_Odm
\r
34 pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable;
\r
36 if(pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV)
\r
38 pDM_DigTable->rx_gain_range_min = (u1Byte) pDM_DigTable->AntDiv_RSSI_max;
\r
39 ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_DIG_LowerBound_88E(): pDM_DigTable->AntDiv_RSSI_max=%d \n",pDM_DigTable->AntDiv_RSSI_max));
\r
41 //If only one Entry connected
\r
45 //3============================================================
\r
46 //3 Dynamic Primary CCA
\r
47 //3============================================================
\r
50 odm_PrimaryCCA_Init(
\r
51 IN PDM_ODM_T pDM_Odm)
\r
53 pPri_CCA_T PrimaryCCA = &(pDM_Odm->DM_PriCCA);
\r
54 PrimaryCCA->DupRTS_flag = 0;
\r
55 PrimaryCCA->intf_flag = 0;
\r
56 PrimaryCCA->intf_type = 0;
\r
57 PrimaryCCA->Monitor_flag = 0;
\r
58 PrimaryCCA->PriCCA_flag = 0;
\r
62 ODM_DynamicPrimaryCCA_DupRTS(
\r
63 IN PDM_ODM_T pDM_Odm
\r
66 pPri_CCA_T PrimaryCCA = &(pDM_Odm->DM_PriCCA);
\r
68 return PrimaryCCA->DupRTS_flag;
\r
72 odm_DynamicPrimaryCCA(
\r
73 IN PDM_ODM_T pDM_Odm
\r
76 PADAPTER Adapter = pDM_Odm->Adapter; // for NIC
\r
78 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN))
\r
79 PRT_WLAN_STA pEntry;
\r
82 PFALSE_ALARM_STATISTICS FalseAlmCnt = &(pDM_Odm->FalseAlmCnt);
\r
83 pPri_CCA_T PrimaryCCA = &(pDM_Odm->DM_PriCCA);
\r
86 BOOLEAN Client_40MHz = FALSE, Client_tmp = FALSE; // connected client BW
\r
87 BOOLEAN bConnected = FALSE; // connected or not
\r
88 static u1Byte Client_40MHz_pre = 0;
\r
89 static u8Byte lastTxOkCnt = 0;
\r
90 static u8Byte lastRxOkCnt = 0;
\r
91 static u4Byte Counter = 0;
\r
92 static u1Byte Delay = 1;
\r
98 #if((DM_ODM_SUPPORT_TYPE==ODM_ADSL) ||( DM_ODM_SUPPORT_TYPE==ODM_CE))
\r
102 if(pDM_Odm->SupportICType != ODM_RTL8188E)
\r
105 Is40MHz = *(pDM_Odm->pBandWidth);
\r
106 SecCHOffset = *(pDM_Odm->pSecChOffset);
\r
107 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("Second CH Offset = %d\n", SecCHOffset));
\r
109 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
\r
111 SecCHOffset = SecCHOffset%2+1; // NIC's definition is reverse to AP 1:secondary below, 2: secondary above
\r
112 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("Second CH Offset = %d\n", SecCHOffset));
\r
113 //3 Check Current WLAN Traffic
\r
114 curTxOkCnt = Adapter->TxStats.NumTxBytesUnicast - lastTxOkCnt;
\r
115 curRxOkCnt = Adapter->RxStats.NumRxBytesUnicast - lastRxOkCnt;
\r
116 lastTxOkCnt = Adapter->TxStats.NumTxBytesUnicast;
\r
117 lastRxOkCnt = Adapter->RxStats.NumRxBytesUnicast;
\r
118 #elif (DM_ODM_SUPPORT_TYPE == ODM_AP)
\r
119 //3 Check Current WLAN Traffic
\r
120 curTxOkCnt = *(pDM_Odm->pNumTxBytesUnicast)-lastTxOkCnt;
\r
121 curRxOkCnt = *(pDM_Odm->pNumRxBytesUnicast)-lastRxOkCnt;
\r
122 lastTxOkCnt = *(pDM_Odm->pNumTxBytesUnicast);
\r
123 lastRxOkCnt = *(pDM_Odm->pNumRxBytesUnicast);
\r
126 //==================Debug Message====================
\r
127 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("TP = %llu\n", curTxOkCnt+curRxOkCnt));
\r
128 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("Is40MHz = %d\n", Is40MHz));
\r
129 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("BW_LSC = %d\n", FalseAlmCnt->Cnt_BW_LSC));
\r
130 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("BW_USC = %d\n", FalseAlmCnt->Cnt_BW_USC));
\r
131 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("CCA OFDM = %d\n", FalseAlmCnt->Cnt_OFDM_CCA));
\r
132 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("CCA CCK = %d\n", FalseAlmCnt->Cnt_CCK_CCA));
\r
133 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("OFDM FA = %d\n", FalseAlmCnt->Cnt_Ofdm_fail));
\r
134 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("CCK FA = %d\n", FalseAlmCnt->Cnt_Cck_fail));
\r
135 //================================================
\r
137 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
\r
138 if (ACTING_AS_AP(Adapter)) // primary cca process only do at AP mode
\r
142 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
\r
143 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("ACTING as AP mode=%d\n", ACTING_AS_AP(Adapter)));
\r
144 //3 To get entry's connection and BW infomation status.
\r
145 for(i=0;i<ASSOCIATE_ENTRY_NUM;i++)
\r
147 if(IsAPModeExist(Adapter)&&GetFirstExtAdapter(Adapter)!=NULL)
\r
148 pEntry=AsocEntry_EnumStation(GetFirstExtAdapter(Adapter), i);
\r
150 pEntry=AsocEntry_EnumStation(GetDefaultAdapter(Adapter), i);
\r
153 Client_tmp = pEntry->BandWidth; // client BW
\r
154 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("Client_BW=%d\n", Client_tmp));
\r
155 if(Client_tmp>Client_40MHz)
\r
156 Client_40MHz = Client_tmp; // 40M/20M coexist => 40M priority is High
\r
158 if(pEntry->bAssociated)
\r
160 bConnected=TRUE; // client is connected or not
\r
169 #elif (DM_ODM_SUPPORT_TYPE == ODM_AP)
\r
170 //3 To get entry's connection and BW infomation status.
\r
174 for(i=0; i<ODM_ASSOCIATE_ENTRY_NUM; i++)
\r
176 pstat = pDM_Odm->pODM_StaInfo[i];
\r
177 if(IS_STA_VALID(pstat) )
\r
179 Client_tmp = pstat->tx_bw;
\r
180 if(Client_tmp>Client_40MHz)
\r
181 Client_40MHz = Client_tmp; // 40M/20M coexist => 40M priority is High
\r
187 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("bConnected=%d\n", bConnected));
\r
188 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("Is Client 40MHz=%d\n", Client_40MHz));
\r
189 //1 Monitor whether the interference exists or not
\r
190 if(PrimaryCCA->Monitor_flag == 1)
\r
192 if(SecCHOffset == 1) // secondary channel is below the primary channel
\r
194 if((FalseAlmCnt->Cnt_OFDM_CCA > 500)&&(FalseAlmCnt->Cnt_BW_LSC > FalseAlmCnt->Cnt_BW_USC+500))
\r
196 if(FalseAlmCnt->Cnt_Ofdm_fail > FalseAlmCnt->Cnt_OFDM_CCA>>1)
\r
198 PrimaryCCA->intf_type = 1;
\r
199 PrimaryCCA->PriCCA_flag = 1;
\r
200 ODM_SetBBReg(pDM_Odm, 0xc6c, BIT8|BIT7, 2); // USC MF
\r
201 if(PrimaryCCA->DupRTS_flag == 1)
\r
202 PrimaryCCA->DupRTS_flag = 0;
\r
206 PrimaryCCA->intf_type = 2;
\r
207 if(PrimaryCCA->DupRTS_flag == 0)
\r
208 PrimaryCCA->DupRTS_flag = 1;
\r
212 else // interferecne disappear
\r
214 PrimaryCCA->DupRTS_flag = 0;
\r
215 PrimaryCCA->intf_flag = 0;
\r
216 PrimaryCCA->intf_type = 0;
\r
219 else if(SecCHOffset == 2) // secondary channel is above the primary channel
\r
221 if((FalseAlmCnt->Cnt_OFDM_CCA > 500)&&(FalseAlmCnt->Cnt_BW_USC > FalseAlmCnt->Cnt_BW_LSC+500))
\r
223 if(FalseAlmCnt->Cnt_Ofdm_fail > FalseAlmCnt->Cnt_OFDM_CCA>>1)
\r
225 PrimaryCCA->intf_type = 1;
\r
226 PrimaryCCA->PriCCA_flag = 1;
\r
227 ODM_SetBBReg(pDM_Odm, 0xc6c, BIT8|BIT7, 1); // LSC MF
\r
228 if(PrimaryCCA->DupRTS_flag == 1)
\r
229 PrimaryCCA->DupRTS_flag = 0;
\r
233 PrimaryCCA->intf_type = 2;
\r
234 if(PrimaryCCA->DupRTS_flag == 0)
\r
235 PrimaryCCA->DupRTS_flag = 1;
\r
239 else // interferecne disappear
\r
241 PrimaryCCA->DupRTS_flag = 0;
\r
242 PrimaryCCA->intf_flag = 0;
\r
243 PrimaryCCA->intf_type = 0;
\r
248 PrimaryCCA->Monitor_flag = 0;
\r
251 //1 Dynamic Primary CCA Main Function
\r
252 if(PrimaryCCA->Monitor_flag == 0)
\r
254 if(Is40MHz) // if RFBW==40M mode which require to process primary cca
\r
256 //2 STA is NOT Connected
\r
259 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("STA NOT Connected!!!!\n"));
\r
261 if(PrimaryCCA->PriCCA_flag == 1) // reset primary cca when STA is disconnected
\r
263 PrimaryCCA->PriCCA_flag = 0;
\r
264 ODM_SetBBReg(pDM_Odm, 0xc6c, BIT8|BIT7, 0);
\r
266 if(PrimaryCCA->DupRTS_flag == 1) // reset Duplicate RTS when STA is disconnected
\r
267 PrimaryCCA->DupRTS_flag = 0;
\r
269 if(SecCHOffset == 1) // secondary channel is below the primary channel
\r
271 if((FalseAlmCnt->Cnt_OFDM_CCA > 800)&&(FalseAlmCnt->Cnt_BW_LSC*5 > FalseAlmCnt->Cnt_BW_USC*9))
\r
273 PrimaryCCA->intf_flag = 1; // secondary channel interference is detected!!!
\r
274 if(FalseAlmCnt->Cnt_Ofdm_fail > FalseAlmCnt->Cnt_OFDM_CCA>>1)
\r
275 PrimaryCCA->intf_type = 1; // interference is shift
\r
277 PrimaryCCA->intf_type = 2; // interference is in-band
\r
281 PrimaryCCA->intf_flag = 0;
\r
282 PrimaryCCA->intf_type = 0;
\r
285 else if(SecCHOffset == 2) // secondary channel is above the primary channel
\r
287 if((FalseAlmCnt->Cnt_OFDM_CCA > 800)&&(FalseAlmCnt->Cnt_BW_USC*5 > FalseAlmCnt->Cnt_BW_LSC*9))
\r
289 PrimaryCCA->intf_flag = 1; // secondary channel interference is detected!!!
\r
290 if(FalseAlmCnt->Cnt_Ofdm_fail > FalseAlmCnt->Cnt_OFDM_CCA>>1)
\r
291 PrimaryCCA->intf_type = 1; // interference is shift
\r
293 PrimaryCCA->intf_type = 2; // interference is in-band
\r
297 PrimaryCCA->intf_flag = 0;
\r
298 PrimaryCCA->intf_type = 0;
\r
301 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("PrimaryCCA=%d\n",PrimaryCCA->PriCCA_flag));
\r
302 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("Intf_Type=%d\n", PrimaryCCA->intf_type));
\r
304 //2 STA is Connected
\r
307 if(Client_40MHz == 0) //3 // client BW = 20MHz
\r
309 if(PrimaryCCA->PriCCA_flag == 0)
\r
311 PrimaryCCA->PriCCA_flag = 1;
\r
313 ODM_SetBBReg(pDM_Odm, 0xc6c, BIT8|BIT7, 2);
\r
314 else if(SecCHOffset==2)
\r
315 ODM_SetBBReg(pDM_Odm, 0xc6c, BIT8|BIT7, 1);
\r
317 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("STA Connected 20M!!! PrimaryCCA=%d\n", PrimaryCCA->PriCCA_flag));
\r
319 else //3 // client BW = 40MHz
\r
321 if(PrimaryCCA->intf_flag == 1) // interference is detected!!
\r
323 if(PrimaryCCA->intf_type == 1)
\r
325 if(PrimaryCCA->PriCCA_flag!=1)
\r
327 PrimaryCCA->PriCCA_flag = 1;
\r
329 ODM_SetBBReg(pDM_Odm, 0xc6c, BIT8|BIT7, 2);
\r
330 else if(SecCHOffset==2)
\r
331 ODM_SetBBReg(pDM_Odm, 0xc6c, BIT8|BIT7, 1);
\r
334 else if(PrimaryCCA->intf_type == 2)
\r
336 if(PrimaryCCA->DupRTS_flag!=1)
\r
337 PrimaryCCA->DupRTS_flag = 1;
\r
340 else // if intf_flag==0
\r
342 if((curTxOkCnt+curRxOkCnt)<10000) //idle mode or TP traffic is very low
\r
344 if(SecCHOffset == 1)
\r
346 if((FalseAlmCnt->Cnt_OFDM_CCA > 800)&&(FalseAlmCnt->Cnt_BW_LSC*5 > FalseAlmCnt->Cnt_BW_USC*9))
\r
348 PrimaryCCA->intf_flag = 1;
\r
349 if(FalseAlmCnt->Cnt_Ofdm_fail > FalseAlmCnt->Cnt_OFDM_CCA>>1)
\r
350 PrimaryCCA->intf_type = 1; // interference is shift
\r
352 PrimaryCCA->intf_type = 2; // interference is in-band
\r
355 else if(SecCHOffset == 2)
\r
357 if((FalseAlmCnt->Cnt_OFDM_CCA > 800)&&(FalseAlmCnt->Cnt_BW_USC*5 > FalseAlmCnt->Cnt_BW_LSC*9))
\r
359 PrimaryCCA->intf_flag = 1;
\r
360 if(FalseAlmCnt->Cnt_Ofdm_fail > FalseAlmCnt->Cnt_OFDM_CCA>>1)
\r
361 PrimaryCCA->intf_type = 1; // interference is shift
\r
363 PrimaryCCA->intf_type = 2; // interference is in-band
\r
368 else // TP Traffic is High
\r
370 if(SecCHOffset == 1)
\r
372 if(FalseAlmCnt->Cnt_BW_LSC > (FalseAlmCnt->Cnt_BW_USC+500))
\r
374 if(Delay == 0) // add delay to avoid interference occurring abruptly, jump one time
\r
376 PrimaryCCA->intf_flag = 1;
\r
377 if(FalseAlmCnt->Cnt_Ofdm_fail > FalseAlmCnt->Cnt_OFDM_CCA>>1)
\r
378 PrimaryCCA->intf_type = 1; // interference is shift
\r
380 PrimaryCCA->intf_type = 2; // interference is in-band
\r
387 else if(SecCHOffset == 2)
\r
389 if(FalseAlmCnt->Cnt_BW_USC > (FalseAlmCnt->Cnt_BW_LSC+500))
\r
391 if(Delay == 0) // add delay to avoid interference occurring abruptly
\r
393 PrimaryCCA->intf_flag = 1;
\r
394 if(FalseAlmCnt->Cnt_Ofdm_fail > FalseAlmCnt->Cnt_OFDM_CCA>>1)
\r
395 PrimaryCCA->intf_type = 1; // interference is shift
\r
397 PrimaryCCA->intf_type = 2; // interference is in-band
\r
406 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("Primary CCA=%d\n", PrimaryCCA->PriCCA_flag));
\r
407 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("Duplicate RTS=%d\n", PrimaryCCA->DupRTS_flag));
\r
410 }// end of connected
\r
413 //1 Dynamic Primary CCA Monitor Counter
\r
414 if((PrimaryCCA->PriCCA_flag == 1)||(PrimaryCCA->DupRTS_flag == 1))
\r
416 if(Client_40MHz == 0) // client=20M no need to monitor primary cca flag
\r
418 Client_40MHz_pre = Client_40MHz;
\r
422 ODM_RT_TRACE(pDM_Odm,ODM_COMP_DYNAMIC_PRICCA, ODM_DBG_LOUD, ("Counter=%d\n", Counter));
\r
423 if((Counter == 30)||((Client_40MHz -Client_40MHz_pre)==1)) // Every 60 sec to monitor one time
\r
425 PrimaryCCA->Monitor_flag = 1; // monitor flag is triggered!!!!!
\r
426 if(PrimaryCCA->PriCCA_flag == 1)
\r
428 PrimaryCCA->PriCCA_flag = 0;
\r
429 ODM_SetBBReg(pDM_Odm, 0xc6c, BIT8|BIT7, 0);
\r
436 Client_40MHz_pre = Client_40MHz;
\r
438 #else //#if (RTL8188E_SUPPORT == 1)
\r
441 odm_PrimaryCCA_Init(
\r
442 IN PDM_ODM_T pDM_Odm)
\r
446 odm_DynamicPrimaryCCA(
\r
447 IN PDM_ODM_T pDM_Odm
\r
452 ODM_DynamicPrimaryCCA_DupRTS(
\r
453 IN PDM_ODM_T pDM_Odm
\r
458 #endif //#if (RTL8188E_SUPPORT == 1)
\r