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