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