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