2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
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.
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.
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.
21 * Purpose: Handles the Basic Service Set & Node Database 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
62 /*--------------------- Static Definitions -------------------------*/
67 /*--------------------- Static Classes ----------------------------*/
69 /*--------------------- Static Variables --------------------------*/
70 static int msglevel
=MSG_LEVEL_INFO
;
71 //static int msglevel =MSG_LEVEL_DEBUG;
75 const 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
}
82 const 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
}
92 /*--------------------- Static Functions --------------------------*/
94 void s_vCheckSensitivity(void *hDeviceContext
);
95 void s_vCheckPreEDThreshold(void *hDeviceContext
);
96 void s_uCalculateLinkQual(void *hDeviceContext
);
98 /*--------------------- Export Variables --------------------------*/
101 /*--------------------- Export Functions --------------------------*/
109 * Routine Description:
110 * Search known BSS list for Desire SSID or BSSID.
113 * PTR to KnownBSS or NULL
117 PKnownBSS
BSSpSearchBSSList(void *hDeviceContext
,
118 PBYTE pbyDesireBSSID
,
120 CARD_PHY_TYPE ePhyType
)
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};
131 if (pbyDesireBSSID
!= NULL
) {
132 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"BSSpSearchBSSList BSSID[%02X %02X %02X-%02X %02X %02X]\n",
133 *pbyDesireBSSID
,*(pbyDesireBSSID
+1),*(pbyDesireBSSID
+2),
134 *(pbyDesireBSSID
+3),*(pbyDesireBSSID
+4),*(pbyDesireBSSID
+5));
135 if ((!is_broadcast_ether_addr(pbyDesireBSSID
)) &&
136 (memcmp(pbyDesireBSSID
, ZeroBSSID
, 6)!= 0)){
137 pbyBSSID
= pbyDesireBSSID
;
140 if (pbyDesireSSID
!= NULL
) {
141 if (((PWLAN_IE_SSID
)pbyDesireSSID
)->len
!= 0) {
142 pSSID
= (PWLAN_IE_SSID
) pbyDesireSSID
;
146 if ((pbyBSSID
!= NULL
)&&(pDevice
->bRoaming
== FALSE
)) {
148 for (ii
= 0; ii
<MAX_BSS_NUM
; ii
++) {
149 pCurrBSS
= &(pMgmt
->sBSSList
[ii
]);
151 pCurrBSS
->bSelected
= FALSE
;
153 if ((pCurrBSS
->bActive
) &&
154 (pCurrBSS
->bSelected
== FALSE
)) {
155 if (!compare_ether_addr(pCurrBSS
->abyBSSID
, pbyBSSID
)) {
158 if ( !memcmp(pSSID
->abySSID
,
159 ((PWLAN_IE_SSID
)pCurrBSS
->abySSID
)->abySSID
,
161 if ((pMgmt
->eConfigMode
== WMAC_CONFIG_AUTO
) ||
162 ((pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
)) ||
163 ((pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
) && WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
))
165 pCurrBSS
->bSelected
= TRUE
;
170 if ((pMgmt
->eConfigMode
== WMAC_CONFIG_AUTO
) ||
171 ((pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
)) ||
172 ((pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
) && WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
))
174 pCurrBSS
->bSelected
= TRUE
;
183 for (ii
= 0; ii
<MAX_BSS_NUM
; ii
++) {
184 pCurrBSS
= &(pMgmt
->sBSSList
[ii
]);
186 //2007-0721-01<Mark>by MikeLiu
187 // if ((pCurrBSS->bActive) &&
188 // (pCurrBSS->bSelected == FALSE)) {
190 pCurrBSS
->bSelected
= FALSE
;
191 if (pCurrBSS
->bActive
) {
195 if (memcmp(pSSID
->abySSID
,
196 ((PWLAN_IE_SSID
)pCurrBSS
->abySSID
)->abySSID
,
198 (pSSID
->len
!= ((PWLAN_IE_SSID
)pCurrBSS
->abySSID
)->len
)) {
199 // SSID not match skip this BSS
203 if (((pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
) && WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
)) ||
204 ((pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
))
206 // Type not match skip this BSS
207 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt
->eConfigMode
, pCurrBSS
->wCapInfo
);
211 if (ePhyType
!= PHY_TYPE_AUTO
) {
212 if (((ePhyType
== PHY_TYPE_11A
) && (PHY_TYPE_11A
!= pCurrBSS
->eNetworkTypeInUse
)) ||
213 ((ePhyType
!= PHY_TYPE_11A
) && (PHY_TYPE_11A
== pCurrBSS
->eNetworkTypeInUse
))) {
214 // PhyType not match skip this BSS
215 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType
, pCurrBSS
->eNetworkTypeInUse
);
220 pMgmt
->pSameBSS
[jj
].uChannel
= pCurrBSS
->uChannel
;
221 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"BSSpSearchBSSList pSelect1[%02X %02X %02X-%02X %02X %02X]\n",*pCurrBSS
->abyBSSID
,*(pCurrBSS
->abyBSSID
+1),*(pCurrBSS
->abyBSSID
+2),*(pCurrBSS
->abyBSSID
+3),*(pCurrBSS
->abyBSSID
+4),*(pCurrBSS
->abyBSSID
+5));
225 if (pSelect
== NULL
) {
228 // compare RSSI, select signal strong one
229 if (pCurrBSS
->uRSSI
< pSelect
->uRSSI
) {
236 pDevice
->bSameBSSMaxNum
= jj
;
238 if (pSelect
!= NULL
) {
239 pSelect
->bSelected
= TRUE
;
240 if (pDevice
->bRoaming
== FALSE
) {
241 // Einsn Add @20070907
242 memset(pbyDesireSSID
, 0, WLAN_IEHDR_LEN
+ WLAN_SSID_MAXLEN
+ 1);
243 memcpy(pbyDesireSSID
,pCurrBSS
->abySSID
,WLAN_IEHDR_LEN
+ WLAN_SSID_MAXLEN
+ 1) ;
256 * Routine Description:
265 void BSSvClearBSSList(void *hDeviceContext
, BOOL bKeepCurrBSSID
)
267 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
268 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
271 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
272 if (bKeepCurrBSSID
) {
273 if (pMgmt
->sBSSList
[ii
].bActive
&&
274 !compare_ether_addr(pMgmt
->sBSSList
[ii
].abyBSSID
,
275 pMgmt
->abyCurrBSSID
)) {
276 //mike mark: there are two same BSSID in list if that AP is in hidden ssid mode,one 's SSID is null,
277 // but other's is obvious, so if it acssociate with your STA exactly,you must keep two
279 // bKeepCurrBSSID = FALSE;
284 pMgmt
->sBSSList
[ii
].bActive
= FALSE
;
285 memset(&pMgmt
->sBSSList
[ii
], 0, sizeof(KnownBSS
));
287 BSSvClearAnyBSSJoinRecord(pDevice
);
294 * Routine Description:
295 * search BSS list by BSSID & SSID if matched
301 PKnownBSS
BSSpAddrIsInBSSList(void *hDeviceContext
,
305 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
306 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
307 PKnownBSS pBSSList
= NULL
;
310 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
311 pBSSList
= &(pMgmt
->sBSSList
[ii
]);
312 if (pBSSList
->bActive
) {
313 if (!compare_ether_addr(pBSSList
->abyBSSID
, abyBSSID
)) {
314 if (pSSID
->len
== ((PWLAN_IE_SSID
)pBSSList
->abySSID
)->len
){
315 if (memcmp(pSSID
->abySSID
,
316 ((PWLAN_IE_SSID
)pBSSList
->abySSID
)->abySSID
,
331 * Routine Description:
332 * Insert a BSS set into known BSS list
339 BOOL
BSSbInsertToBSSList(void *hDeviceContext
,
342 WORD wBeaconInterval
,
346 PWLAN_IE_SUPP_RATES pSuppRates
,
347 PWLAN_IE_SUPP_RATES pExtSuppRates
,
350 PWLAN_IE_RSN_EXT pRSNWPA
,
351 PWLAN_IE_COUNTRY pIE_Country
,
352 PWLAN_IE_QUIET pIE_Quiet
,
353 unsigned int uIELength
,
355 void *pRxPacketContext
)
358 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
359 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
360 PSRxMgmtPacket pRxPacket
= (PSRxMgmtPacket
)pRxPacketContext
;
361 PKnownBSS pBSSList
= NULL
;
363 BOOL bParsingQuiet
= FALSE
;
367 pBSSList
= (PKnownBSS
)&(pMgmt
->sBSSList
[0]);
369 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
370 pBSSList
= (PKnownBSS
)&(pMgmt
->sBSSList
[ii
]);
371 if (!pBSSList
->bActive
)
375 if (ii
== MAX_BSS_NUM
){
376 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Get free KnowBSS node failed.\n");
380 pBSSList
->bActive
= TRUE
;
381 memcpy( pBSSList
->abyBSSID
, abyBSSIDAddr
, WLAN_BSSID_LEN
);
382 HIDWORD(pBSSList
->qwBSSTimestamp
) = cpu_to_le32(HIDWORD(qwTimestamp
));
383 LODWORD(pBSSList
->qwBSSTimestamp
) = cpu_to_le32(LODWORD(qwTimestamp
));
384 pBSSList
->wBeaconInterval
= cpu_to_le16(wBeaconInterval
);
385 pBSSList
->wCapInfo
= cpu_to_le16(wCapInfo
);
386 pBSSList
->uClearCount
= 0;
388 if (pSSID
->len
> WLAN_SSID_MAXLEN
)
389 pSSID
->len
= WLAN_SSID_MAXLEN
;
390 memcpy( pBSSList
->abySSID
, pSSID
, pSSID
->len
+ WLAN_IEHDR_LEN
);
392 pBSSList
->uChannel
= byCurrChannel
;
394 if (pSuppRates
->len
> WLAN_RATES_MAXLEN
)
395 pSuppRates
->len
= WLAN_RATES_MAXLEN
;
396 memcpy( pBSSList
->abySuppRates
, pSuppRates
, pSuppRates
->len
+ WLAN_IEHDR_LEN
);
398 if (pExtSuppRates
!= NULL
) {
399 if (pExtSuppRates
->len
> WLAN_RATES_MAXLEN
)
400 pExtSuppRates
->len
= WLAN_RATES_MAXLEN
;
401 memcpy(pBSSList
->abyExtSuppRates
, pExtSuppRates
, pExtSuppRates
->len
+ WLAN_IEHDR_LEN
);
402 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates
->len
);
405 memset(pBSSList
->abyExtSuppRates
, 0, WLAN_IEHDR_LEN
+ WLAN_RATES_MAXLEN
+ 1);
407 pBSSList
->sERP
.byERP
= psERP
->byERP
;
408 pBSSList
->sERP
.bERPExist
= psERP
->bERPExist
;
410 // Check if BSS is 802.11a/b/g
411 if (pBSSList
->uChannel
> CB_MAX_CHANNEL_24G
) {
412 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11A
;
414 if (pBSSList
->sERP
.bERPExist
== TRUE
) {
415 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11G
;
417 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11B
;
421 pBSSList
->byRxRate
= pRxPacket
->byRxRate
;
422 pBSSList
->qwLocalTSF
= pRxPacket
->qwLocalTSF
;
423 pBSSList
->uRSSI
= pRxPacket
->uRSSI
;
424 pBSSList
->bySQ
= pRxPacket
->bySQ
;
426 if ((pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) &&
427 (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
)) {
429 if (pBSSList
== pMgmt
->pCurrBSS
) {
430 bParsingQuiet
= TRUE
;
434 WPA_ClearRSN(pBSSList
);
436 if (pRSNWPA
!= NULL
) {
437 unsigned int uLen
= pRSNWPA
->len
+ 2;
439 if (uLen
<= (uIELength
-
440 (unsigned int) (ULONG_PTR
) ((PBYTE
) pRSNWPA
- pbyIEs
))) {
441 pBSSList
->wWPALen
= uLen
;
442 memcpy(pBSSList
->byWPAIE
, pRSNWPA
, uLen
);
443 WPA_ParseRSN(pBSSList
, pRSNWPA
);
447 WPA2_ClearRSN(pBSSList
);
450 unsigned int uLen
= pRSN
->len
+ 2;
452 if (uLen
<= (uIELength
-
453 (unsigned int) (ULONG_PTR
) ((PBYTE
) pRSN
- pbyIEs
))) {
454 pBSSList
->wRSNLen
= uLen
;
455 memcpy(pBSSList
->byRSNIE
, pRSN
, uLen
);
456 WPA2vParseRSN(pBSSList
, pRSN
);
460 if ((pMgmt
->eAuthenMode
== WMAC_AUTH_WPA2
) || (pBSSList
->bWPA2Valid
== TRUE
)) {
462 PSKeyItem pTransmitKey
= NULL
;
463 BOOL bIs802_1x
= FALSE
;
465 for (ii
= 0; ii
< pBSSList
->wAKMSSAuthCount
; ii
++) {
466 if (pBSSList
->abyAKMSSAuthType
[ii
] == WLAN_11i_AKMSS_802_1X
) {
471 if ((bIs802_1x
== TRUE
) && (pSSID
->len
== ((PWLAN_IE_SSID
)pMgmt
->abyDesireSSID
)->len
) &&
472 ( !memcmp(pSSID
->abySSID
, ((PWLAN_IE_SSID
)pMgmt
->abyDesireSSID
)->abySSID
, pSSID
->len
))) {
474 bAdd_PMKID_Candidate((void *) pDevice
,
476 &pBSSList
->sRSNCapObj
);
478 if ((pDevice
->bLinkPass
== TRUE
) && (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
)) {
479 if ((KeybGetTransmitKey(&(pDevice
->sKey
), pDevice
->abyBSSID
, PAIRWISE_KEY
, &pTransmitKey
) == TRUE
) ||
480 (KeybGetTransmitKey(&(pDevice
->sKey
), pDevice
->abyBSSID
, GROUP_KEY
, &pTransmitKey
) == TRUE
)) {
481 pDevice
->gsPMKIDCandidate
.StatusType
= Ndis802_11StatusType_PMKID_CandidateList
;
482 pDevice
->gsPMKIDCandidate
.Version
= 1;
490 if (pDevice
->bUpdateBBVGA
) {
491 // Moniter if RSSI is too strong.
492 pBSSList
->byRSSIStatCnt
= 0;
493 RFvRSSITodBm(pDevice
, (BYTE
)(pRxPacket
->uRSSI
), &pBSSList
->ldBmMAX
);
494 pBSSList
->ldBmAverage
[0] = pBSSList
->ldBmMAX
;
495 pBSSList
->ldBmAverRange
= pBSSList
->ldBmMAX
;
496 for (ii
= 1; ii
< RSSI_STAT_COUNT
; ii
++)
497 pBSSList
->ldBmAverage
[ii
] = 0;
500 pBSSList
->uIELength
= uIELength
;
501 if (pBSSList
->uIELength
> WLAN_BEACON_FR_MAXLEN
)
502 pBSSList
->uIELength
= WLAN_BEACON_FR_MAXLEN
;
503 memcpy(pBSSList
->abyIEs
, pbyIEs
, pBSSList
->uIELength
);
511 * Routine Description:
512 * Update BSS set in known BSS list
518 // TODO: input structure modify
520 BOOL
BSSbUpdateToBSSList(void *hDeviceContext
,
522 WORD wBeaconInterval
,
527 PWLAN_IE_SUPP_RATES pSuppRates
,
528 PWLAN_IE_SUPP_RATES pExtSuppRates
,
531 PWLAN_IE_RSN_EXT pRSNWPA
,
532 PWLAN_IE_COUNTRY pIE_Country
,
533 PWLAN_IE_QUIET pIE_Quiet
,
535 unsigned int uIELength
,
537 void *pRxPacketContext
)
540 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
541 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
542 PSRxMgmtPacket pRxPacket
= (PSRxMgmtPacket
)pRxPacketContext
;
543 signed long ldBm
, ldBmSum
;
544 BOOL bParsingQuiet
= FALSE
;
546 if (pBSSList
== NULL
)
550 HIDWORD(pBSSList
->qwBSSTimestamp
) = cpu_to_le32(HIDWORD(qwTimestamp
));
551 LODWORD(pBSSList
->qwBSSTimestamp
) = cpu_to_le32(LODWORD(qwTimestamp
));
552 pBSSList
->wBeaconInterval
= cpu_to_le16(wBeaconInterval
);
553 pBSSList
->wCapInfo
= cpu_to_le16(wCapInfo
);
554 pBSSList
->uClearCount
= 0;
555 pBSSList
->uChannel
= byCurrChannel
;
557 if (pSSID
->len
> WLAN_SSID_MAXLEN
)
558 pSSID
->len
= WLAN_SSID_MAXLEN
;
560 if ((pSSID
->len
!= 0) && (pSSID
->abySSID
[0] != 0))
561 memcpy(pBSSList
->abySSID
, pSSID
, pSSID
->len
+ WLAN_IEHDR_LEN
);
562 memcpy(pBSSList
->abySuppRates
, pSuppRates
,pSuppRates
->len
+ WLAN_IEHDR_LEN
);
564 if (pExtSuppRates
!= NULL
) {
565 memcpy(pBSSList
->abyExtSuppRates
, pExtSuppRates
,pExtSuppRates
->len
+ WLAN_IEHDR_LEN
);
567 memset(pBSSList
->abyExtSuppRates
, 0, WLAN_IEHDR_LEN
+ WLAN_RATES_MAXLEN
+ 1);
569 pBSSList
->sERP
.byERP
= psERP
->byERP
;
570 pBSSList
->sERP
.bERPExist
= psERP
->bERPExist
;
572 // Check if BSS is 802.11a/b/g
573 if (pBSSList
->uChannel
> CB_MAX_CHANNEL_24G
) {
574 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11A
;
576 if (pBSSList
->sERP
.bERPExist
== TRUE
) {
577 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11G
;
579 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11B
;
583 pBSSList
->byRxRate
= pRxPacket
->byRxRate
;
584 pBSSList
->qwLocalTSF
= pRxPacket
->qwLocalTSF
;
586 pBSSList
->uRSSI
= pRxPacket
->uRSSI
;
587 pBSSList
->bySQ
= pRxPacket
->bySQ
;
589 if ((pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) &&
590 (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
)) {
592 if (pBSSList
== pMgmt
->pCurrBSS
) {
593 bParsingQuiet
= TRUE
;
597 WPA_ClearRSN(pBSSList
); //mike update
599 if (pRSNWPA
!= NULL
) {
600 unsigned int uLen
= pRSNWPA
->len
+ 2;
601 if (uLen
<= (uIELength
-
602 (unsigned int) (ULONG_PTR
) ((PBYTE
) pRSNWPA
- pbyIEs
))) {
603 pBSSList
->wWPALen
= uLen
;
604 memcpy(pBSSList
->byWPAIE
, pRSNWPA
, uLen
);
605 WPA_ParseRSN(pBSSList
, pRSNWPA
);
609 WPA2_ClearRSN(pBSSList
); //mike update
612 unsigned int uLen
= pRSN
->len
+ 2;
613 if (uLen
<= (uIELength
-
614 (unsigned int) (ULONG_PTR
) ((PBYTE
) pRSN
- pbyIEs
))) {
615 pBSSList
->wRSNLen
= uLen
;
616 memcpy(pBSSList
->byRSNIE
, pRSN
, uLen
);
617 WPA2vParseRSN(pBSSList
, pRSN
);
621 if (pRxPacket
->uRSSI
!= 0) {
622 RFvRSSITodBm(pDevice
, (BYTE
)(pRxPacket
->uRSSI
), &ldBm
);
623 // Moniter if RSSI is too strong.
624 pBSSList
->byRSSIStatCnt
++;
625 pBSSList
->byRSSIStatCnt
%= RSSI_STAT_COUNT
;
626 pBSSList
->ldBmAverage
[pBSSList
->byRSSIStatCnt
] = ldBm
;
628 for (ii
= 0, jj
= 0; ii
< RSSI_STAT_COUNT
; ii
++) {
629 if (pBSSList
->ldBmAverage
[ii
] != 0) {
631 max(pBSSList
->ldBmAverage
[ii
], ldBm
);
633 pBSSList
->ldBmAverage
[ii
];
637 pBSSList
->ldBmAverRange
= ldBmSum
/jj
;
640 pBSSList
->uIELength
= uIELength
;
641 if (pBSSList
->uIELength
> WLAN_BEACON_FR_MAXLEN
)
642 pBSSList
->uIELength
= WLAN_BEACON_FR_MAXLEN
;
643 memcpy(pBSSList
->abyIEs
, pbyIEs
, pBSSList
->uIELength
);
654 * Routine Description:
655 * Search Node DB table to find the index of matched DstAddr
662 BOOL
BSSbIsSTAInNodeDB(void *hDeviceContext
,
664 unsigned int *puNodeIndex
)
666 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
667 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
670 // Index = 0 reserved for AP Node
671 for (ii
= 1; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
672 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
673 if (!compare_ether_addr(abyDstAddr
,
674 pMgmt
->sNodeDBTable
[ii
].abyMACAddr
)) {
688 * Routine Description:
689 * Find an empty node and allocated; if no empty found,
690 * instand used of most inactive one.
696 void BSSvCreateOneNode(void *hDeviceContext
, unsigned int *puNodeIndex
)
699 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
700 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
702 unsigned int BigestCount
= 0;
703 unsigned int SelectIndex
;
705 // Index = 0 reserved for AP Node (In STA mode)
706 // Index = 0 reserved for Broadcast/MultiCast (In AP mode)
708 for (ii
= 1; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
709 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
710 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
> BigestCount
) {
711 BigestCount
= pMgmt
->sNodeDBTable
[ii
].uInActiveCount
;
720 // if not found replace uInActiveCount is largest one.
721 if ( ii
== (MAX_NODE_NUM
+ 1)) {
722 *puNodeIndex
= SelectIndex
;
723 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Replace inactive node = %d\n", SelectIndex
);
725 if (pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
.next
!= NULL
) {
726 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
)) != NULL
)
734 memset(&pMgmt
->sNodeDBTable
[*puNodeIndex
], 0, sizeof(KnownNodeDB
));
735 pMgmt
->sNodeDBTable
[*puNodeIndex
].bActive
= TRUE
;
736 pMgmt
->sNodeDBTable
[*puNodeIndex
].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
737 // for AP mode PS queue
738 skb_queue_head_init(&pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
);
739 pMgmt
->sNodeDBTable
[*puNodeIndex
].byAuthSequence
= 0;
740 pMgmt
->sNodeDBTable
[*puNodeIndex
].wEnQueueCnt
= 0;
741 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Create node index = %d\n", ii
);
748 * Routine Description:
749 * Remove Node by NodeIndex
757 void BSSvRemoveOneNode(void *hDeviceContext
, unsigned int uNodeIndex
)
760 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
761 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
762 BYTE byMask
[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
766 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[uNodeIndex
].sTxPSQueue
)) != NULL
)
769 memset(&pMgmt
->sNodeDBTable
[uNodeIndex
], 0, sizeof(KnownNodeDB
));
771 pMgmt
->abyPSTxMap
[pMgmt
->sNodeDBTable
[uNodeIndex
].wAID
>> 3] &= ~byMask
[pMgmt
->sNodeDBTable
[uNodeIndex
].wAID
& 7];
775 * Routine Description:
776 * Update AP Node content in Index 0 of KnownNodeDB
784 void BSSvUpdateAPNode(void *hDeviceContext
,
786 PWLAN_IE_SUPP_RATES pSuppRates
,
787 PWLAN_IE_SUPP_RATES pExtSuppRates
)
789 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
790 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
791 unsigned int uRateLen
= WLAN_RATES_MAXLEN
;
793 memset(&pMgmt
->sNodeDBTable
[0], 0, sizeof(KnownNodeDB
));
795 pMgmt
->sNodeDBTable
[0].bActive
= TRUE
;
796 if (pDevice
->byBBType
== BB_TYPE_11B
) {
797 uRateLen
= WLAN_RATES_MAXLEN_11B
;
799 pMgmt
->abyCurrSuppRates
[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES
)pSuppRates
,
800 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrSuppRates
,
802 pMgmt
->abyCurrExtSuppRates
[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES
)pExtSuppRates
,
803 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrExtSuppRates
,
805 RATEvParseMaxRate((void *) pDevice
,
806 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrSuppRates
,
807 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrExtSuppRates
,
809 &(pMgmt
->sNodeDBTable
[0].wMaxBasicRate
),
810 &(pMgmt
->sNodeDBTable
[0].wMaxSuppRate
),
811 &(pMgmt
->sNodeDBTable
[0].wSuppRate
),
812 &(pMgmt
->sNodeDBTable
[0].byTopCCKBasicRate
),
813 &(pMgmt
->sNodeDBTable
[0].byTopOFDMBasicRate
)
815 memcpy(pMgmt
->sNodeDBTable
[0].abyMACAddr
, pMgmt
->abyCurrBSSID
, WLAN_ADDR_LEN
);
816 pMgmt
->sNodeDBTable
[0].wTxDataRate
= pMgmt
->sNodeDBTable
[0].wMaxSuppRate
;
817 pMgmt
->sNodeDBTable
[0].bShortPreamble
= WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo
);
818 pMgmt
->sNodeDBTable
[0].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
819 // Auto rate fallback function initiation.
820 // RATEbInit(pDevice);
821 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt
->sNodeDBTable
[0].wTxDataRate
);
827 * Routine Description:
828 * Add Multicast Node content in Index 0 of KnownNodeDB
836 void BSSvAddMulticastNode(void *hDeviceContext
)
838 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
839 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
841 if (!pDevice
->bEnableHostWEP
)
842 memset(&pMgmt
->sNodeDBTable
[0], 0, sizeof(KnownNodeDB
));
843 memset(pMgmt
->sNodeDBTable
[0].abyMACAddr
, 0xff, WLAN_ADDR_LEN
);
844 pMgmt
->sNodeDBTable
[0].bActive
= TRUE
;
845 pMgmt
->sNodeDBTable
[0].bPSEnable
= FALSE
;
846 skb_queue_head_init(&pMgmt
->sNodeDBTable
[0].sTxPSQueue
);
847 RATEvParseMaxRate((void *) pDevice
,
848 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrSuppRates
,
849 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrExtSuppRates
,
851 &(pMgmt
->sNodeDBTable
[0].wMaxBasicRate
),
852 &(pMgmt
->sNodeDBTable
[0].wMaxSuppRate
),
853 &(pMgmt
->sNodeDBTable
[0].wSuppRate
),
854 &(pMgmt
->sNodeDBTable
[0].byTopCCKBasicRate
),
855 &(pMgmt
->sNodeDBTable
[0].byTopOFDMBasicRate
)
857 pMgmt
->sNodeDBTable
[0].wTxDataRate
= pMgmt
->sNodeDBTable
[0].wMaxBasicRate
;
858 pMgmt
->sNodeDBTable
[0].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
864 * Routine Description:
867 * Second call back function to update Node DB info & AP link status
875 void BSSvSecondCallBack(void *hDeviceContext
)
877 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
878 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
880 PWLAN_IE_SSID pItemSSID
, pCurrSSID
;
881 unsigned int uSleepySTACnt
= 0;
882 unsigned int uNonShortSlotSTACnt
= 0;
883 unsigned int uLongPreambleSTACnt
= 0;
884 viawget_wpa_header
*wpahdr
;
886 spin_lock_irq(&pDevice
->lock
);
888 pDevice
->uAssocCount
= 0;
890 //Power Saving Mode Tx Burst
891 if ( pDevice
->bEnablePSMode
== TRUE
) {
892 pDevice
->ulPSModeWaitTx
++;
893 if ( pDevice
->ulPSModeWaitTx
>= 2 ) {
894 pDevice
->ulPSModeWaitTx
= 0;
895 pDevice
->bPSModeTxBurst
= FALSE
;
899 pDevice
->byERPFlag
&=
900 ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
902 if (pDevice
->wUseProtectCntDown
> 0) {
903 pDevice
->wUseProtectCntDown
--;
906 // disable protect mode
907 pDevice
->byERPFlag
&= ~(WLAN_SET_ERP_USE_PROTECTION(1));
910 if(pDevice
->byReAssocCount
> 0) {
911 pDevice
->byReAssocCount
++;
912 if((pDevice
->byReAssocCount
> 10) && (pDevice
->bLinkPass
!= TRUE
)) { //10 sec timeout
913 printk("Re-association timeout!!!\n");
914 pDevice
->byReAssocCount
= 0;
915 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
916 // if(pDevice->bWPASuppWextEnabled == TRUE)
918 union iwreq_data wrqu
;
919 memset(&wrqu
, 0, sizeof (wrqu
));
920 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
921 PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
922 wireless_send_event(pDevice
->dev
, SIOCGIWAP
, &wrqu
, NULL
);
926 else if(pDevice
->bLinkPass
== TRUE
)
927 pDevice
->byReAssocCount
= 0;
930 if((pMgmt
->eCurrState
!=WMAC_STATE_ASSOC
) &&
931 (pMgmt
->eLastState
==WMAC_STATE_ASSOC
))
933 union iwreq_data wrqu
;
934 memset(&wrqu
, 0, sizeof(wrqu
));
935 wrqu
.data
.flags
= RT_DISCONNECTED_EVENT_FLAG
;
936 wireless_send_event(pDevice
->dev
, IWEVCUSTOM
, &wrqu
, NULL
);
938 pMgmt
->eLastState
= pMgmt
->eCurrState
;
940 s_uCalculateLinkQual((void *)pDevice
);
942 for (ii
= 0; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
944 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
945 // Increase in-activity counter
946 pMgmt
->sNodeDBTable
[ii
].uInActiveCount
++;
949 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
> MAX_INACTIVE_COUNT
) {
950 BSSvRemoveOneNode(pDevice
, ii
);
951 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
952 "Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT
, ii
);
956 if (pMgmt
->sNodeDBTable
[ii
].eNodeState
>= NODE_ASSOC
) {
958 pDevice
->uAssocCount
++;
960 // check if Non ERP exist
961 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
< ERP_RECOVER_COUNT
) {
962 if (!pMgmt
->sNodeDBTable
[ii
].bShortPreamble
) {
963 pDevice
->byERPFlag
|= WLAN_SET_ERP_BARKER_MODE(1);
964 uLongPreambleSTACnt
++;
966 if (!pMgmt
->sNodeDBTable
[ii
].bERPExist
) {
967 pDevice
->byERPFlag
|= WLAN_SET_ERP_NONERP_PRESENT(1);
968 pDevice
->byERPFlag
|= WLAN_SET_ERP_USE_PROTECTION(1);
970 if (!pMgmt
->sNodeDBTable
[ii
].bShortSlotTime
)
971 uNonShortSlotSTACnt
++;
975 // check if any STA in PS mode
976 if (pMgmt
->sNodeDBTable
[ii
].bPSEnable
)
982 // Rate fallback check
983 if (!pDevice
->bFixRate
) {
985 // ii = 0 for multicast node (AP & Adhoc)
986 RATEvTxRateFallBack((void *)pDevice
,
987 &(pMgmt
->sNodeDBTable
[ii
]));
990 // ii = 0 reserved for unicast AP node (Infra STA)
991 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
)
992 RATEvTxRateFallBack((void *)pDevice
,
993 &(pMgmt
->sNodeDBTable
[ii
]));
998 // check if pending PS queue
999 if (pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
!= 0) {
1000 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Index= %d, Queue = %d pending \n",
1001 ii
, pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
);
1002 if ((ii
>0) && (pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
> 15)) {
1003 BSSvRemoveOneNode(pDevice
, ii
);
1004 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Pending many queues PS STA Index = %d remove \n", ii
);
1013 if ((pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
) && (pDevice
->byBBType
== BB_TYPE_11G
)) {
1015 // on/off protect mode
1016 if (WLAN_GET_ERP_USE_PROTECTION(pDevice
->byERPFlag
)) {
1017 if (!pDevice
->bProtectMode
) {
1018 MACvEnableProtectMD(pDevice
);
1019 pDevice
->bProtectMode
= TRUE
;
1023 if (pDevice
->bProtectMode
) {
1024 MACvDisableProtectMD(pDevice
);
1025 pDevice
->bProtectMode
= FALSE
;
1028 // on/off short slot time
1030 if (uNonShortSlotSTACnt
> 0) {
1031 if (pDevice
->bShortSlotTime
) {
1032 pDevice
->bShortSlotTime
= FALSE
;
1033 BBvSetShortSlotTime(pDevice
);
1034 vUpdateIFS((void *)pDevice
);
1038 if (!pDevice
->bShortSlotTime
) {
1039 pDevice
->bShortSlotTime
= TRUE
;
1040 BBvSetShortSlotTime(pDevice
);
1041 vUpdateIFS((void *)pDevice
);
1045 // on/off barker long preamble mode
1047 if (uLongPreambleSTACnt
> 0) {
1048 if (!pDevice
->bBarkerPreambleMd
) {
1049 MACvEnableBarkerPreambleMd(pDevice
);
1050 pDevice
->bBarkerPreambleMd
= TRUE
;
1054 if (pDevice
->bBarkerPreambleMd
) {
1055 MACvDisableBarkerPreambleMd(pDevice
);
1056 pDevice
->bBarkerPreambleMd
= FALSE
;
1063 // Check if any STA in PS mode, enable DTIM multicast deliver
1064 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
) {
1065 if (uSleepySTACnt
> 0)
1066 pMgmt
->sNodeDBTable
[0].bPSEnable
= TRUE
;
1068 pMgmt
->sNodeDBTable
[0].bPSEnable
= FALSE
;
1071 pItemSSID
= (PWLAN_IE_SSID
)pMgmt
->abyDesireSSID
;
1072 pCurrSSID
= (PWLAN_IE_SSID
)pMgmt
->abyCurrSSID
;
1074 if ((pMgmt
->eCurrMode
== WMAC_MODE_STANDBY
) ||
1075 (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
)) {
1077 if (pMgmt
->sNodeDBTable
[0].bActive
) { // Assoc with BSS
1079 if (pDevice
->bUpdateBBVGA
) {
1080 /* s_vCheckSensitivity((void *) pDevice); */
1081 s_vCheckPreEDThreshold((void *) pDevice
);
1084 if ((pMgmt
->sNodeDBTable
[0].uInActiveCount
>= (LOST_BEACON_COUNT
/2)) &&
1085 (pDevice
->byBBVGACurrent
!= pDevice
->abyBBVGA
[0]) ) {
1086 pDevice
->byBBVGANew
= pDevice
->abyBBVGA
[0];
1087 bScheduleCommand((void *) pDevice
,
1088 WLAN_CMD_CHANGE_BBSENSITIVITY
,
1092 if (pMgmt
->sNodeDBTable
[0].uInActiveCount
>= LOST_BEACON_COUNT
) {
1093 pMgmt
->sNodeDBTable
[0].bActive
= FALSE
;
1094 pMgmt
->eCurrMode
= WMAC_MODE_STANDBY
;
1095 pMgmt
->eCurrState
= WMAC_STATE_IDLE
;
1096 netif_stop_queue(pDevice
->dev
);
1097 pDevice
->bLinkPass
= FALSE
;
1098 ControlvMaskByte(pDevice
,MESSAGE_REQUEST_MACREG
,MAC_REG_PAPEDELAY
,LEDSTS_STS
,LEDSTS_SLOW
);
1099 pDevice
->bRoaming
= TRUE
;
1100 pDevice
->bIsRoaming
= FALSE
;
1102 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Lost AP beacon [%d] sec, disconnected !\n", pMgmt
->sNodeDBTable
[0].uInActiveCount
);
1103 /* let wpa supplicant know AP may disconnect */
1104 if ((pDevice
->bWPADEVUp
) && (pDevice
->skb
!= NULL
)) {
1105 wpahdr
= (viawget_wpa_header
*)pDevice
->skb
->data
;
1106 wpahdr
->type
= VIAWGET_DISASSOC_MSG
;
1107 wpahdr
->resp_ie_len
= 0;
1108 wpahdr
->req_ie_len
= 0;
1109 skb_put(pDevice
->skb
, sizeof(viawget_wpa_header
));
1110 pDevice
->skb
->dev
= pDevice
->wpadev
;
1111 skb_reset_mac_header(pDevice
->skb
);
1112 pDevice
->skb
->pkt_type
= PACKET_HOST
;
1113 pDevice
->skb
->protocol
= htons(ETH_P_802_2
);
1114 memset(pDevice
->skb
->cb
, 0, sizeof(pDevice
->skb
->cb
));
1115 netif_rx(pDevice
->skb
);
1116 pDevice
->skb
= dev_alloc_skb((int)pDevice
->rx_buf_sz
);
1118 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1120 union iwreq_data wrqu
;
1121 memset(&wrqu
, 0, sizeof (wrqu
));
1122 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1123 PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
1124 wireless_send_event(pDevice
->dev
, SIOCGIWAP
, &wrqu
, NULL
);
1129 else if (pItemSSID
->len
!= 0) {
1131 if ((pDevice
->bEnableRoaming
== TRUE
)&&(!(pMgmt
->Cisco_cckm
))) {
1132 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"bRoaming %d, !\n", pDevice
->bRoaming
);
1133 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"bIsRoaming %d, !\n", pDevice
->bIsRoaming
);
1134 if ((pDevice
->bRoaming
== TRUE
)&&(pDevice
->bIsRoaming
== TRUE
)){
1135 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Fast Roaming ...\n");
1136 BSSvClearBSSList((void *) pDevice
, pDevice
->bLinkPass
);
1137 bScheduleCommand((void *) pDevice
,
1138 WLAN_CMD_BSSID_SCAN
,
1139 pMgmt
->abyDesireSSID
);
1140 bScheduleCommand((void *) pDevice
,
1142 pMgmt
->abyDesireSSID
);
1143 pDevice
->uAutoReConnectTime
= 0;
1144 pDevice
->uIsroamingTime
= 0;
1145 pDevice
->bRoaming
= FALSE
;
1147 wpahdr
= (viawget_wpa_header
*)pDevice
->skb
->data
;
1148 wpahdr
->type
= VIAWGET_CCKM_ROAM_MSG
;
1149 wpahdr
->resp_ie_len
= 0;
1150 wpahdr
->req_ie_len
= 0;
1151 skb_put(pDevice
->skb
, sizeof(viawget_wpa_header
));
1152 pDevice
->skb
->dev
= pDevice
->wpadev
;
1153 skb_reset_mac_header(pDevice
->skb
);
1154 pDevice
->skb
->pkt_type
= PACKET_HOST
;
1155 pDevice
->skb
->protocol
= htons(ETH_P_802_2
);
1156 memset(pDevice
->skb
->cb
, 0, sizeof(pDevice
->skb
->cb
));
1157 netif_rx(pDevice
->skb
);
1158 pDevice
->skb
= dev_alloc_skb((int)pDevice
->rx_buf_sz
);
1161 else if ((pDevice
->bRoaming
== FALSE
)&&(pDevice
->bIsRoaming
== TRUE
)) {
1162 pDevice
->uIsroamingTime
++;
1163 if (pDevice
->uIsroamingTime
>= 20)
1164 pDevice
->bIsRoaming
= FALSE
;
1169 if (pDevice
->uAutoReConnectTime
< 10) {
1170 pDevice
->uAutoReConnectTime
++;
1171 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1172 //network manager support need not do Roaming scan???
1173 if(pDevice
->bWPASuppWextEnabled
==TRUE
)
1174 pDevice
->uAutoReConnectTime
= 0;
1178 //mike use old encryption status for wpa reauthen
1179 if(pDevice
->bWPADEVUp
)
1180 pDevice
->eEncryptionStatus
= pDevice
->eOldEncryptionStatus
;
1182 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Roaming ...\n");
1183 BSSvClearBSSList((void *) pDevice
, pDevice
->bLinkPass
);
1184 pMgmt
->eScanType
= WMAC_SCAN_ACTIVE
;
1185 bScheduleCommand((void *) pDevice
,
1186 WLAN_CMD_BSSID_SCAN
,
1187 pMgmt
->abyDesireSSID
);
1188 bScheduleCommand((void *) pDevice
,
1190 pMgmt
->abyDesireSSID
);
1191 pDevice
->uAutoReConnectTime
= 0;
1197 if (pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) {
1198 // if adhoc started which essid is NULL string, rescaning.
1199 if ((pMgmt
->eCurrState
== WMAC_STATE_STARTED
) && (pCurrSSID
->len
== 0)) {
1200 if (pDevice
->uAutoReConnectTime
< 10) {
1201 pDevice
->uAutoReConnectTime
++;
1204 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Adhoc re-scaning ...\n");
1205 pMgmt
->eScanType
= WMAC_SCAN_ACTIVE
;
1206 bScheduleCommand((void *) pDevice
, WLAN_CMD_BSSID_SCAN
, NULL
);
1207 bScheduleCommand((void *) pDevice
, WLAN_CMD_SSID
, NULL
);
1208 pDevice
->uAutoReConnectTime
= 0;
1211 if (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
) {
1213 if (pDevice
->bUpdateBBVGA
) {
1214 /* s_vCheckSensitivity((void *) pDevice); */
1215 s_vCheckPreEDThreshold((void *) pDevice
);
1217 if (pMgmt
->sNodeDBTable
[0].uInActiveCount
>=ADHOC_LOST_BEACON_COUNT
) {
1218 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Lost other STA beacon [%d] sec, started !\n", pMgmt
->sNodeDBTable
[0].uInActiveCount
);
1219 pMgmt
->sNodeDBTable
[0].uInActiveCount
= 0;
1220 pMgmt
->eCurrState
= WMAC_STATE_STARTED
;
1221 netif_stop_queue(pDevice
->dev
);
1222 pDevice
->bLinkPass
= FALSE
;
1223 ControlvMaskByte(pDevice
,MESSAGE_REQUEST_MACREG
,MAC_REG_PAPEDELAY
,LEDSTS_STS
,LEDSTS_SLOW
);
1228 if (pDevice
->bLinkPass
== TRUE
) {
1229 if (netif_queue_stopped(pDevice
->dev
))
1230 netif_wake_queue(pDevice
->dev
);
1233 spin_unlock_irq(&pDevice
->lock
);
1235 pMgmt
->sTimerSecondCallback
.expires
= RUN_AT(HZ
);
1236 add_timer(&pMgmt
->sTimerSecondCallback
);
1241 * Routine Description:
1244 * Update Tx attemps, Tx failure counter in Node DB
1252 void BSSvUpdateNodeTxCounter(void *hDeviceContext
,
1253 PSStatCounter pStatistic
,
1257 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1258 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
1259 unsigned int uNodeIndex
= 0;
1262 WORD wFallBackRate
= RATE_1M
;
1269 byPktNum
= (byPktNO
& 0x0F) >> 4;
1270 byTxRetry
= (byTSR
& 0xF0) >> 4;
1271 wRate
= (WORD
) (byPktNO
& 0xF0) >> 4;
1272 wFIFOCtl
= pStatistic
->abyTxPktInfo
[byPktNum
].wFIFOCtl
;
1273 pbyDestAddr
= (PBYTE
) &( pStatistic
->abyTxPktInfo
[byPktNum
].abyDestAddr
[0]);
1275 if (wFIFOCtl
& FIFOCTL_AUTO_FB_0
) {
1276 byFallBack
= AUTO_FB_0
;
1277 } else if (wFIFOCtl
& FIFOCTL_AUTO_FB_1
) {
1278 byFallBack
= AUTO_FB_1
;
1280 byFallBack
= AUTO_FB_NONE
;
1283 // Only Unicast using support rates
1284 if (wFIFOCtl
& FIFOCTL_NEEDACK
) {
1285 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) {
1286 pMgmt
->sNodeDBTable
[0].uTxAttempts
+= 1;
1287 if ( !(byTSR
& (TSR_TMO
| TSR_RETRYTMO
))) {
1288 // transmit success, TxAttempts at least plus one
1289 pMgmt
->sNodeDBTable
[0].uTxOk
[MAX_RATE
]++;
1290 if ( (byFallBack
== AUTO_FB_NONE
) ||
1291 (wRate
< RATE_18M
) ) {
1292 wFallBackRate
= wRate
;
1293 } else if (byFallBack
== AUTO_FB_0
) {
1295 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][byTxRetry
];
1297 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][4];
1298 } else if (byFallBack
== AUTO_FB_1
) {
1300 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][byTxRetry
];
1302 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1304 pMgmt
->sNodeDBTable
[0].uTxOk
[wFallBackRate
]++;
1306 pMgmt
->sNodeDBTable
[0].uTxFailures
++;
1308 pMgmt
->sNodeDBTable
[0].uTxRetry
+= byTxRetry
;
1309 if (byTxRetry
!= 0) {
1310 pMgmt
->sNodeDBTable
[0].uTxFail
[MAX_RATE
]+=byTxRetry
;
1311 if ( (byFallBack
== AUTO_FB_NONE
) ||
1312 (wRate
< RATE_18M
) ) {
1313 pMgmt
->sNodeDBTable
[0].uTxFail
[wRate
]+=byTxRetry
;
1314 } else if (byFallBack
== AUTO_FB_0
) {
1315 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1318 awHWRetry0
[wRate
-RATE_18M
][ii
];
1321 awHWRetry0
[wRate
-RATE_18M
][4];
1322 pMgmt
->sNodeDBTable
[0].uTxFail
[wFallBackRate
]++;
1324 } else if (byFallBack
== AUTO_FB_1
) {
1325 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1328 awHWRetry1
[wRate
-RATE_18M
][ii
];
1331 awHWRetry1
[wRate
-RATE_18M
][4];
1332 pMgmt
->sNodeDBTable
[0].uTxFail
[wFallBackRate
]++;
1338 if ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) ||
1339 (pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
)) {
1341 if (BSSbIsSTAInNodeDB((void *) pDevice
,
1344 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxAttempts
+= 1;
1345 if ( !(byTSR
& (TSR_TMO
| TSR_RETRYTMO
))) {
1346 // transmit success, TxAttempts at least plus one
1347 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxOk
[MAX_RATE
]++;
1348 if ( (byFallBack
== AUTO_FB_NONE
) ||
1349 (wRate
< RATE_18M
) ) {
1350 wFallBackRate
= wRate
;
1351 } else if (byFallBack
== AUTO_FB_0
) {
1353 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][byTxRetry
];
1355 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][4];
1356 } else if (byFallBack
== AUTO_FB_1
) {
1358 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][byTxRetry
];
1360 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1362 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxOk
[wFallBackRate
]++;
1364 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFailures
++;
1366 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxRetry
+= byTxRetry
;
1367 if (byTxRetry
!= 0) {
1368 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[MAX_RATE
]+=byTxRetry
;
1369 if ( (byFallBack
== AUTO_FB_NONE
) ||
1370 (wRate
< RATE_18M
) ) {
1371 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wRate
]+=byTxRetry
;
1372 } else if (byFallBack
== AUTO_FB_0
) {
1373 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1376 awHWRetry0
[wRate
-RATE_18M
][ii
];
1379 awHWRetry0
[wRate
-RATE_18M
][4];
1380 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wFallBackRate
]++;
1382 } else if (byFallBack
== AUTO_FB_1
) {
1383 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1385 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][ii
];
1387 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1388 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wFallBackRate
]++;
1399 * Routine Description:
1400 * Clear Nodes & skb in DB Table
1405 * hDeviceContext - The adapter context.
1406 * uStartIndex - starting index
1415 void BSSvClearNodeDBTable(void *hDeviceContext
,
1416 unsigned int uStartIndex
)
1418 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1419 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
1420 struct sk_buff
*skb
;
1423 for (ii
= uStartIndex
; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
1424 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
1425 // check if sTxPSQueue has been initial
1426 if (pMgmt
->sNodeDBTable
[ii
].sTxPSQueue
.next
!= NULL
) {
1427 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[ii
].sTxPSQueue
)) != NULL
){
1428 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"PS skb != NULL %d\n", ii
);
1432 memset(&pMgmt
->sNodeDBTable
[ii
], 0, sizeof(KnownNodeDB
));
1437 void s_vCheckSensitivity(void *hDeviceContext
)
1439 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1440 PKnownBSS pBSSList
= NULL
;
1441 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
1444 if ((pMgmt
->eCurrState
== WMAC_STATE_ASSOC
) ||
1445 ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) && (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
))) {
1446 pBSSList
= BSSpAddrIsInBSSList(pDevice
, pMgmt
->abyCurrBSSID
, (PWLAN_IE_SSID
)pMgmt
->abyCurrSSID
);
1447 if (pBSSList
!= NULL
) {
1448 /* Update BB register if RSSI is too strong */
1449 signed long LocalldBmAverage
= 0;
1450 signed long uNumofdBm
= 0;
1451 for (ii
= 0; ii
< RSSI_STAT_COUNT
; ii
++) {
1452 if (pBSSList
->ldBmAverage
[ii
] != 0) {
1454 LocalldBmAverage
+= pBSSList
->ldBmAverage
[ii
];
1457 if (uNumofdBm
> 0) {
1458 LocalldBmAverage
= LocalldBmAverage
/uNumofdBm
;
1459 for (ii
=0;ii
<BB_VGA_LEVEL
;ii
++) {
1460 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage
, pDevice
->ldBmThreshold
[ii
], pDevice
->abyBBVGA
[ii
]);
1461 if (LocalldBmAverage
< pDevice
->ldBmThreshold
[ii
]) {
1462 pDevice
->byBBVGANew
= pDevice
->abyBBVGA
[ii
];
1466 if (pDevice
->byBBVGANew
!= pDevice
->byBBVGACurrent
) {
1467 pDevice
->uBBVGADiffCount
++;
1468 if (pDevice
->uBBVGADiffCount
>= BB_VGA_CHANGE_THRESHOLD
)
1469 bScheduleCommand((void *) pDevice
,
1470 WLAN_CMD_CHANGE_BBSENSITIVITY
,
1473 pDevice
->uBBVGADiffCount
= 0;
1480 void s_uCalculateLinkQual(void *hDeviceContext
)
1482 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1483 unsigned long TxOkRatio
, TxCnt
;
1484 unsigned long RxOkRatio
, RxCnt
;
1485 unsigned long RssiRatio
;
1488 TxCnt
= pDevice
->scStatistic
.TxNoRetryOkCount
+
1489 pDevice
->scStatistic
.TxRetryOkCount
+
1490 pDevice
->scStatistic
.TxFailCount
;
1491 RxCnt
= pDevice
->scStatistic
.RxFcsErrCnt
+
1492 pDevice
->scStatistic
.RxOkCnt
;
1493 TxOkRatio
= (TxCnt
< 6) ? 4000:((pDevice
->scStatistic
.TxNoRetryOkCount
* 4000) / TxCnt
);
1494 RxOkRatio
= (RxCnt
< 6) ? 2000:((pDevice
->scStatistic
.RxOkCnt
* 2000) / RxCnt
);
1495 //decide link quality
1496 if(pDevice
->bLinkPass
!=TRUE
)
1498 pDevice
->scStatistic
.LinkQuality
= 0;
1499 pDevice
->scStatistic
.SignalStren
= 0;
1503 RFvRSSITodBm(pDevice
, (BYTE
)(pDevice
->uCurrRSSI
), &ldBm
);
1507 else if(-ldBm
> 90) {
1511 RssiRatio
= (40-(-ldBm
-50))*4000/40;
1513 pDevice
->scStatistic
.SignalStren
= RssiRatio
/40;
1514 pDevice
->scStatistic
.LinkQuality
= (RssiRatio
+TxOkRatio
+RxOkRatio
)/100;
1516 pDevice
->scStatistic
.RxFcsErrCnt
= 0;
1517 pDevice
->scStatistic
.RxOkCnt
= 0;
1518 pDevice
->scStatistic
.TxFailCount
= 0;
1519 pDevice
->scStatistic
.TxNoRetryOkCount
= 0;
1520 pDevice
->scStatistic
.TxRetryOkCount
= 0;
1523 void BSSvClearAnyBSSJoinRecord(void *hDeviceContext
)
1525 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1526 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
1529 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++)
1530 pMgmt
->sBSSList
[ii
].bSelected
= FALSE
;
1533 void s_vCheckPreEDThreshold(void *hDeviceContext
)
1535 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1536 PKnownBSS pBSSList
= NULL
;
1537 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
1539 if ((pMgmt
->eCurrState
== WMAC_STATE_ASSOC
) ||
1540 ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) && (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
))) {
1541 pBSSList
= BSSpAddrIsInBSSList(pDevice
, pMgmt
->abyCurrBSSID
, (PWLAN_IE_SSID
)pMgmt
->abyCurrSSID
);
1542 if (pBSSList
!= NULL
) {
1543 pDevice
->byBBPreEDRSSI
= (BYTE
) (~(pBSSList
->ldBmAverRange
) + 1);
1544 BBvUpdatePreEDThreshold(pDevice
, FALSE
);