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