Merge Trond's bugfixes
[cascardo/linux.git] / drivers / staging / vt6655 / bssdb.c
1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * File: bssdb.c
20  *
21  * Purpose: Handles the Basic Service Set & Node Database functions
22  *
23  * Functions:
24  *      BSSpSearchBSSList - Search known BSS list for Desire SSID or BSSID
25  *      BSSvClearBSSList - Clear BSS List
26  *      BSSbInsertToBSSList - Insert a BSS set into known BSS list
27  *      BSSbUpdateToBSSList - Update BSS set in known BSS list
28  *      BSSDBbIsSTAInNodeDB - Search Node DB table to find the index of matched DstAddr
29  *      BSSvCreateOneNode - Allocate an Node for Node DB
30  *      BSSvUpdateAPNode - Update AP Node content in Index 0 of KnownNodeDB
31  *      BSSvSecondCallBack - One second timer callback function to update Node DB info & AP link status
32  *      BSSvUpdateNodeTxCounter - Update Tx attemps, Tx failure counter in Node DB for auto-fall back rate control
33  *
34  * Revision History:
35  *
36  * Author: Lyndon Chen
37  *
38  * Date: July 17, 2002
39  *
40  */
41
42 #include "ttype.h"
43 #include "tmacro.h"
44 #include "tether.h"
45 #include "device.h"
46 #include "80211hdr.h"
47 #include "bssdb.h"
48 #include "wmgr.h"
49 #include "datarate.h"
50 #include "desc.h"
51 #include "wcmd.h"
52 #include "wpa.h"
53 #include "baseband.h"
54 #include "rf.h"
55 #include "card.h"
56 #include "channel.h"
57 #include "mac.h"
58 #include "wpa2.h"
59 #include "iowpa.h"
60
61 /*---------------------  Static Definitions -------------------------*/
62
63
64
65
66 /*---------------------  Static Classes  ----------------------------*/
67
68 /*---------------------  Static Variables  --------------------------*/
69 static int          msglevel                =MSG_LEVEL_INFO;
70 //static int          msglevel                =MSG_LEVEL_DEBUG;
71
72
73
74 const unsigned short awHWRetry0[5][5] = {
75                                             {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
76                                             {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M},
77                                             {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M},
78                                             {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M},
79                                             {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M}
80                                            };
81 const unsigned short awHWRetry1[5][5] = {
82                                             {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M},
83                                             {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M},
84                                             {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M},
85                                             {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M},
86                                             {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M}
87                                            };
88
89
90
91 /*---------------------  Static Functions  --------------------------*/
92
93 void s_vCheckSensitivity(
94     void *hDeviceContext
95     );
96
97 #ifdef Calcu_LinkQual
98 void s_uCalculateLinkQual(
99     void *hDeviceContext
100     );
101 #endif
102
103
104 void s_vCheckPreEDThreshold(
105     void *hDeviceContext
106     );
107 /*---------------------  Export Variables  --------------------------*/
108
109
110 /*---------------------  Export Functions  --------------------------*/
111
112
113
114
115
116 /*+
117  *
118  * Routine Description:
119  *    Search known BSS list for Desire SSID or BSSID.
120  *
121  * Return Value:
122  *    PTR to KnownBSS or NULL
123  *
124 -*/
125
126 PKnownBSS
127 BSSpSearchBSSList(
128     void *hDeviceContext,
129     unsigned char *pbyDesireBSSID,
130     unsigned char *pbyDesireSSID,
131     CARD_PHY_TYPE  ePhyType
132     )
133 {
134     PSDevice        pDevice = (PSDevice)hDeviceContext;
135     PSMgmtObject    pMgmt = pDevice->pMgmt;
136     unsigned char *pbyBSSID = NULL;
137     PWLAN_IE_SSID   pSSID = NULL;
138     PKnownBSS       pCurrBSS = NULL;
139     PKnownBSS       pSelect = NULL;
140     unsigned char ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
141     unsigned int ii = 0;
142
143     if (pbyDesireBSSID != NULL) {
144                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
145                         "BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID);
146         if ((!is_broadcast_ether_addr(pbyDesireBSSID)) &&
147              (memcmp(pbyDesireBSSID, ZeroBSSID, 6)!= 0)){
148             pbyBSSID = pbyDesireBSSID;
149         }
150     }
151     if (pbyDesireSSID != NULL) {
152         if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) {
153             pSSID = (PWLAN_IE_SSID) pbyDesireSSID;
154         }
155     }
156
157     if (pbyBSSID != NULL) {
158         // match BSSID first
159         for (ii = 0; ii <MAX_BSS_NUM; ii++) {
160             pCurrBSS = &(pMgmt->sBSSList[ii]);
161 if(pDevice->bLinkPass==false) pCurrBSS->bSelected = false;
162             if ((pCurrBSS->bActive) &&
163                 (pCurrBSS->bSelected == false)) {
164                 if (!compare_ether_addr(pCurrBSS->abyBSSID, pbyBSSID)) {
165                     if (pSSID != NULL) {
166                         // compare ssid
167                         if ( !memcmp(pSSID->abySSID,
168                             ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
169                             pSSID->len)) {
170                             if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) ||
171                                 ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
172                                 ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
173                                 ) {
174                                 pCurrBSS->bSelected = true;
175                                 return(pCurrBSS);
176                             }
177                         }
178                     } else {
179                         if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) ||
180                             ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
181                             ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
182                             ) {
183                             pCurrBSS->bSelected = true;
184                             return(pCurrBSS);
185                         }
186                     }
187                 }
188             }
189         }
190     } else {
191         // ignore BSSID
192         for (ii = 0; ii <MAX_BSS_NUM; ii++) {
193             pCurrBSS = &(pMgmt->sBSSList[ii]);
194         //2007-0721-01<Add>by MikeLiu
195           pCurrBSS->bSelected = false;
196           if (pCurrBSS->bActive) {
197
198                 if (pSSID != NULL) {
199                     // matched SSID
200                     if (! !memcmp(pSSID->abySSID,
201                         ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
202                         pSSID->len) ||
203                         (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) {
204                         // SSID not match skip this BSS
205                         continue;
206                       }
207                 }
208                 if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) ||
209                     ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo))
210                     ){
211                     // Type not match skip this BSS
212                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo);
213                     continue;
214                 }
215
216                 if (ePhyType != PHY_TYPE_AUTO) {
217                     if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) ||
218                         ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) {
219                         // PhyType not match skip this BSS
220                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse);
221                         continue;
222                     }
223                 }
224 /*
225                 if (pMgmt->eAuthenMode < WMAC_AUTH_WPA) {
226                     if (pCurrBSS->bWPAValid == true) {
227                         // WPA AP will reject connection of station without WPA enable.
228                         continue;
229                     }
230                 } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
231                            (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
232                     if (pCurrBSS->bWPAValid == false) {
233                         // station with WPA enable can't join NonWPA AP.
234                         continue;
235                     }
236                 } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
237                            (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
238                     if (pCurrBSS->bWPA2Valid == false) {
239                         // station with WPA2 enable can't join NonWPA2 AP.
240                         continue;
241                     }
242                 }
243 */
244                 if (pSelect == NULL) {
245                     pSelect = pCurrBSS;
246                 } else {
247                     // compare RSSI, select signal strong one
248                     if (pCurrBSS->uRSSI < pSelect->uRSSI) {
249                         pSelect = pCurrBSS;
250                     }
251                 }
252             }
253         }
254         if (pSelect != NULL) {
255             pSelect->bSelected = true;
256 /*
257                         if (pDevice->bRoaming == false)  {
258         //       Einsn Add @20070907
259                         memset(pbyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
260                         memcpy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1) ;
261                                                 }*/
262
263             return(pSelect);
264         }
265     }
266     return(NULL);
267
268 }
269
270
271 /*+
272  *
273  * Routine Description:
274  *    Clear BSS List
275  *
276  * Return Value:
277  *    None.
278  *
279 -*/
280
281
282 void
283 BSSvClearBSSList(
284     void *hDeviceContext,
285     bool bKeepCurrBSSID
286     )
287 {
288     PSDevice     pDevice = (PSDevice)hDeviceContext;
289     PSMgmtObject    pMgmt = pDevice->pMgmt;
290     unsigned int ii;
291
292     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
293         if (bKeepCurrBSSID) {
294             if (pMgmt->sBSSList[ii].bActive &&
295                 !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) {
296                // bKeepCurrBSSID = false;
297                 continue;
298             }
299         }
300
301         if ((pMgmt->sBSSList[ii].bActive) && (pMgmt->sBSSList[ii].uClearCount < BSS_CLEAR_COUNT)) {
302              pMgmt->sBSSList[ii].uClearCount ++;
303              continue;
304         }
305
306         pMgmt->sBSSList[ii].bActive = false;
307         memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS));
308     }
309     BSSvClearAnyBSSJoinRecord(pDevice);
310
311     return;
312 }
313
314
315
316 /*+
317  *
318  * Routine Description:
319  *    search BSS list by BSSID & SSID if matched
320  *
321  * Return Value:
322  *    true if found.
323  *
324 -*/
325 PKnownBSS
326 BSSpAddrIsInBSSList(
327     void *hDeviceContext,
328     unsigned char *abyBSSID,
329     PWLAN_IE_SSID pSSID
330     )
331 {
332     PSDevice     pDevice = (PSDevice)hDeviceContext;
333     PSMgmtObject    pMgmt = pDevice->pMgmt;
334     PKnownBSS       pBSSList = NULL;
335     unsigned int ii;
336
337     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
338         pBSSList = &(pMgmt->sBSSList[ii]);
339         if (pBSSList->bActive) {
340             if (!compare_ether_addr(pBSSList->abyBSSID, abyBSSID)) {
341 //                if (pSSID == NULL)
342 //                    return pBSSList;
343                 if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len){
344                     if (memcmp(pSSID->abySSID,
345                             ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
346                             pSSID->len) == 0)
347                         return pBSSList;
348                 }
349             }
350         }
351     }
352
353     return NULL;
354 };
355
356
357
358 /*+
359  *
360  * Routine Description:
361  *    Insert a BSS set into known BSS list
362  *
363  * Return Value:
364  *    true if success.
365  *
366 -*/
367
368 bool
369 BSSbInsertToBSSList (
370     void *hDeviceContext,
371     unsigned char *abyBSSIDAddr,
372     QWORD qwTimestamp,
373     unsigned short wBeaconInterval,
374     unsigned short wCapInfo,
375     unsigned char byCurrChannel,
376     PWLAN_IE_SSID pSSID,
377     PWLAN_IE_SUPP_RATES pSuppRates,
378     PWLAN_IE_SUPP_RATES pExtSuppRates,
379     PERPObject psERP,
380     PWLAN_IE_RSN pRSN,
381     PWLAN_IE_RSN_EXT pRSNWPA,
382     PWLAN_IE_COUNTRY pIE_Country,
383     PWLAN_IE_QUIET pIE_Quiet,
384     unsigned int uIELength,
385     unsigned char *pbyIEs,
386     void *pRxPacketContext
387     )
388 {
389
390     PSDevice     pDevice = (PSDevice)hDeviceContext;
391     PSMgmtObject    pMgmt = pDevice->pMgmt;
392     PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
393     PKnownBSS       pBSSList = NULL;
394     unsigned int ii;
395     bool bParsingQuiet = false;
396     PWLAN_IE_QUIET  pQuiet = NULL;
397
398
399
400     pBSSList = (PKnownBSS)&(pMgmt->sBSSList[0]);
401
402     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
403         pBSSList = (PKnownBSS)&(pMgmt->sBSSList[ii]);
404         if (!pBSSList->bActive)
405                 break;
406     }
407
408     if (ii == MAX_BSS_NUM){
409         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n");
410         return false;
411     }
412     // save the BSS info
413     pBSSList->bActive = true;
414     memcpy( pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN);
415     HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
416     LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp));
417     pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
418     pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
419     pBSSList->uClearCount = 0;
420
421     if (pSSID->len > WLAN_SSID_MAXLEN)
422         pSSID->len = WLAN_SSID_MAXLEN;
423     memcpy( pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
424
425     pBSSList->uChannel = byCurrChannel;
426
427     if (pSuppRates->len > WLAN_RATES_MAXLEN)
428         pSuppRates->len = WLAN_RATES_MAXLEN;
429     memcpy( pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN);
430
431     if (pExtSuppRates != NULL) {
432         if (pExtSuppRates->len > WLAN_RATES_MAXLEN)
433             pExtSuppRates->len = WLAN_RATES_MAXLEN;
434         memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN);
435         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates->len);
436
437     } else {
438         memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
439     }
440     pBSSList->sERP.byERP = psERP->byERP;
441     pBSSList->sERP.bERPExist = psERP->bERPExist;
442
443     // Check if BSS is 802.11a/b/g
444     if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
445         pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
446     } else {
447         if (pBSSList->sERP.bERPExist == true) {
448             pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
449         } else {
450             pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
451         }
452     }
453
454     pBSSList->byRxRate = pRxPacket->byRxRate;
455     pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF;
456     pBSSList->uRSSI = pRxPacket->uRSSI;
457     pBSSList->bySQ = pRxPacket->bySQ;
458
459    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
460         (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
461         // assoc with BSS
462         if (pBSSList == pMgmt->pCurrBSS) {
463             bParsingQuiet = true;
464         }
465     }
466
467     WPA_ClearRSN(pBSSList);
468
469     if (pRSNWPA != NULL) {
470         unsigned int uLen = pRSNWPA->len + 2;
471
472         if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) {
473             pBSSList->wWPALen = uLen;
474             memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
475             WPA_ParseRSN(pBSSList, pRSNWPA);
476         }
477     }
478
479     WPA2_ClearRSN(pBSSList);
480
481     if (pRSN != NULL) {
482         unsigned int uLen = pRSN->len + 2;
483         if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) {
484             pBSSList->wRSNLen = uLen;
485             memcpy(pBSSList->byRSNIE, pRSN, uLen);
486             WPA2vParseRSN(pBSSList, pRSN);
487         }
488     }
489
490     if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pBSSList->bWPA2Valid == true)) {
491
492         PSKeyItem  pTransmitKey = NULL;
493         bool bIs802_1x = false;
494
495         for (ii = 0; ii < pBSSList->wAKMSSAuthCount; ii ++) {
496             if (pBSSList->abyAKMSSAuthType[ii] == WLAN_11i_AKMSS_802_1X) {
497                 bIs802_1x = true;
498                 break;
499             }
500         }
501         if ((bIs802_1x == true) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) &&
502             ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) {
503
504             bAdd_PMKID_Candidate((void *)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj);
505
506             if ((pDevice->bLinkPass == true) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
507                 if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) ||
508                     (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey) == true)) {
509                     pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList;
510                     pDevice->gsPMKIDCandidate.Version = 1;
511
512                 }
513
514             }
515         }
516     }
517
518     if (pDevice->bUpdateBBVGA) {
519         // Moniter if RSSI is too strong.
520         pBSSList->byRSSIStatCnt = 0;
521         RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &pBSSList->ldBmMAX);
522         pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX;
523         for (ii = 1; ii < RSSI_STAT_COUNT; ii++)
524             pBSSList->ldBmAverage[ii] = 0;
525     }
526
527     if ((pIE_Country != NULL) &&
528         (pMgmt->b11hEnable == true)) {
529         set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse,
530                             pIE_Country);
531     }
532
533     if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) {
534         if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
535             (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
536             // valid EID
537             if (pQuiet == NULL) {
538                 pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
539                 CARDbSetQuiet(  pMgmt->pAdapter,
540                                 true,
541                                 pQuiet->byQuietCount,
542                                 pQuiet->byQuietPeriod,
543                                 *((unsigned short *)pQuiet->abyQuietDuration),
544                                 *((unsigned short *)pQuiet->abyQuietOffset)
545                                 );
546             } else {
547                 pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
548                 CARDbSetQuiet(  pMgmt->pAdapter,
549                                 false,
550                                 pQuiet->byQuietCount,
551                                 pQuiet->byQuietPeriod,
552                                 *((unsigned short *)pQuiet->abyQuietDuration),
553                                 *((unsigned short *)pQuiet->abyQuietOffset)
554                                 );
555             }
556         }
557     }
558
559     if ((bParsingQuiet == true) &&
560         (pQuiet != NULL)) {
561         CARDbStartQuiet(pMgmt->pAdapter);
562     }
563
564     pBSSList->uIELength = uIELength;
565     if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
566         pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
567     memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
568
569     return true;
570 }
571
572
573 /*+
574  *
575  * Routine Description:
576  *    Update BSS set in known BSS list
577  *
578  * Return Value:
579  *    true if success.
580  *
581 -*/
582 // TODO: input structure modify
583
584 bool
585 BSSbUpdateToBSSList (
586     void *hDeviceContext,
587     QWORD qwTimestamp,
588     unsigned short wBeaconInterval,
589     unsigned short wCapInfo,
590     unsigned char byCurrChannel,
591     bool bChannelHit,
592     PWLAN_IE_SSID pSSID,
593     PWLAN_IE_SUPP_RATES pSuppRates,
594     PWLAN_IE_SUPP_RATES pExtSuppRates,
595     PERPObject psERP,
596     PWLAN_IE_RSN pRSN,
597     PWLAN_IE_RSN_EXT pRSNWPA,
598     PWLAN_IE_COUNTRY pIE_Country,
599     PWLAN_IE_QUIET pIE_Quiet,
600     PKnownBSS pBSSList,
601     unsigned int uIELength,
602     unsigned char *pbyIEs,
603     void *pRxPacketContext
604     )
605 {
606     int             ii;
607     PSDevice        pDevice = (PSDevice)hDeviceContext;
608     PSMgmtObject    pMgmt = pDevice->pMgmt;
609     PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
610     long            ldBm;
611     bool bParsingQuiet = false;
612     PWLAN_IE_QUIET  pQuiet = NULL;
613
614
615
616     if (pBSSList == NULL)
617         return false;
618
619
620     HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
621     LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp));
622     pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
623     pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
624     pBSSList->uClearCount = 0;
625     pBSSList->uChannel = byCurrChannel;
626 //    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbUpdateToBSSList: pBSSList->uChannel: %d\n", pBSSList->uChannel);
627
628     if (pSSID->len > WLAN_SSID_MAXLEN)
629         pSSID->len = WLAN_SSID_MAXLEN;
630
631     if ((pSSID->len != 0) && (pSSID->abySSID[0] != 0))
632         memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
633     memcpy(pBSSList->abySuppRates, pSuppRates,pSuppRates->len + WLAN_IEHDR_LEN);
634
635     if (pExtSuppRates != NULL) {
636         memcpy(pBSSList->abyExtSuppRates, pExtSuppRates,pExtSuppRates->len + WLAN_IEHDR_LEN);
637     } else {
638         memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
639     }
640     pBSSList->sERP.byERP = psERP->byERP;
641     pBSSList->sERP.bERPExist = psERP->bERPExist;
642
643     // Check if BSS is 802.11a/b/g
644     if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
645         pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
646     } else {
647         if (pBSSList->sERP.bERPExist == true) {
648             pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
649         } else {
650             pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
651         }
652     }
653
654     pBSSList->byRxRate = pRxPacket->byRxRate;
655     pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF;
656     if(bChannelHit)
657         pBSSList->uRSSI = pRxPacket->uRSSI;
658     pBSSList->bySQ = pRxPacket->bySQ;
659
660    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
661         (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
662         // assoc with BSS
663         if (pBSSList == pMgmt->pCurrBSS) {
664             bParsingQuiet = true;
665         }
666     }
667
668    WPA_ClearRSN(pBSSList);         //mike update
669
670     if (pRSNWPA != NULL) {
671         unsigned int uLen = pRSNWPA->len + 2;
672         if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) {
673             pBSSList->wWPALen = uLen;
674             memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
675             WPA_ParseRSN(pBSSList, pRSNWPA);
676         }
677     }
678
679    WPA2_ClearRSN(pBSSList);  //mike update
680
681     if (pRSN != NULL) {
682         unsigned int uLen = pRSN->len + 2;
683         if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) {
684             pBSSList->wRSNLen = uLen;
685             memcpy(pBSSList->byRSNIE, pRSN, uLen);
686             WPA2vParseRSN(pBSSList, pRSN);
687         }
688     }
689
690     if (pRxPacket->uRSSI != 0) {
691         RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &ldBm);
692         // Moniter if RSSI is too strong.
693         pBSSList->byRSSIStatCnt++;
694         pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT;
695         pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm;
696         for(ii=0;ii<RSSI_STAT_COUNT;ii++) {
697             if (pBSSList->ldBmAverage[ii] != 0) {
698                 pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm);
699             }
700         }
701     }
702
703     if ((pIE_Country != NULL) &&
704         (pMgmt->b11hEnable == true)) {
705         set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse,
706                             pIE_Country);
707     }
708
709     if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) {
710         if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
711             (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
712             // valid EID
713             if (pQuiet == NULL) {
714                 pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
715                 CARDbSetQuiet(  pMgmt->pAdapter,
716                                 true,
717                                 pQuiet->byQuietCount,
718                                 pQuiet->byQuietPeriod,
719                                 *((unsigned short *)pQuiet->abyQuietDuration),
720                                 *((unsigned short *)pQuiet->abyQuietOffset)
721                                 );
722             } else {
723                 pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
724                 CARDbSetQuiet(  pMgmt->pAdapter,
725                                 false,
726                                 pQuiet->byQuietCount,
727                                 pQuiet->byQuietPeriod,
728                                 *((unsigned short *)pQuiet->abyQuietDuration),
729                                 *((unsigned short *)pQuiet->abyQuietOffset)
730                                 );
731             }
732         }
733     }
734
735     if ((bParsingQuiet == true) &&
736         (pQuiet != NULL)) {
737         CARDbStartQuiet(pMgmt->pAdapter);
738     }
739
740     pBSSList->uIELength = uIELength;
741     if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
742         pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
743     memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
744
745     return true;
746 }
747
748
749
750
751
752 /*+
753  *
754  * Routine Description:
755  *    Search Node DB table to find the index of matched DstAddr
756  *
757  * Return Value:
758  *    None
759  *
760 -*/
761
762 bool
763 BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr,
764                 unsigned int *puNodeIndex)
765 {
766     PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
767     unsigned int ii;
768
769     // Index = 0 reserved for AP Node
770     for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
771         if (pMgmt->sNodeDBTable[ii].bActive) {
772             if (!compare_ether_addr(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) {
773                 *puNodeIndex = ii;
774                 return true;
775             }
776         }
777     }
778
779    return false;
780 };
781
782
783
784 /*+
785  *
786  * Routine Description:
787  *    Find an empty node and allocat it; if there is no empty node,
788  *    then use the most inactive one.
789  *
790  * Return Value:
791  *    None
792  *
793 -*/
794 void
795 BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex)
796 {
797
798     PSDevice     pDevice = (PSDevice)hDeviceContext;
799     PSMgmtObject    pMgmt = pDevice->pMgmt;
800     unsigned int ii;
801     unsigned int BigestCount = 0;
802     unsigned int SelectIndex;
803     struct sk_buff  *skb;
804     // Index = 0 reserved for AP Node (In STA mode)
805     // Index = 0 reserved for Broadcast/MultiCast (In AP mode)
806     SelectIndex = 1;
807     for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
808         if (pMgmt->sNodeDBTable[ii].bActive) {
809             if (pMgmt->sNodeDBTable[ii].uInActiveCount > BigestCount) {
810                 BigestCount = pMgmt->sNodeDBTable[ii].uInActiveCount;
811                 SelectIndex = ii;
812             }
813         }
814         else {
815             break;
816         }
817     }
818
819     // if not found replace uInActiveCount is largest one.
820     if ( ii == (MAX_NODE_NUM + 1)) {
821         *puNodeIndex = SelectIndex;
822         DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Replace inactive node = %d\n", SelectIndex);
823         // clear ps buffer
824         if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) {
825             while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL)
826             dev_kfree_skb(skb);
827         }
828     }
829     else {
830         *puNodeIndex = ii;
831     }
832
833     memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB));
834     pMgmt->sNodeDBTable[*puNodeIndex].bActive = true;
835     pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND;
836     // for AP mode PS queue
837     skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue);
838     pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0;
839     pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0;
840     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii);
841     return;
842 };
843
844
845
846 /*+
847  *
848  * Routine Description:
849  *    Remove Node by NodeIndex
850  *
851  *
852  * Return Value:
853  *    None
854  *
855 -*/
856 void
857 BSSvRemoveOneNode(
858     void *hDeviceContext,
859     unsigned int uNodeIndex
860     )
861 {
862
863     PSDevice        pDevice = (PSDevice)hDeviceContext;
864     PSMgmtObject    pMgmt = pDevice->pMgmt;
865     unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
866     struct sk_buff  *skb;
867
868
869     while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)) != NULL)
870             dev_kfree_skb(skb);
871     // clear context
872     memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB));
873     // clear tx bit map
874     pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &=  ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7];
875
876     return;
877 };
878 /*+
879  *
880  * Routine Description:
881  *    Update AP Node content in Index 0 of KnownNodeDB
882  *
883  *
884  * Return Value:
885  *    None
886  *
887 -*/
888
889 void
890 BSSvUpdateAPNode(
891     void *hDeviceContext,
892     unsigned short *pwCapInfo,
893     PWLAN_IE_SUPP_RATES pSuppRates,
894     PWLAN_IE_SUPP_RATES pExtSuppRates
895     )
896 {
897     PSDevice     pDevice = (PSDevice)hDeviceContext;
898     PSMgmtObject    pMgmt = pDevice->pMgmt;
899     unsigned int uRateLen = WLAN_RATES_MAXLEN;
900
901     memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
902
903     pMgmt->sNodeDBTable[0].bActive = true;
904     if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
905         uRateLen = WLAN_RATES_MAXLEN_11B;
906     }
907     pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates,
908                                             (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
909                                             uRateLen);
910     pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates,
911                                             (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
912                                             uRateLen);
913     RATEvParseMaxRate((void *)pDevice,
914                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
915                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
916                        true,
917                        &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
918                        &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
919                        &(pMgmt->sNodeDBTable[0].wSuppRate),
920                        &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
921                        &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
922                       );
923     memcpy(pMgmt->sNodeDBTable[0].abyMACAddr, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
924     pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate;
925     pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo);
926     pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
927 #ifdef  PLICE_DEBUG
928         printk("BSSvUpdateAPNode:MaxSuppRate is %d\n",pMgmt->sNodeDBTable[0].wMaxSuppRate);
929 #endif
930     // Auto rate fallback function initiation.
931     // RATEbInit(pDevice);
932     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate);
933
934 };
935
936
937
938
939
940 /*+
941  *
942  * Routine Description:
943  *    Add Multicast Node content in Index 0 of KnownNodeDB
944  *
945  *
946  * Return Value:
947  *    None
948  *
949 -*/
950
951
952 void
953 BSSvAddMulticastNode(
954     void *hDeviceContext
955     )
956 {
957     PSDevice     pDevice = (PSDevice)hDeviceContext;
958     PSMgmtObject    pMgmt = pDevice->pMgmt;
959
960     if (!pDevice->bEnableHostWEP)
961         memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
962     memset(pMgmt->sNodeDBTable[0].abyMACAddr, 0xff, WLAN_ADDR_LEN);
963     pMgmt->sNodeDBTable[0].bActive = true;
964     pMgmt->sNodeDBTable[0].bPSEnable = false;
965     skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue);
966     RATEvParseMaxRate((void *)pDevice,
967                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
968                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
969                       true,
970                       &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
971                       &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
972                        &(pMgmt->sNodeDBTable[0].wSuppRate),
973                       &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
974                       &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
975                      );
976     pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate;
977 #ifdef  PLICE_DEBUG
978         printk("BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n",pMgmt->sNodeDBTable[0].wTxDataRate);
979 #endif
980     pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
981
982 };
983
984
985
986
987
988 /*+
989  *
990  * Routine Description:
991  *
992  *
993  *  Second call back function to update Node DB info & AP link status
994  *
995  *
996  * Return Value:
997  *    none.
998  *
999 -*/
1000  //2008-4-14 <add> by chester for led issue
1001  #ifdef FOR_LED_ON_NOTEBOOK
1002 bool cc=false;
1003 unsigned int status;
1004 #endif
1005 void
1006 BSSvSecondCallBack(
1007     void *hDeviceContext
1008     )
1009 {
1010     PSDevice        pDevice = (PSDevice)hDeviceContext;
1011     PSMgmtObject    pMgmt = pDevice->pMgmt;
1012     unsigned int ii;
1013     PWLAN_IE_SSID   pItemSSID, pCurrSSID;
1014     unsigned int uSleepySTACnt = 0;
1015     unsigned int uNonShortSlotSTACnt = 0;
1016     unsigned int uLongPreambleSTACnt = 0;
1017     viawget_wpa_header* wpahdr;  //DavidWang
1018
1019     spin_lock_irq(&pDevice->lock);
1020
1021     pDevice->uAssocCount = 0;
1022
1023     pDevice->byERPFlag &=
1024         ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
1025  //2008-4-14 <add> by chester for led issue
1026 #ifdef FOR_LED_ON_NOTEBOOK
1027 MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
1028 if ((( !(pDevice->byGPIO & GPIO0_DATA)&&(pDevice->bHWRadioOff == false))||((pDevice->byGPIO & GPIO0_DATA)&&(pDevice->bHWRadioOff == true)))&&(cc==false)){
1029 cc=true;
1030 }
1031 else if(cc==true){
1032
1033 if(pDevice->bHWRadioOff == true){
1034             if ( !(pDevice->byGPIO & GPIO0_DATA))
1035 //||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
1036 {if(status==1) goto start;
1037 status=1;
1038 CARDbRadioPowerOff(pDevice);
1039                 pMgmt->sNodeDBTable[0].bActive = false;
1040                 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
1041                 pMgmt->eCurrState = WMAC_STATE_IDLE;
1042                 //netif_stop_queue(pDevice->dev);
1043                 pDevice->bLinkPass = false;
1044
1045 }
1046   if (pDevice->byGPIO &GPIO0_DATA)
1047 //||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
1048 {if(status==2) goto start;
1049 status=2;
1050 CARDbRadioPowerOn(pDevice);
1051 } }
1052 else{
1053             if (pDevice->byGPIO & GPIO0_DATA)
1054 //||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
1055 {if(status==3) goto start;
1056 status=3;
1057 CARDbRadioPowerOff(pDevice);
1058                 pMgmt->sNodeDBTable[0].bActive = false;
1059                 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
1060                 pMgmt->eCurrState = WMAC_STATE_IDLE;
1061                 //netif_stop_queue(pDevice->dev);
1062                 pDevice->bLinkPass = false;
1063
1064 }
1065   if ( !(pDevice->byGPIO & GPIO0_DATA))
1066 //||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
1067 {if(status==4) goto start;
1068 status=4;
1069 CARDbRadioPowerOn(pDevice);
1070 } }
1071 }
1072 start:
1073 #endif
1074
1075
1076     if (pDevice->wUseProtectCntDown > 0) {
1077         pDevice->wUseProtectCntDown --;
1078     }
1079     else {
1080         // disable protect mode
1081         pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1));
1082     }
1083
1084 {
1085        pDevice->byReAssocCount++;
1086    if((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != true)) {  //10 sec timeout
1087                      printk("Re-association timeout!!!\n");
1088                    pDevice->byReAssocCount = 0;
1089                      #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1090                     // if(pDevice->bWPASuppWextEnabled == true)
1091                         {
1092                         union iwreq_data  wrqu;
1093                         memset(&wrqu, 0, sizeof (wrqu));
1094                           wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1095                         PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
1096                         wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
1097                        }
1098                     #endif
1099      }
1100    else if(pDevice->bLinkPass == true)
1101         pDevice->byReAssocCount = 0;
1102 }
1103
1104 #ifdef Calcu_LinkQual
1105    s_uCalculateLinkQual((void *)pDevice);
1106 #endif
1107
1108     for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
1109
1110         if (pMgmt->sNodeDBTable[ii].bActive) {
1111             // Increase in-activity counter
1112             pMgmt->sNodeDBTable[ii].uInActiveCount++;
1113
1114             if (ii > 0) {
1115                 if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) {
1116                     BSSvRemoveOneNode(pDevice, ii);
1117                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
1118                         "Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT, ii);
1119                     continue;
1120                 }
1121
1122                 if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) {
1123
1124                     pDevice->uAssocCount++;
1125
1126                     // check if Non ERP exist
1127                     if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) {
1128                         if (!pMgmt->sNodeDBTable[ii].bShortPreamble) {
1129                             pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
1130                             uLongPreambleSTACnt ++;
1131                         }
1132                         if (!pMgmt->sNodeDBTable[ii].bERPExist) {
1133                             pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
1134                             pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
1135                         }
1136                         if (!pMgmt->sNodeDBTable[ii].bShortSlotTime)
1137                             uNonShortSlotSTACnt++;
1138                     }
1139                 }
1140
1141                 // check if any STA in PS mode
1142                 if (pMgmt->sNodeDBTable[ii].bPSEnable)
1143                     uSleepySTACnt++;
1144
1145
1146             }
1147
1148             // Rate fallback check
1149             if (!pDevice->bFixRate) {
1150 /*
1151                 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (ii == 0))
1152                     RATEvTxRateFallBack(pDevice, &(pMgmt->sNodeDBTable[ii]));
1153 */
1154                 if (ii > 0) {
1155                     // ii = 0 for multicast node (AP & Adhoc)
1156                     RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii]));
1157                 }
1158                 else {
1159                     // ii = 0 reserved for unicast AP node (Infra STA)
1160                     if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)
1161 #ifdef  PLICE_DEBUG
1162                 printk("SecondCallback:Before:TxDataRate is %d\n",pMgmt->sNodeDBTable[0].wTxDataRate);
1163 #endif
1164                         RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii]));
1165 #ifdef  PLICE_DEBUG
1166                 printk("SecondCallback:After:TxDataRate is %d\n",pMgmt->sNodeDBTable[0].wTxDataRate);
1167 #endif
1168
1169                 }
1170
1171             }
1172
1173             // check if pending PS queue
1174             if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) {
1175                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n",
1176                            ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
1177                 if ((ii >0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) {
1178                     BSSvRemoveOneNode(pDevice, ii);
1179                     DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii);
1180                     continue;
1181                 }
1182             }
1183         }
1184
1185     }
1186
1187
1188     if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->eCurrentPHYType == PHY_TYPE_11G)) {
1189
1190         // on/off protect mode
1191         if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
1192             if (!pDevice->bProtectMode) {
1193                 MACvEnableProtectMD(pDevice->PortOffset);
1194                 pDevice->bProtectMode = true;
1195             }
1196         }
1197         else {
1198             if (pDevice->bProtectMode) {
1199                 MACvDisableProtectMD(pDevice->PortOffset);
1200                 pDevice->bProtectMode = false;
1201             }
1202         }
1203         // on/off short slot time
1204
1205         if (uNonShortSlotSTACnt > 0) {
1206             if (pDevice->bShortSlotTime) {
1207                 pDevice->bShortSlotTime = false;
1208                 BBvSetShortSlotTime(pDevice);
1209                 vUpdateIFS((void *)pDevice);
1210             }
1211         }
1212         else {
1213             if (!pDevice->bShortSlotTime) {
1214                 pDevice->bShortSlotTime = true;
1215                 BBvSetShortSlotTime(pDevice);
1216                 vUpdateIFS((void *)pDevice);
1217             }
1218         }
1219
1220         // on/off barker long preamble mode
1221
1222         if (uLongPreambleSTACnt > 0) {
1223             if (!pDevice->bBarkerPreambleMd) {
1224                 MACvEnableBarkerPreambleMd(pDevice->PortOffset);
1225                 pDevice->bBarkerPreambleMd = true;
1226             }
1227         }
1228         else {
1229             if (pDevice->bBarkerPreambleMd) {
1230                 MACvDisableBarkerPreambleMd(pDevice->PortOffset);
1231                 pDevice->bBarkerPreambleMd = false;
1232             }
1233         }
1234
1235     }
1236
1237
1238     // Check if any STA in PS mode, enable DTIM multicast deliver
1239     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1240         if (uSleepySTACnt > 0)
1241             pMgmt->sNodeDBTable[0].bPSEnable = true;
1242         else
1243             pMgmt->sNodeDBTable[0].bPSEnable = false;
1244     }
1245
1246     pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
1247     pCurrSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
1248
1249     if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
1250         (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
1251
1252         if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
1253            // DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Callback inactive Count = [%d]\n", pMgmt->sNodeDBTable[0].uInActiveCount);
1254             //if (pDevice->bUpdateBBVGA) {
1255             //  s_vCheckSensitivity((void *) pDevice);
1256             //}
1257
1258             if (pDevice->bUpdateBBVGA) {
1259                // s_vCheckSensitivity((void *) pDevice);
1260                s_vCheckPreEDThreshold((void *)pDevice);
1261             }
1262
1263             if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) &&
1264                 (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) ) {
1265                 pDevice->byBBVGANew = pDevice->abyBBVGA[0];
1266                 bScheduleCommand((void *) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL);
1267             }
1268
1269                 if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) {
1270                 pMgmt->sNodeDBTable[0].bActive = false;
1271                 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
1272                 pMgmt->eCurrState = WMAC_STATE_IDLE;
1273                 netif_stop_queue(pDevice->dev);
1274                 pDevice->bLinkPass = false;
1275                 pDevice->bRoaming = true;
1276                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
1277         if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
1278              wpahdr = (viawget_wpa_header *)pDevice->skb->data;
1279              wpahdr->type = VIAWGET_DISASSOC_MSG;
1280              wpahdr->resp_ie_len = 0;
1281              wpahdr->req_ie_len = 0;
1282              skb_put(pDevice->skb, sizeof(viawget_wpa_header));
1283              pDevice->skb->dev = pDevice->wpadev;
1284              skb_reset_mac_header(pDevice->skb);
1285              pDevice->skb->pkt_type = PACKET_HOST;
1286              pDevice->skb->protocol = htons(ETH_P_802_2);
1287              memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
1288              netif_rx(pDevice->skb);
1289              pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1290          }
1291    #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1292   // if(pDevice->bWPASuppWextEnabled == true)
1293       {
1294         union iwreq_data  wrqu;
1295         memset(&wrqu, 0, sizeof (wrqu));
1296         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1297         PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
1298         wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
1299      }
1300   #endif
1301             }
1302         }
1303         else if (pItemSSID->len != 0) {
1304             if (pDevice->uAutoReConnectTime < 10) {
1305                 pDevice->uAutoReConnectTime++;
1306                #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1307                 //network manager support need not do Roaming scan???
1308                 if(pDevice->bWPASuppWextEnabled ==true)
1309                  pDevice->uAutoReConnectTime = 0;
1310              #endif
1311             }
1312             else {
1313            //mike use old encryption status for wpa reauthen
1314               if(pDevice->bWPADEVUp)
1315                   pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus;
1316
1317                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n");
1318                 BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
1319               pMgmt->eScanType = WMAC_SCAN_ACTIVE;
1320                 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
1321                 bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
1322                 pDevice->uAutoReConnectTime = 0;
1323             }
1324         }
1325     }
1326
1327     if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
1328         // if adhoc started which essid is NULL string, rescanning.
1329         if ((pMgmt->eCurrState == WMAC_STATE_STARTED) && (pCurrSSID->len == 0)) {
1330             if (pDevice->uAutoReConnectTime < 10) {
1331                 pDevice->uAutoReConnectTime++;
1332             }
1333             else {
1334                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scanning ...\n");
1335               pMgmt->eScanType = WMAC_SCAN_ACTIVE;
1336                 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1337                 bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL);
1338                 pDevice->uAutoReConnectTime = 0;
1339             };
1340         }
1341         if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
1342
1343             if (pDevice->bUpdateBBVGA) {
1344                //s_vCheckSensitivity((void *) pDevice);
1345                s_vCheckPreEDThreshold((void *)pDevice);
1346             }
1347                 if (pMgmt->sNodeDBTable[0].uInActiveCount >=ADHOC_LOST_BEACON_COUNT) {
1348                     DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
1349                 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
1350                 pMgmt->eCurrState = WMAC_STATE_STARTED;
1351                 netif_stop_queue(pDevice->dev);
1352                 pDevice->bLinkPass = false;
1353             }
1354         }
1355     }
1356
1357     spin_unlock_irq(&pDevice->lock);
1358
1359     pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
1360     add_timer(&pMgmt->sTimerSecondCallback);
1361     return;
1362 }
1363
1364
1365
1366
1367 /*+
1368  *
1369  * Routine Description:
1370  *
1371  *
1372  *  Update Tx attemps, Tx failure counter in Node DB
1373  *
1374  *
1375  * Return Value:
1376  *    none.
1377  *
1378 -*/
1379
1380
1381
1382 void
1383 BSSvUpdateNodeTxCounter(
1384     void *hDeviceContext,
1385     unsigned char byTsr0,
1386     unsigned char byTsr1,
1387     unsigned char *pbyBuffer,
1388     unsigned int uFIFOHeaderSize
1389     )
1390 {
1391     PSDevice        pDevice = (PSDevice)hDeviceContext;
1392     PSMgmtObject    pMgmt = pDevice->pMgmt;
1393     unsigned int uNodeIndex = 0;
1394     unsigned char byTxRetry = (byTsr0 & TSR0_NCR);
1395     PSTxBufHead     pTxBufHead;
1396     PS802_11Header  pMACHeader;
1397     unsigned short wRate;
1398     unsigned short wFallBackRate = RATE_1M;
1399     unsigned char byFallBack;
1400     unsigned int ii;
1401 //      unsigned int txRetryTemp;
1402 //PLICE_DEBUG->
1403         //txRetryTemp = byTxRetry;
1404         //if (txRetryTemp== 8)
1405         //txRetryTemp -=3;
1406 //PLICE_DEBUG <-
1407     pTxBufHead = (PSTxBufHead) pbyBuffer;
1408     if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0) {
1409         byFallBack = AUTO_FB_0;
1410     } else if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_1) {
1411         byFallBack = AUTO_FB_1;
1412     } else {
1413         byFallBack = AUTO_FB_NONE;
1414     }
1415     wRate = pTxBufHead->wReserved; //?wRate
1416     //printk("BSSvUpdateNodeTxCounter:byTxRetry is %d\n",byTxRetry);
1417
1418 //printk("BSSvUpdateNodeTx:wRate is %d,byFallback is %d\n",wRate,byFallBack);
1419 //#ifdef        PLICE_DEBUG
1420         //printk("BSSvUpdateNodeTx: wRate is %d\n",wRate);
1421 ////#endif
1422     // Only Unicast using support rates
1423     if (pTxBufHead->wFIFOCtl & FIFOCTL_NEEDACK) {
1424         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wRate %04X, byTsr0 %02X, byTsr1 %02X\n", wRate, byTsr0, byTsr1);
1425         if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
1426             pMgmt->sNodeDBTable[0].uTxAttempts += 1;
1427             if ((byTsr1 & TSR1_TERR) == 0) {
1428                 // transmit success, TxAttempts at least plus one
1429                 pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++;
1430                 if ( (byFallBack == AUTO_FB_NONE) ||
1431                      (wRate < RATE_18M) ) {
1432                     wFallBackRate = wRate;
1433                 } else if (byFallBack == AUTO_FB_0) {
1434 //PLICE_DEBUG
1435                                   if (byTxRetry < 5)
1436                                 //if (txRetryTemp < 5)
1437                                         wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
1438                         //wFallBackRate = awHWRetry0[wRate-RATE_12M][byTxRetry];
1439                         //wFallBackRate = awHWRetry0[wRate-RATE_18M][txRetryTemp] +1;
1440                 else
1441                         wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
1442                         //wFallBackRate = awHWRetry0[wRate-RATE_12M][4];
1443                 } else if (byFallBack == AUTO_FB_1) {
1444                     if (byTxRetry < 5)
1445                         wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry];
1446                     else
1447                         wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
1448                 }
1449                 pMgmt->sNodeDBTable[0].uTxOk[wFallBackRate]++;
1450             } else {
1451                 pMgmt->sNodeDBTable[0].uTxFailures ++;
1452             }
1453             pMgmt->sNodeDBTable[0].uTxRetry += byTxRetry;
1454             if (byTxRetry != 0) {
1455                 pMgmt->sNodeDBTable[0].uTxFail[MAX_RATE]+=byTxRetry;
1456                 if ( (byFallBack == AUTO_FB_NONE) ||
1457                      (wRate < RATE_18M) ) {
1458                     pMgmt->sNodeDBTable[0].uTxFail[wRate]+=byTxRetry;
1459                 } else if (byFallBack == AUTO_FB_0) {
1460 //PLICE_DEBUG
1461                                    for(ii=0;ii<byTxRetry;ii++)
1462                 //for (ii=0;ii<txRetryTemp;ii++)
1463                 {
1464                         if (ii < 5)
1465                                 {
1466
1467 //PLICE_DEBUG
1468                                                 wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
1469                                         //printk(" II is %d:BSSvUpdateNodeTx:wFallBackRate is %d\n",ii,wFallBackRate);
1470                                 //wFallBackRate = awHWRetry0[wRate-RATE_12M][ii];
1471                                 }
1472                         else
1473                                 {
1474                         wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
1475                         //printk("ii is %d BSSvUpdateNodeTx:wFallBackRate is %d\n",ii,wFallBackRate);
1476                                 //wFallBackRate = awHWRetry0[wRate-RATE_12M][4];
1477                                 }
1478                                                 pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
1479                     }
1480                 } else if (byFallBack == AUTO_FB_1) {
1481                     for(ii=0;ii<byTxRetry;ii++) {
1482                         if (ii < 5)
1483                             wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
1484                         else
1485                             wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
1486                         pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
1487                     }
1488                 }
1489             }
1490         }
1491
1492         if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
1493             (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
1494
1495             pMACHeader = (PS802_11Header)(pbyBuffer + uFIFOHeaderSize);
1496
1497             if (BSSDBbIsSTAInNodeDB((void *)pMgmt, &(pMACHeader->abyAddr1[0]), &uNodeIndex)){
1498                 pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1;
1499                 if ((byTsr1 & TSR1_TERR) == 0) {
1500                     // transmit success, TxAttempts at least plus one
1501                     pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
1502                     if ( (byFallBack == AUTO_FB_NONE) ||
1503                          (wRate < RATE_18M) ) {
1504                         wFallBackRate = wRate;
1505                     } else if (byFallBack == AUTO_FB_0) {
1506                         if (byTxRetry < 5)
1507                             wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
1508                         else
1509                             wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
1510                     } else if (byFallBack == AUTO_FB_1) {
1511                         if (byTxRetry < 5)
1512                             wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry];
1513                         else
1514                             wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
1515                     }
1516                     pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wFallBackRate]++;
1517                 } else {
1518                     pMgmt->sNodeDBTable[uNodeIndex].uTxFailures ++;
1519                 }
1520                 pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += byTxRetry;
1521                 if (byTxRetry != 0) {
1522                     pMgmt->sNodeDBTable[uNodeIndex].uTxFail[MAX_RATE]+=byTxRetry;
1523                     if ( (byFallBack == AUTO_FB_NONE) ||
1524                          (wRate < RATE_18M) ) {
1525                         pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wRate]+=byTxRetry;
1526                     } else if (byFallBack == AUTO_FB_0) {
1527                         for(ii=0;ii<byTxRetry;ii++) {
1528                             if (ii < 5)
1529                                 wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
1530                             else
1531                                 wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
1532                             pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
1533                         }
1534                     } else if (byFallBack == AUTO_FB_1) {
1535                         for(ii=0;ii<byTxRetry;ii++) {
1536                             if (ii < 5)
1537                                 wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
1538                             else
1539                                 wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
1540                             pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
1541                         }
1542                     }
1543                 }
1544             }
1545         }
1546     }
1547
1548     return;
1549
1550
1551 }
1552
1553
1554
1555
1556 /*+
1557  *
1558  * Routine Description:
1559  *    Clear Nodes & skb in DB Table
1560  *
1561  *
1562  * Parameters:
1563  *  In:
1564  *      hDeviceContext        - The adapter context.
1565  *      uStartIndex           - starting index
1566  *  Out:
1567  *      none
1568  *
1569  * Return Value:
1570  *    None.
1571  *
1572 -*/
1573
1574
1575 void
1576 BSSvClearNodeDBTable(
1577     void *hDeviceContext,
1578     unsigned int uStartIndex
1579     )
1580
1581 {
1582     PSDevice     pDevice = (PSDevice)hDeviceContext;
1583     PSMgmtObject    pMgmt = pDevice->pMgmt;
1584     struct sk_buff  *skb;
1585     unsigned int ii;
1586
1587     for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) {
1588         if (pMgmt->sNodeDBTable[ii].bActive) {
1589             // check if sTxPSQueue has been initial
1590             if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) {
1591                 while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL){
1592                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii);
1593                         dev_kfree_skb(skb);
1594                 }
1595             }
1596             memset(&pMgmt->sNodeDBTable[ii], 0, sizeof(KnownNodeDB));
1597         }
1598     }
1599
1600     return;
1601 };
1602
1603
1604 void s_vCheckSensitivity(
1605     void *hDeviceContext
1606     )
1607 {
1608     PSDevice        pDevice = (PSDevice)hDeviceContext;
1609     PKnownBSS       pBSSList = NULL;
1610     PSMgmtObject    pMgmt = pDevice->pMgmt;
1611     int             ii;
1612
1613     if ((pDevice->byLocalID <= REV_ID_VT3253_A1) && (pDevice->byRFType == RF_RFMD2959) &&
1614         (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
1615         return;
1616     }
1617
1618     if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
1619         ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
1620         pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
1621         if (pBSSList != NULL) {
1622             // Updata BB Reg if RSSI is too strong.
1623             long    LocalldBmAverage = 0;
1624             long    uNumofdBm = 0;
1625             for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
1626                 if (pBSSList->ldBmAverage[ii] != 0) {
1627                     uNumofdBm ++;
1628                     LocalldBmAverage += pBSSList->ldBmAverage[ii];
1629                 }
1630             }
1631             if (uNumofdBm > 0) {
1632                 LocalldBmAverage = LocalldBmAverage/uNumofdBm;
1633                 for (ii=0;ii<BB_VGA_LEVEL;ii++) {
1634                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage, pDevice->ldBmThreshold[ii], pDevice->abyBBVGA[ii]);
1635                     if (LocalldBmAverage < pDevice->ldBmThreshold[ii]) {
1636                             pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
1637                         break;
1638                     }
1639                 }
1640                 if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
1641                     pDevice->uBBVGADiffCount++;
1642                     if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD)
1643                         bScheduleCommand((void *) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL);
1644                 } else {
1645                     pDevice->uBBVGADiffCount = 0;
1646                 }
1647             }
1648         }
1649     }
1650 }
1651
1652
1653 void
1654 BSSvClearAnyBSSJoinRecord (
1655     void *hDeviceContext
1656     )
1657 {
1658     PSDevice        pDevice = (PSDevice)hDeviceContext;
1659     PSMgmtObject    pMgmt = pDevice->pMgmt;
1660     unsigned int ii;
1661
1662     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
1663         pMgmt->sBSSList[ii].bSelected = false;
1664     }
1665     return;
1666 }
1667
1668 #ifdef Calcu_LinkQual
1669 void s_uCalculateLinkQual(
1670     void *hDeviceContext
1671     )
1672 {
1673    PSDevice        pDevice = (PSDevice)hDeviceContext;
1674    unsigned long TxOkRatio, TxCnt;
1675    unsigned long RxOkRatio,RxCnt;
1676    unsigned long RssiRatio;
1677    long ldBm;
1678
1679 TxCnt = pDevice->scStatistic.TxNoRetryOkCount +
1680               pDevice->scStatistic.TxRetryOkCount +
1681               pDevice->scStatistic.TxFailCount;
1682 RxCnt = pDevice->scStatistic.RxFcsErrCnt +
1683               pDevice->scStatistic.RxOkCnt;
1684 TxOkRatio = (TxCnt < 6) ? 4000:((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt);
1685 RxOkRatio = (RxCnt < 6) ? 2000:((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt);
1686 //decide link quality
1687 if(pDevice->bLinkPass !=true)
1688 {
1689  //  printk("s_uCalculateLinkQual-->Link disconnect and Poor quality**\n");
1690    pDevice->scStatistic.LinkQuality = 0;
1691    pDevice->scStatistic.SignalStren = 0;
1692 }
1693 else
1694 {
1695    RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm);
1696    if(-ldBm < 50)  {
1697         RssiRatio = 4000;
1698      }
1699    else if(-ldBm > 90) {
1700         RssiRatio = 0;
1701      }
1702    else {
1703         RssiRatio = (40-(-ldBm-50))*4000/40;
1704      }
1705    pDevice->scStatistic.SignalStren = RssiRatio/40;
1706    pDevice->scStatistic.LinkQuality = (RssiRatio+TxOkRatio+RxOkRatio)/100;
1707 }
1708    pDevice->scStatistic.RxFcsErrCnt = 0;
1709    pDevice->scStatistic.RxOkCnt = 0;
1710    pDevice->scStatistic.TxFailCount = 0;
1711    pDevice->scStatistic.TxNoRetryOkCount = 0;
1712    pDevice->scStatistic.TxRetryOkCount = 0;
1713    return;
1714 }
1715 #endif
1716
1717 void s_vCheckPreEDThreshold(
1718     void *hDeviceContext
1719     )
1720 {
1721     PSDevice        pDevice = (PSDevice)hDeviceContext;
1722     PKnownBSS       pBSSList = NULL;
1723     PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1724
1725     if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
1726         ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
1727         pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
1728         if (pBSSList != NULL) {
1729             pDevice->byBBPreEDRSSI = (unsigned char) (~(pBSSList->ldBmAverRange) + 1);
1730             //BBvUpdatePreEDThreshold(pDevice, false);
1731         }
1732     }
1733     return;
1734 }
1735