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 int msglevel
=MSG_LEVEL_INFO
;
63 //static int msglevel =MSG_LEVEL_DEBUG;
65 static const u16 awHWRetry0
[5][5] = {
66 {RATE_18M
, RATE_18M
, RATE_12M
, RATE_12M
, RATE_12M
},
67 {RATE_24M
, RATE_24M
, RATE_18M
, RATE_12M
, RATE_12M
},
68 {RATE_36M
, RATE_36M
, RATE_24M
, RATE_18M
, RATE_18M
},
69 {RATE_48M
, RATE_48M
, RATE_36M
, RATE_24M
, RATE_24M
},
70 {RATE_54M
, RATE_54M
, RATE_48M
, RATE_36M
, RATE_36M
}
72 static const u16 awHWRetry1
[5][5] = {
73 {RATE_18M
, RATE_18M
, RATE_12M
, RATE_6M
, RATE_6M
},
74 {RATE_24M
, RATE_24M
, RATE_18M
, RATE_6M
, RATE_6M
},
75 {RATE_36M
, RATE_36M
, RATE_24M
, RATE_12M
, RATE_12M
},
76 {RATE_48M
, RATE_48M
, RATE_24M
, RATE_12M
, RATE_12M
},
77 {RATE_54M
, RATE_54M
, RATE_36M
, RATE_18M
, RATE_18M
}
80 static void s_vCheckSensitivity(struct vnt_private
*pDevice
);
81 static void s_vCheckPreEDThreshold(struct vnt_private
*pDevice
);
82 static void s_uCalculateLinkQual(struct vnt_private
*pDevice
);
86 * Routine Description:
87 * Search known BSS list for Desire SSID or BSSID.
90 * PTR to KnownBSS or NULL
94 PKnownBSS
BSSpSearchBSSList(struct vnt_private
*pDevice
,
95 u8
*pbyDesireBSSID
, u8
*pbyDesireSSID
,
96 CARD_PHY_TYPE ePhyType
)
98 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
100 PWLAN_IE_SSID pSSID
= NULL
;
101 PKnownBSS pCurrBSS
= NULL
;
102 PKnownBSS pSelect
= NULL
;
103 u8 ZeroBSSID
[WLAN_BSSID_LEN
] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
107 if (pbyDesireBSSID
!= NULL
) {
108 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
109 "BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID
);
110 if ((!is_broadcast_ether_addr(pbyDesireBSSID
)) &&
111 (memcmp(pbyDesireBSSID
, ZeroBSSID
, 6)!= 0)){
112 pbyBSSID
= pbyDesireBSSID
;
115 if (pbyDesireSSID
!= NULL
) {
116 if (((PWLAN_IE_SSID
)pbyDesireSSID
)->len
!= 0) {
117 pSSID
= (PWLAN_IE_SSID
) pbyDesireSSID
;
121 if ((pbyBSSID
!= NULL
)&&(pDevice
->bRoaming
== false)) {
123 for (ii
= 0; ii
<MAX_BSS_NUM
; ii
++) {
124 pCurrBSS
= &(pMgmt
->sBSSList
[ii
]);
126 pCurrBSS
->bSelected
= false;
128 if ((pCurrBSS
->bActive
) &&
129 (pCurrBSS
->bSelected
== false)) {
130 if (ether_addr_equal(pCurrBSS
->abyBSSID
, pbyBSSID
)) {
133 if ( !memcmp(pSSID
->abySSID
,
134 ((PWLAN_IE_SSID
)pCurrBSS
->abySSID
)->abySSID
,
136 if ((pMgmt
->eConfigMode
== WMAC_CONFIG_AUTO
) ||
137 ((pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
)) ||
138 ((pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
) && WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
))
140 pCurrBSS
->bSelected
= true;
145 if ((pMgmt
->eConfigMode
== WMAC_CONFIG_AUTO
) ||
146 ((pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
)) ||
147 ((pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
) && WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
))
149 pCurrBSS
->bSelected
= true;
158 for (ii
= 0; ii
<MAX_BSS_NUM
; ii
++) {
159 pCurrBSS
= &(pMgmt
->sBSSList
[ii
]);
161 //2007-0721-01<Mark>by MikeLiu
162 // if ((pCurrBSS->bActive) &&
163 // (pCurrBSS->bSelected == false)) {
165 pCurrBSS
->bSelected
= false;
166 if (pCurrBSS
->bActive
) {
170 if (memcmp(pSSID
->abySSID
,
171 ((PWLAN_IE_SSID
)pCurrBSS
->abySSID
)->abySSID
,
173 (pSSID
->len
!= ((PWLAN_IE_SSID
)pCurrBSS
->abySSID
)->len
)) {
174 // SSID not match skip this BSS
178 if (((pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
) && WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
)) ||
179 ((pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
))
181 // Type not match skip this BSS
182 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt
->eConfigMode
, pCurrBSS
->wCapInfo
);
186 if (ePhyType
!= PHY_TYPE_AUTO
) {
187 if (((ePhyType
== PHY_TYPE_11A
) && (PHY_TYPE_11A
!= pCurrBSS
->eNetworkTypeInUse
)) ||
188 ((ePhyType
!= PHY_TYPE_11A
) && (PHY_TYPE_11A
== pCurrBSS
->eNetworkTypeInUse
))) {
189 // PhyType not match skip this BSS
190 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType
, pCurrBSS
->eNetworkTypeInUse
);
195 pMgmt
->pSameBSS
[jj
].uChannel
= pCurrBSS
->uChannel
;
196 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
197 "BSSpSearchBSSList pSelect1[%pM]\n",
201 if (pSelect
== NULL
) {
204 // compare RSSI, select the strongest signal
205 if (pCurrBSS
->uRSSI
< pSelect
->uRSSI
) {
212 pDevice
->bSameBSSMaxNum
= jj
;
214 if (pSelect
!= NULL
) {
215 pSelect
->bSelected
= true;
216 if (pDevice
->bRoaming
== false) {
217 // Einsn Add @20070907
218 memcpy(pbyDesireSSID
,pCurrBSS
->abySSID
,WLAN_IEHDR_LEN
+ WLAN_SSID_MAXLEN
+ 1) ;
230 * Routine Description:
238 void BSSvClearBSSList(struct vnt_private
*pDevice
, int bKeepCurrBSSID
)
240 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
243 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
244 if (bKeepCurrBSSID
) {
245 if (pMgmt
->sBSSList
[ii
].bActive
&&
246 ether_addr_equal(pMgmt
->sBSSList
[ii
].abyBSSID
,
247 pMgmt
->abyCurrBSSID
)) {
248 //mike mark: there are two BSSID's in list. If that AP is in hidden ssid mode, one SSID is null,
249 // but other's might not be obvious, so if it associate's with your STA,
250 // you must keep the two of them!!
251 // bKeepCurrBSSID = false;
256 pMgmt
->sBSSList
[ii
].bActive
= false;
257 memset(&pMgmt
->sBSSList
[ii
], 0, sizeof(KnownBSS
));
259 BSSvClearAnyBSSJoinRecord(pDevice
);
264 * Routine Description:
265 * search BSS list by BSSID & SSID if matched
271 PKnownBSS
BSSpAddrIsInBSSList(struct vnt_private
*pDevice
,
272 u8
*abyBSSID
, PWLAN_IE_SSID pSSID
)
274 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
275 PKnownBSS pBSSList
= NULL
;
278 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
279 pBSSList
= &(pMgmt
->sBSSList
[ii
]);
280 if (pBSSList
->bActive
) {
281 if (ether_addr_equal(pBSSList
->abyBSSID
, abyBSSID
)) {
282 if (pSSID
->len
== ((PWLAN_IE_SSID
)pBSSList
->abySSID
)->len
){
283 if (memcmp(pSSID
->abySSID
,
284 ((PWLAN_IE_SSID
)pBSSList
->abySSID
)->abySSID
,
297 * Routine Description:
298 * Insert a BSS set into known BSS list
305 int BSSbInsertToBSSList(struct vnt_private
*pDevice
,
312 PWLAN_IE_SUPP_RATES pSuppRates
,
313 PWLAN_IE_SUPP_RATES pExtSuppRates
,
316 PWLAN_IE_RSN_EXT pRSNWPA
,
317 PWLAN_IE_COUNTRY pIE_Country
,
318 PWLAN_IE_QUIET pIE_Quiet
,
321 void *pRxPacketContext
)
323 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
324 struct vnt_rx_mgmt
*pRxPacket
=
325 (struct vnt_rx_mgmt
*)pRxPacketContext
;
326 PKnownBSS pBSSList
= NULL
;
328 bool bParsingQuiet
= false;
330 pBSSList
= (PKnownBSS
)&(pMgmt
->sBSSList
[0]);
332 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
333 pBSSList
= (PKnownBSS
)&(pMgmt
->sBSSList
[ii
]);
334 if (!pBSSList
->bActive
)
338 if (ii
== MAX_BSS_NUM
){
339 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Get free KnowBSS node failed.\n");
343 pBSSList
->bActive
= true;
344 memcpy( pBSSList
->abyBSSID
, abyBSSIDAddr
, WLAN_BSSID_LEN
);
345 pBSSList
->qwBSSTimestamp
= cpu_to_le64(qwTimestamp
);
346 pBSSList
->wBeaconInterval
= cpu_to_le16(wBeaconInterval
);
347 pBSSList
->wCapInfo
= cpu_to_le16(wCapInfo
);
348 pBSSList
->uClearCount
= 0;
350 if (pSSID
->len
> WLAN_SSID_MAXLEN
)
351 pSSID
->len
= WLAN_SSID_MAXLEN
;
352 memcpy( pBSSList
->abySSID
, pSSID
, pSSID
->len
+ WLAN_IEHDR_LEN
);
354 pBSSList
->uChannel
= byCurrChannel
;
356 if (pSuppRates
->len
> WLAN_RATES_MAXLEN
)
357 pSuppRates
->len
= WLAN_RATES_MAXLEN
;
358 memcpy( pBSSList
->abySuppRates
, pSuppRates
, pSuppRates
->len
+ WLAN_IEHDR_LEN
);
360 if (pExtSuppRates
!= NULL
) {
361 if (pExtSuppRates
->len
> WLAN_RATES_MAXLEN
)
362 pExtSuppRates
->len
= WLAN_RATES_MAXLEN
;
363 memcpy(pBSSList
->abyExtSuppRates
, pExtSuppRates
, pExtSuppRates
->len
+ WLAN_IEHDR_LEN
);
364 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates
->len
);
367 memset(pBSSList
->abyExtSuppRates
, 0, WLAN_IEHDR_LEN
+ WLAN_RATES_MAXLEN
+ 1);
369 pBSSList
->sERP
.byERP
= psERP
->byERP
;
370 pBSSList
->sERP
.bERPExist
= psERP
->bERPExist
;
372 // Check if BSS is 802.11a/b/g
373 if (pBSSList
->uChannel
> CB_MAX_CHANNEL_24G
) {
374 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11A
;
376 if (pBSSList
->sERP
.bERPExist
== true) {
377 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11G
;
379 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11B
;
383 pBSSList
->byRxRate
= pRxPacket
->byRxRate
;
384 pBSSList
->qwLocalTSF
= pRxPacket
->qwLocalTSF
;
385 pBSSList
->uRSSI
= pRxPacket
->uRSSI
;
386 pBSSList
->bySQ
= pRxPacket
->bySQ
;
388 if ((pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) &&
389 (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
)) {
391 if (pBSSList
== pMgmt
->pCurrBSS
) {
392 bParsingQuiet
= true;
396 WPA_ClearRSN(pBSSList
);
398 if (pRSNWPA
!= NULL
) {
399 unsigned int uLen
= pRSNWPA
->len
+ 2;
401 if (uLen
<= (uIELength
-
402 (unsigned int) (u32
) ((u8
*) pRSNWPA
- pbyIEs
))) {
403 pBSSList
->wWPALen
= uLen
;
404 memcpy(pBSSList
->byWPAIE
, pRSNWPA
, uLen
);
405 WPA_ParseRSN(pBSSList
, pRSNWPA
);
409 WPA2_ClearRSN(pBSSList
);
412 unsigned int uLen
= pRSN
->len
+ 2;
414 if (uLen
<= (uIELength
-
415 (unsigned int) (u32
) ((u8
*) pRSN
- pbyIEs
))) {
416 pBSSList
->wRSNLen
= uLen
;
417 memcpy(pBSSList
->byRSNIE
, pRSN
, uLen
);
418 WPA2vParseRSN(pBSSList
, pRSN
);
422 if ((pMgmt
->eAuthenMode
== WMAC_AUTH_WPA2
) || (pBSSList
->bWPA2Valid
== true)) {
424 PSKeyItem pTransmitKey
= NULL
;
425 bool bIs802_1x
= false;
427 for (ii
= 0; ii
< pBSSList
->wAKMSSAuthCount
; ii
++) {
428 if (pBSSList
->abyAKMSSAuthType
[ii
] == WLAN_11i_AKMSS_802_1X
) {
433 if ((bIs802_1x
== true) && (pSSID
->len
== ((PWLAN_IE_SSID
)pMgmt
->abyDesireSSID
)->len
) &&
434 ( !memcmp(pSSID
->abySSID
, ((PWLAN_IE_SSID
)pMgmt
->abyDesireSSID
)->abySSID
, pSSID
->len
))) {
436 bAdd_PMKID_Candidate((void *) pDevice
,
438 &pBSSList
->sRSNCapObj
);
440 if ((pDevice
->bLinkPass
== true) && (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
)) {
441 if ((KeybGetTransmitKey(&(pDevice
->sKey
), pDevice
->abyBSSID
, PAIRWISE_KEY
, &pTransmitKey
) == true) ||
442 (KeybGetTransmitKey(&(pDevice
->sKey
), pDevice
->abyBSSID
, GROUP_KEY
, &pTransmitKey
) == true)) {
443 pDevice
->gsPMKIDCandidate
.StatusType
= Ndis802_11StatusType_PMKID_CandidateList
;
444 pDevice
->gsPMKIDCandidate
.Version
= 1;
452 if (pDevice
->bUpdateBBVGA
) {
453 // Monitor if RSSI is too strong.
454 pBSSList
->byRSSIStatCnt
= 0;
455 RFvRSSITodBm(pDevice
, (u8
)(pRxPacket
->uRSSI
), &pBSSList
->ldBmMAX
);
456 pBSSList
->ldBmAverage
[0] = pBSSList
->ldBmMAX
;
457 pBSSList
->ldBmAverRange
= pBSSList
->ldBmMAX
;
458 for (ii
= 1; ii
< RSSI_STAT_COUNT
; ii
++)
459 pBSSList
->ldBmAverage
[ii
] = 0;
462 pBSSList
->uIELength
= uIELength
;
463 if (pBSSList
->uIELength
> WLAN_BEACON_FR_MAXLEN
)
464 pBSSList
->uIELength
= WLAN_BEACON_FR_MAXLEN
;
465 memcpy(pBSSList
->abyIEs
, pbyIEs
, pBSSList
->uIELength
);
472 * Routine Description:
473 * Update BSS set in known BSS list
479 // TODO: input structure modify
481 int BSSbUpdateToBSSList(struct vnt_private
*pDevice
,
488 PWLAN_IE_SUPP_RATES pSuppRates
,
489 PWLAN_IE_SUPP_RATES pExtSuppRates
,
492 PWLAN_IE_RSN_EXT pRSNWPA
,
493 PWLAN_IE_COUNTRY pIE_Country
,
494 PWLAN_IE_QUIET pIE_Quiet
,
498 void *pRxPacketContext
)
500 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
501 struct vnt_rx_mgmt
*pRxPacket
=
502 (struct vnt_rx_mgmt
*)pRxPacketContext
;
504 signed long ldBm
, ldBmSum
;
505 bool bParsingQuiet
= false;
507 if (pBSSList
== NULL
)
510 pBSSList
->qwBSSTimestamp
= cpu_to_le64(qwTimestamp
);
512 pBSSList
->wBeaconInterval
= cpu_to_le16(wBeaconInterval
);
513 pBSSList
->wCapInfo
= cpu_to_le16(wCapInfo
);
514 pBSSList
->uClearCount
= 0;
515 pBSSList
->uChannel
= byCurrChannel
;
517 if (pSSID
->len
> WLAN_SSID_MAXLEN
)
518 pSSID
->len
= WLAN_SSID_MAXLEN
;
520 if ((pSSID
->len
!= 0) && (pSSID
->abySSID
[0] != 0))
521 memcpy(pBSSList
->abySSID
, pSSID
, pSSID
->len
+ WLAN_IEHDR_LEN
);
522 memcpy(pBSSList
->abySuppRates
, pSuppRates
,pSuppRates
->len
+ WLAN_IEHDR_LEN
);
524 if (pExtSuppRates
!= NULL
) {
525 memcpy(pBSSList
->abyExtSuppRates
, pExtSuppRates
,pExtSuppRates
->len
+ WLAN_IEHDR_LEN
);
527 memset(pBSSList
->abyExtSuppRates
, 0, WLAN_IEHDR_LEN
+ WLAN_RATES_MAXLEN
+ 1);
529 pBSSList
->sERP
.byERP
= psERP
->byERP
;
530 pBSSList
->sERP
.bERPExist
= psERP
->bERPExist
;
532 // Check if BSS is 802.11a/b/g
533 if (pBSSList
->uChannel
> CB_MAX_CHANNEL_24G
) {
534 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11A
;
536 if (pBSSList
->sERP
.bERPExist
== true) {
537 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11G
;
539 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11B
;
543 pBSSList
->byRxRate
= pRxPacket
->byRxRate
;
544 pBSSList
->qwLocalTSF
= pRxPacket
->qwLocalTSF
;
546 pBSSList
->uRSSI
= pRxPacket
->uRSSI
;
547 pBSSList
->bySQ
= pRxPacket
->bySQ
;
549 if ((pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) &&
550 (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
)) {
552 if (pBSSList
== pMgmt
->pCurrBSS
) {
553 bParsingQuiet
= true;
557 WPA_ClearRSN(pBSSList
); //mike update
559 if (pRSNWPA
!= NULL
) {
560 unsigned int uLen
= pRSNWPA
->len
+ 2;
561 if (uLen
<= (uIELength
-
562 (unsigned int) (u32
) ((u8
*) pRSNWPA
- pbyIEs
))) {
563 pBSSList
->wWPALen
= uLen
;
564 memcpy(pBSSList
->byWPAIE
, pRSNWPA
, uLen
);
565 WPA_ParseRSN(pBSSList
, pRSNWPA
);
569 WPA2_ClearRSN(pBSSList
); //mike update
572 unsigned int uLen
= pRSN
->len
+ 2;
573 if (uLen
<= (uIELength
-
574 (unsigned int) (u32
) ((u8
*) pRSN
- pbyIEs
))) {
575 pBSSList
->wRSNLen
= uLen
;
576 memcpy(pBSSList
->byRSNIE
, pRSN
, uLen
);
577 WPA2vParseRSN(pBSSList
, pRSN
);
581 if (pRxPacket
->uRSSI
!= 0) {
582 RFvRSSITodBm(pDevice
, (u8
)(pRxPacket
->uRSSI
), &ldBm
);
583 // Monitor if RSSI is too strong.
584 pBSSList
->byRSSIStatCnt
++;
585 pBSSList
->byRSSIStatCnt
%= RSSI_STAT_COUNT
;
586 pBSSList
->ldBmAverage
[pBSSList
->byRSSIStatCnt
] = ldBm
;
588 for (ii
= 0, jj
= 0; ii
< RSSI_STAT_COUNT
; ii
++) {
589 if (pBSSList
->ldBmAverage
[ii
] != 0) {
591 max(pBSSList
->ldBmAverage
[ii
], ldBm
);
593 pBSSList
->ldBmAverage
[ii
];
597 pBSSList
->ldBmAverRange
= ldBmSum
/jj
;
600 pBSSList
->uIELength
= uIELength
;
601 if (pBSSList
->uIELength
> WLAN_BEACON_FR_MAXLEN
)
602 pBSSList
->uIELength
= WLAN_BEACON_FR_MAXLEN
;
603 memcpy(pBSSList
->abyIEs
, pbyIEs
, pBSSList
->uIELength
);
610 * Routine Description:
611 * Search Node DB table to find the index of matched DstAddr
618 int BSSbIsSTAInNodeDB(struct vnt_private
*pDevice
,
619 u8
*abyDstAddr
, u32
*puNodeIndex
)
621 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
624 // Index = 0 reserved for AP Node
625 for (ii
= 1; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
626 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
627 if (ether_addr_equal(abyDstAddr
,
628 pMgmt
->sNodeDBTable
[ii
].abyMACAddr
)) {
640 * Routine Description:
641 * Find an empty node and allocate it; if no empty node
642 * is found, then use the most inactive one.
648 void BSSvCreateOneNode(struct vnt_private
*pDevice
, u32
*puNodeIndex
)
650 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
656 // Index = 0 reserved for AP Node (In STA mode)
657 // Index = 0 reserved for Broadcast/MultiCast (In AP mode)
659 for (ii
= 1; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
660 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
661 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
> BigestCount
) {
662 BigestCount
= pMgmt
->sNodeDBTable
[ii
].uInActiveCount
;
671 // if not found replace uInActiveCount with the largest one.
672 if ( ii
== (MAX_NODE_NUM
+ 1)) {
673 *puNodeIndex
= SelectIndex
;
674 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Replace inactive node = %d\n", SelectIndex
);
676 if (pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
.next
!= NULL
) {
677 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
)) != NULL
)
685 memset(&pMgmt
->sNodeDBTable
[*puNodeIndex
], 0, sizeof(KnownNodeDB
));
686 pMgmt
->sNodeDBTable
[*puNodeIndex
].bActive
= true;
687 pMgmt
->sNodeDBTable
[*puNodeIndex
].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
688 // for AP mode PS queue
689 skb_queue_head_init(&pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
);
690 pMgmt
->sNodeDBTable
[*puNodeIndex
].byAuthSequence
= 0;
691 pMgmt
->sNodeDBTable
[*puNodeIndex
].wEnQueueCnt
= 0;
692 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Create node index = %d\n", ii
);
697 * Routine Description:
698 * Remove Node by NodeIndex
706 void BSSvRemoveOneNode(struct vnt_private
*pDevice
, u32 uNodeIndex
)
708 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
709 u8 byMask
[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
712 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[uNodeIndex
].sTxPSQueue
)) != NULL
)
715 memset(&pMgmt
->sNodeDBTable
[uNodeIndex
], 0, sizeof(KnownNodeDB
));
717 pMgmt
->abyPSTxMap
[pMgmt
->sNodeDBTable
[uNodeIndex
].wAID
>> 3] &= ~byMask
[pMgmt
->sNodeDBTable
[uNodeIndex
].wAID
& 7];
721 * Routine Description:
722 * Update AP Node content in Index 0 of KnownNodeDB
730 void BSSvUpdateAPNode(struct vnt_private
*pDevice
, u16
*pwCapInfo
,
731 PWLAN_IE_SUPP_RATES pSuppRates
, PWLAN_IE_SUPP_RATES pExtSuppRates
)
733 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
734 u32 uRateLen
= WLAN_RATES_MAXLEN
;
736 memset(&pMgmt
->sNodeDBTable
[0], 0, sizeof(KnownNodeDB
));
738 pMgmt
->sNodeDBTable
[0].bActive
= true;
739 if (pDevice
->byBBType
== BB_TYPE_11B
) {
740 uRateLen
= WLAN_RATES_MAXLEN_11B
;
742 pMgmt
->abyCurrSuppRates
[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES
)pSuppRates
,
743 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrSuppRates
,
745 pMgmt
->abyCurrExtSuppRates
[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES
)pExtSuppRates
,
746 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrExtSuppRates
,
748 RATEvParseMaxRate((void *) pDevice
,
749 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrSuppRates
,
750 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrExtSuppRates
,
752 &(pMgmt
->sNodeDBTable
[0].wMaxBasicRate
),
753 &(pMgmt
->sNodeDBTable
[0].wMaxSuppRate
),
754 &(pMgmt
->sNodeDBTable
[0].wSuppRate
),
755 &(pMgmt
->sNodeDBTable
[0].byTopCCKBasicRate
),
756 &(pMgmt
->sNodeDBTable
[0].byTopOFDMBasicRate
)
758 memcpy(pMgmt
->sNodeDBTable
[0].abyMACAddr
, pMgmt
->abyCurrBSSID
, WLAN_ADDR_LEN
);
759 pMgmt
->sNodeDBTable
[0].wTxDataRate
= pMgmt
->sNodeDBTable
[0].wMaxSuppRate
;
760 pMgmt
->sNodeDBTable
[0].bShortPreamble
= WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo
);
761 pMgmt
->sNodeDBTable
[0].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
762 // Auto rate fallback function initiation.
763 // RATEbInit(pDevice);
764 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt
->sNodeDBTable
[0].wTxDataRate
);
770 * Routine Description:
771 * Add Multicast Node content in Index 0 of KnownNodeDB
779 void BSSvAddMulticastNode(struct vnt_private
*pDevice
)
781 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
783 if (!pDevice
->bEnableHostWEP
)
784 memset(&pMgmt
->sNodeDBTable
[0], 0, sizeof(KnownNodeDB
));
785 memset(pMgmt
->sNodeDBTable
[0].abyMACAddr
, 0xff, WLAN_ADDR_LEN
);
786 pMgmt
->sNodeDBTable
[0].bActive
= true;
787 pMgmt
->sNodeDBTable
[0].bPSEnable
= false;
788 skb_queue_head_init(&pMgmt
->sNodeDBTable
[0].sTxPSQueue
);
789 RATEvParseMaxRate((void *) pDevice
,
790 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrSuppRates
,
791 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrExtSuppRates
,
793 &(pMgmt
->sNodeDBTable
[0].wMaxBasicRate
),
794 &(pMgmt
->sNodeDBTable
[0].wMaxSuppRate
),
795 &(pMgmt
->sNodeDBTable
[0].wSuppRate
),
796 &(pMgmt
->sNodeDBTable
[0].byTopCCKBasicRate
),
797 &(pMgmt
->sNodeDBTable
[0].byTopOFDMBasicRate
)
799 pMgmt
->sNodeDBTable
[0].wTxDataRate
= pMgmt
->sNodeDBTable
[0].wMaxBasicRate
;
800 pMgmt
->sNodeDBTable
[0].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
806 * Routine Description:
809 * Second call back function to update Node DB info & AP link status
817 void BSSvSecondCallBack(struct work_struct
*work
)
819 struct vnt_private
*pDevice
= container_of(work
,
820 struct vnt_private
, second_callback_work
.work
);
821 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
823 PWLAN_IE_SSID pItemSSID
, pCurrSSID
;
824 u32 uSleepySTACnt
= 0;
825 u32 uNonShortSlotSTACnt
= 0;
826 u32 uLongPreambleSTACnt
= 0;
828 if (pDevice
->Flags
& fMP_DISCONNECTED
)
831 spin_lock_irq(&pDevice
->lock
);
833 pDevice
->uAssocCount
= 0;
835 //Power Saving Mode Tx Burst
836 if ( pDevice
->bEnablePSMode
== true ) {
837 pDevice
->ulPSModeWaitTx
++;
838 if ( pDevice
->ulPSModeWaitTx
>= 2 ) {
839 pDevice
->ulPSModeWaitTx
= 0;
840 pDevice
->bPSModeTxBurst
= false;
844 pDevice
->byERPFlag
&=
845 ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
847 if (pDevice
->wUseProtectCntDown
> 0) {
848 pDevice
->wUseProtectCntDown
--;
851 // disable protect mode
852 pDevice
->byERPFlag
&= ~(WLAN_SET_ERP_USE_PROTECTION(1));
855 if(pDevice
->byReAssocCount
> 0) {
856 pDevice
->byReAssocCount
++;
857 if((pDevice
->byReAssocCount
> 10) && (pDevice
->bLinkPass
!= true)) { //10 sec timeout
858 printk("Re-association timeout!!!\n");
859 pDevice
->byReAssocCount
= 0;
860 // if(pDevice->bWPASuppWextEnabled == true)
862 union iwreq_data wrqu
;
863 memset(&wrqu
, 0, sizeof (wrqu
));
864 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
865 PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
866 wireless_send_event(pDevice
->dev
, SIOCGIWAP
, &wrqu
, NULL
);
869 else if(pDevice
->bLinkPass
== true)
870 pDevice
->byReAssocCount
= 0;
873 pMgmt
->eLastState
= pMgmt
->eCurrState
;
875 s_uCalculateLinkQual(pDevice
);
877 for (ii
= 0; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
879 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
880 // Increase in-activity counter
881 pMgmt
->sNodeDBTable
[ii
].uInActiveCount
++;
884 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
> MAX_INACTIVE_COUNT
) {
885 BSSvRemoveOneNode(pDevice
, ii
);
886 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
887 "Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT
, ii
);
891 if (pMgmt
->sNodeDBTable
[ii
].eNodeState
>= NODE_ASSOC
) {
893 pDevice
->uAssocCount
++;
895 // check if Non ERP exist
896 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
< ERP_RECOVER_COUNT
) {
897 if (!pMgmt
->sNodeDBTable
[ii
].bShortPreamble
) {
898 pDevice
->byERPFlag
|= WLAN_SET_ERP_BARKER_MODE(1);
899 uLongPreambleSTACnt
++;
901 if (!pMgmt
->sNodeDBTable
[ii
].bERPExist
) {
902 pDevice
->byERPFlag
|= WLAN_SET_ERP_NONERP_PRESENT(1);
903 pDevice
->byERPFlag
|= WLAN_SET_ERP_USE_PROTECTION(1);
905 if (!pMgmt
->sNodeDBTable
[ii
].bShortSlotTime
)
906 uNonShortSlotSTACnt
++;
910 // check if any STA in PS mode
911 if (pMgmt
->sNodeDBTable
[ii
].bPSEnable
)
916 // Rate fallback check
917 if (!pDevice
->bFixRate
) {
919 // ii = 0 for multicast node (AP & Adhoc)
920 RATEvTxRateFallBack((void *)pDevice
,
921 &(pMgmt
->sNodeDBTable
[ii
]));
924 // ii = 0 reserved for unicast AP node (Infra STA)
925 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
)
926 RATEvTxRateFallBack((void *)pDevice
,
927 &(pMgmt
->sNodeDBTable
[ii
]));
932 // check if pending PS queue
933 if (pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
!= 0) {
934 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Index= %d, Queue = %d pending \n",
935 ii
, pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
);
936 if ((ii
>0) && (pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
> 15)) {
937 BSSvRemoveOneNode(pDevice
, ii
);
938 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Pending many queues PS STA Index = %d remove \n", ii
);
946 if ((pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
) && (pDevice
->byBBType
== BB_TYPE_11G
)) {
948 // on/off protect mode
949 if (WLAN_GET_ERP_USE_PROTECTION(pDevice
->byERPFlag
)) {
950 if (!pDevice
->bProtectMode
) {
951 MACvEnableProtectMD(pDevice
);
952 pDevice
->bProtectMode
= true;
956 if (pDevice
->bProtectMode
) {
957 MACvDisableProtectMD(pDevice
);
958 pDevice
->bProtectMode
= false;
961 // on/off short slot time
963 if (uNonShortSlotSTACnt
> 0) {
964 if (pDevice
->bShortSlotTime
) {
965 pDevice
->bShortSlotTime
= false;
966 BBvSetShortSlotTime(pDevice
);
967 vUpdateIFS((void *)pDevice
);
971 if (!pDevice
->bShortSlotTime
) {
972 pDevice
->bShortSlotTime
= true;
973 BBvSetShortSlotTime(pDevice
);
974 vUpdateIFS((void *)pDevice
);
978 // on/off barker long preamble mode
980 if (uLongPreambleSTACnt
> 0) {
981 if (!pDevice
->bBarkerPreambleMd
) {
982 MACvEnableBarkerPreambleMd(pDevice
);
983 pDevice
->bBarkerPreambleMd
= true;
987 if (pDevice
->bBarkerPreambleMd
) {
988 MACvDisableBarkerPreambleMd(pDevice
);
989 pDevice
->bBarkerPreambleMd
= false;
995 // Check if any STA in PS mode, enable DTIM multicast deliver
996 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
) {
997 if (uSleepySTACnt
> 0)
998 pMgmt
->sNodeDBTable
[0].bPSEnable
= true;
1000 pMgmt
->sNodeDBTable
[0].bPSEnable
= false;
1003 pItemSSID
= (PWLAN_IE_SSID
)pMgmt
->abyDesireSSID
;
1004 pCurrSSID
= (PWLAN_IE_SSID
)pMgmt
->abyCurrSSID
;
1006 if ((pMgmt
->eCurrMode
== WMAC_MODE_STANDBY
) ||
1007 (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
)) {
1009 if (pMgmt
->sNodeDBTable
[0].bActive
) { // Assoc with BSS
1011 if (pDevice
->bUpdateBBVGA
) {
1012 s_vCheckSensitivity(pDevice
);
1013 s_vCheckPreEDThreshold(pDevice
);
1016 if ((pMgmt
->sNodeDBTable
[0].uInActiveCount
>= (LOST_BEACON_COUNT
/2)) &&
1017 (pDevice
->byBBVGACurrent
!= pDevice
->abyBBVGA
[0]) ) {
1018 pDevice
->byBBVGANew
= pDevice
->abyBBVGA
[0];
1019 bScheduleCommand((void *) pDevice
,
1020 WLAN_CMD_CHANGE_BBSENSITIVITY
,
1024 if (pMgmt
->sNodeDBTable
[0].uInActiveCount
>= LOST_BEACON_COUNT
) {
1025 pMgmt
->sNodeDBTable
[0].bActive
= false;
1026 pMgmt
->eCurrMode
= WMAC_MODE_STANDBY
;
1027 pMgmt
->eCurrState
= WMAC_STATE_IDLE
;
1028 netif_stop_queue(pDevice
->dev
);
1029 pDevice
->bLinkPass
= false;
1030 ControlvMaskByte(pDevice
,MESSAGE_REQUEST_MACREG
,MAC_REG_PAPEDELAY
,LEDSTS_STS
,LEDSTS_SLOW
);
1031 pDevice
->bRoaming
= true;
1032 pDevice
->bIsRoaming
= false;
1034 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Lost AP beacon [%d] sec, disconnected !\n", pMgmt
->sNodeDBTable
[0].uInActiveCount
);
1035 /* let wpa supplicant know AP may disconnect */
1037 union iwreq_data wrqu
;
1038 memset(&wrqu
, 0, sizeof (wrqu
));
1039 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1040 PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
1041 wireless_send_event(pDevice
->dev
, SIOCGIWAP
, &wrqu
, NULL
);
1045 else if (pItemSSID
->len
!= 0) {
1047 if ((pDevice
->bEnableRoaming
== true)&&(!(pMgmt
->Cisco_cckm
))) {
1048 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"bRoaming %d, !\n", pDevice
->bRoaming
);
1049 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"bIsRoaming %d, !\n", pDevice
->bIsRoaming
);
1050 if ((pDevice
->bRoaming
== true)&&(pDevice
->bIsRoaming
== true)){
1051 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Fast Roaming ...\n");
1052 BSSvClearBSSList((void *) pDevice
, pDevice
->bLinkPass
);
1053 bScheduleCommand((void *) pDevice
,
1054 WLAN_CMD_BSSID_SCAN
,
1055 pMgmt
->abyDesireSSID
);
1056 bScheduleCommand((void *) pDevice
,
1058 pMgmt
->abyDesireSSID
);
1059 pDevice
->uAutoReConnectTime
= 0;
1060 pDevice
->uIsroamingTime
= 0;
1061 pDevice
->bRoaming
= false;
1063 else if ((pDevice
->bRoaming
== false)&&(pDevice
->bIsRoaming
== true)) {
1064 pDevice
->uIsroamingTime
++;
1065 if (pDevice
->uIsroamingTime
>= 20)
1066 pDevice
->bIsRoaming
= false;
1071 if (pDevice
->uAutoReConnectTime
< 10) {
1072 pDevice
->uAutoReConnectTime
++;
1073 //network manager support need not do Roaming scan???
1074 if(pDevice
->bWPASuppWextEnabled
==true)
1075 pDevice
->uAutoReConnectTime
= 0;
1078 //mike use old encryption status for wpa reauthen
1079 if(pDevice
->bWPADEVUp
)
1080 pDevice
->eEncryptionStatus
= pDevice
->eOldEncryptionStatus
;
1082 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Roaming ...\n");
1083 BSSvClearBSSList((void *) pDevice
, pDevice
->bLinkPass
);
1084 pMgmt
->eScanType
= WMAC_SCAN_ACTIVE
;
1085 bScheduleCommand((void *) pDevice
,
1086 WLAN_CMD_BSSID_SCAN
,
1087 pMgmt
->abyDesireSSID
);
1088 bScheduleCommand((void *) pDevice
,
1090 pMgmt
->abyDesireSSID
);
1091 pDevice
->uAutoReConnectTime
= 0;
1097 if (pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) {
1098 // if adhoc started which essid is NULL string, rescanning.
1099 if ((pMgmt
->eCurrState
== WMAC_STATE_STARTED
) && (pCurrSSID
->len
== 0)) {
1100 if (pDevice
->uAutoReConnectTime
< 10) {
1101 pDevice
->uAutoReConnectTime
++;
1104 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Adhoc re-scanning ...\n");
1105 pMgmt
->eScanType
= WMAC_SCAN_ACTIVE
;
1106 bScheduleCommand((void *) pDevice
, WLAN_CMD_BSSID_SCAN
, NULL
);
1107 bScheduleCommand((void *) pDevice
, WLAN_CMD_SSID
, NULL
);
1108 pDevice
->uAutoReConnectTime
= 0;
1111 if (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
) {
1113 if (pDevice
->bUpdateBBVGA
) {
1114 s_vCheckSensitivity(pDevice
);
1115 s_vCheckPreEDThreshold(pDevice
);
1117 if (pMgmt
->sNodeDBTable
[0].uInActiveCount
>=ADHOC_LOST_BEACON_COUNT
) {
1118 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Lost other STA beacon [%d] sec, started !\n", pMgmt
->sNodeDBTable
[0].uInActiveCount
);
1119 pMgmt
->sNodeDBTable
[0].uInActiveCount
= 0;
1120 pMgmt
->eCurrState
= WMAC_STATE_STARTED
;
1121 netif_stop_queue(pDevice
->dev
);
1122 pDevice
->bLinkPass
= false;
1123 ControlvMaskByte(pDevice
,MESSAGE_REQUEST_MACREG
,MAC_REG_PAPEDELAY
,LEDSTS_STS
,LEDSTS_SLOW
);
1128 if (pDevice
->bLinkPass
== true) {
1129 if (pMgmt
->eAuthenMode
< WMAC_AUTH_WPA
||
1130 pDevice
->fWPA_Authened
== true) {
1131 if (++pDevice
->tx_data_time_out
> 40) {
1132 pDevice
->tx_trigger
= true;
1134 PSbSendNullPacket(pDevice
);
1136 pDevice
->tx_trigger
= false;
1137 pDevice
->tx_data_time_out
= 0;
1141 if (netif_queue_stopped(pDevice
->dev
))
1142 netif_wake_queue(pDevice
->dev
);
1145 spin_unlock_irq(&pDevice
->lock
);
1147 schedule_delayed_work(&pDevice
->second_callback_work
, HZ
);
1152 * Routine Description:
1155 * Update Tx attemps, Tx failure counter in Node DB
1163 void BSSvUpdateNodeTxCounter(struct vnt_private
*pDevice
,
1164 PSStatCounter pStatistic
, u8 byTSR
, u8 byPktNO
)
1166 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
1170 u16 wFallBackRate
= RATE_1M
;
1177 byPktNum
= (byPktNO
& 0x0F) >> 4;
1178 byTxRetry
= (byTSR
& 0xF0) >> 4;
1179 wRate
= (u16
) (byPktNO
& 0xF0) >> 4;
1180 wFIFOCtl
= pStatistic
->abyTxPktInfo
[byPktNum
].wFIFOCtl
;
1181 pbyDestAddr
= (u8
*) &( pStatistic
->abyTxPktInfo
[byPktNum
].abyDestAddr
[0]);
1183 if (wFIFOCtl
& FIFOCTL_AUTO_FB_0
) {
1184 byFallBack
= AUTO_FB_0
;
1185 } else if (wFIFOCtl
& FIFOCTL_AUTO_FB_1
) {
1186 byFallBack
= AUTO_FB_1
;
1188 byFallBack
= AUTO_FB_NONE
;
1191 // Only Unicast using support rates
1192 if (wFIFOCtl
& FIFOCTL_NEEDACK
) {
1193 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) {
1194 pMgmt
->sNodeDBTable
[0].uTxAttempts
+= 1;
1195 if ( !(byTSR
& (TSR_TMO
| TSR_RETRYTMO
))) {
1196 // transmit success, TxAttempts at least plus one
1197 pMgmt
->sNodeDBTable
[0].uTxOk
[MAX_RATE
]++;
1198 if ( (byFallBack
== AUTO_FB_NONE
) ||
1199 (wRate
< RATE_18M
) ) {
1200 wFallBackRate
= wRate
;
1201 } else if (byFallBack
== AUTO_FB_0
) {
1203 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][byTxRetry
];
1205 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][4];
1206 } else if (byFallBack
== AUTO_FB_1
) {
1208 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][byTxRetry
];
1210 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1212 pMgmt
->sNodeDBTable
[0].uTxOk
[wFallBackRate
]++;
1214 pMgmt
->sNodeDBTable
[0].uTxFailures
++;
1216 pMgmt
->sNodeDBTable
[0].uTxRetry
+= byTxRetry
;
1217 if (byTxRetry
!= 0) {
1218 pMgmt
->sNodeDBTable
[0].uTxFail
[MAX_RATE
]+=byTxRetry
;
1219 if ( (byFallBack
== AUTO_FB_NONE
) ||
1220 (wRate
< RATE_18M
) ) {
1221 pMgmt
->sNodeDBTable
[0].uTxFail
[wRate
]+=byTxRetry
;
1222 } else if (byFallBack
== AUTO_FB_0
) {
1223 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1226 awHWRetry0
[wRate
-RATE_18M
][ii
];
1229 awHWRetry0
[wRate
-RATE_18M
][4];
1230 pMgmt
->sNodeDBTable
[0].uTxFail
[wFallBackRate
]++;
1232 } else if (byFallBack
== AUTO_FB_1
) {
1233 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1236 awHWRetry1
[wRate
-RATE_18M
][ii
];
1239 awHWRetry1
[wRate
-RATE_18M
][4];
1240 pMgmt
->sNodeDBTable
[0].uTxFail
[wFallBackRate
]++;
1246 if ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) ||
1247 (pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
)) {
1249 if (BSSbIsSTAInNodeDB((void *) pDevice
,
1252 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxAttempts
+= 1;
1253 if ( !(byTSR
& (TSR_TMO
| TSR_RETRYTMO
))) {
1254 // transmit success, TxAttempts at least plus one
1255 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxOk
[MAX_RATE
]++;
1256 if ( (byFallBack
== AUTO_FB_NONE
) ||
1257 (wRate
< RATE_18M
) ) {
1258 wFallBackRate
= wRate
;
1259 } else if (byFallBack
== AUTO_FB_0
) {
1261 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][byTxRetry
];
1263 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][4];
1264 } else if (byFallBack
== AUTO_FB_1
) {
1266 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][byTxRetry
];
1268 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1270 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxOk
[wFallBackRate
]++;
1272 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFailures
++;
1274 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxRetry
+= byTxRetry
;
1275 if (byTxRetry
!= 0) {
1276 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[MAX_RATE
]+=byTxRetry
;
1277 if ( (byFallBack
== AUTO_FB_NONE
) ||
1278 (wRate
< RATE_18M
) ) {
1279 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wRate
]+=byTxRetry
;
1280 } else if (byFallBack
== AUTO_FB_0
) {
1281 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1284 awHWRetry0
[wRate
-RATE_18M
][ii
];
1287 awHWRetry0
[wRate
-RATE_18M
][4];
1288 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wFallBackRate
]++;
1290 } else if (byFallBack
== AUTO_FB_1
) {
1291 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1293 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][ii
];
1295 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1296 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wFallBackRate
]++;
1307 * Routine Description:
1308 * Clear Nodes & skb in DB Table
1313 * hDeviceContext - The adapter context.
1314 * uStartIndex - starting index
1323 void BSSvClearNodeDBTable(struct vnt_private
*pDevice
, u32 uStartIndex
)
1325 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
1326 struct sk_buff
*skb
;
1329 for (ii
= uStartIndex
; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
1330 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
1331 // check if sTxPSQueue has been initial
1332 if (pMgmt
->sNodeDBTable
[ii
].sTxPSQueue
.next
!= NULL
) {
1333 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[ii
].sTxPSQueue
)) != NULL
){
1334 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"PS skb != NULL %d\n", ii
);
1338 memset(&pMgmt
->sNodeDBTable
[ii
], 0, sizeof(KnownNodeDB
));
1343 static void s_vCheckSensitivity(struct vnt_private
*pDevice
)
1345 PKnownBSS pBSSList
= NULL
;
1346 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
1349 if ((pMgmt
->eCurrState
== WMAC_STATE_ASSOC
) ||
1350 ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) && (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
))) {
1351 pBSSList
= BSSpAddrIsInBSSList(pDevice
, pMgmt
->abyCurrBSSID
, (PWLAN_IE_SSID
)pMgmt
->abyCurrSSID
);
1352 if (pBSSList
!= NULL
) {
1353 /* Update BB register if RSSI is too strong */
1354 signed long LocalldBmAverage
= 0;
1355 signed long uNumofdBm
= 0;
1356 for (ii
= 0; ii
< RSSI_STAT_COUNT
; ii
++) {
1357 if (pBSSList
->ldBmAverage
[ii
] != 0) {
1359 LocalldBmAverage
+= pBSSList
->ldBmAverage
[ii
];
1362 if (uNumofdBm
> 0) {
1363 LocalldBmAverage
= LocalldBmAverage
/uNumofdBm
;
1364 for (ii
=0;ii
<BB_VGA_LEVEL
;ii
++) {
1365 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage
, pDevice
->ldBmThreshold
[ii
], pDevice
->abyBBVGA
[ii
]);
1366 if (LocalldBmAverage
< pDevice
->ldBmThreshold
[ii
]) {
1367 pDevice
->byBBVGANew
= pDevice
->abyBBVGA
[ii
];
1371 if (pDevice
->byBBVGANew
!= pDevice
->byBBVGACurrent
) {
1372 pDevice
->uBBVGADiffCount
++;
1373 if (pDevice
->uBBVGADiffCount
>= BB_VGA_CHANGE_THRESHOLD
)
1374 bScheduleCommand(pDevice
,
1375 WLAN_CMD_CHANGE_BBSENSITIVITY
,
1378 pDevice
->uBBVGADiffCount
= 0;
1385 static void s_uCalculateLinkQual(struct vnt_private
*pDevice
)
1387 struct net_device_stats
*stats
= &pDevice
->stats
;
1388 unsigned long TxOkRatio
, TxCnt
;
1389 unsigned long RxOkRatio
, RxCnt
;
1390 unsigned long RssiRatio
;
1394 TxCnt
= stats
->tx_packets
+ pDevice
->wstats
.discard
.retries
;
1396 RxCnt
= stats
->rx_packets
+ stats
->rx_frame_errors
;
1398 TxOkRatio
= (TxCnt
< 6) ? 4000:((stats
->tx_packets
* 4000) / TxCnt
);
1400 RxOkRatio
= (RxCnt
< 6) ? 2000 :
1401 ((stats
->rx_packets
* 2000) / RxCnt
);
1403 /* decide link quality */
1404 if (pDevice
->bLinkPass
!= true) {
1405 pDevice
->wstats
.qual
.qual
= 0;
1406 pDevice
->scStatistic
.SignalStren
= 0;
1408 RFvRSSITodBm(pDevice
, (u8
)(pDevice
->uCurrRSSI
), &ldBm
);
1411 else if (-ldBm
> 90)
1414 RssiRatio
= (40-(-ldBm
-50)) * 4000 / 40;
1416 pDevice
->scStatistic
.SignalStren
= RssiRatio
/ 40;
1417 qual
= (RssiRatio
+ TxOkRatio
+ RxOkRatio
) / 100;
1419 pDevice
->wstats
.qual
.qual
= (u8
)qual
;
1421 pDevice
->wstats
.qual
.qual
= 100;
1424 pDevice
->scStatistic
.RxFcsErrCnt
= 0;
1425 pDevice
->scStatistic
.RxOkCnt
= 0;
1426 pDevice
->scStatistic
.TxFailCount
= 0;
1427 pDevice
->scStatistic
.TxNoRetryOkCount
= 0;
1428 pDevice
->scStatistic
.TxRetryOkCount
= 0;
1431 void BSSvClearAnyBSSJoinRecord(struct vnt_private
*pDevice
)
1433 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
1436 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++)
1437 pMgmt
->sBSSList
[ii
].bSelected
= false;
1442 static void s_vCheckPreEDThreshold(struct vnt_private
*pDevice
)
1444 PKnownBSS pBSSList
= NULL
;
1445 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
1447 if ((pMgmt
->eCurrState
== WMAC_STATE_ASSOC
) ||
1448 ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) && (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
))) {
1449 pBSSList
= BSSpAddrIsInBSSList(pDevice
, pMgmt
->abyCurrBSSID
, (PWLAN_IE_SSID
)pMgmt
->abyCurrSSID
);
1450 if (pBSSList
!= NULL
) {
1451 pDevice
->byBBPreEDRSSI
= (u8
) (~(pBSSList
->ldBmAverRange
) + 1);
1452 BBvUpdatePreEDThreshold(pDevice
, false);