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