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