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 * BSSDBbIsSTAInNodeDB - Search Node DB table to find the index of matched DstAddr
29 * BSSvCreateOneNode - Allocate an Node for Node DB
30 * BSSvUpdateAPNode - Update AP Node content in Index 0 of KnownNodeDB
31 * BSSvSecondCallBack - One second timer callback function to update Node DB info & AP link status
32 * BSSvUpdateNodeTxCounter - Update Tx attemps, Tx failure counter in Node DB for auto-fall back rate control
61 /*--------------------- Static Definitions -------------------------*/
63 /*--------------------- Static Classes ----------------------------*/
65 /*--------------------- Static Variables --------------------------*/
66 static int msglevel
= MSG_LEVEL_INFO
;
68 const unsigned short awHWRetry0
[5][5] = {
69 {RATE_18M
, RATE_18M
, RATE_12M
, RATE_12M
, RATE_12M
},
70 {RATE_24M
, RATE_24M
, RATE_18M
, RATE_12M
, RATE_12M
},
71 {RATE_36M
, RATE_36M
, RATE_24M
, RATE_18M
, RATE_18M
},
72 {RATE_48M
, RATE_48M
, RATE_36M
, RATE_24M
, RATE_24M
},
73 {RATE_54M
, RATE_54M
, RATE_48M
, RATE_36M
, RATE_36M
}
75 const unsigned short awHWRetry1
[5][5] = {
76 {RATE_18M
, RATE_18M
, RATE_12M
, RATE_6M
, RATE_6M
},
77 {RATE_24M
, RATE_24M
, RATE_18M
, RATE_6M
, RATE_6M
},
78 {RATE_36M
, RATE_36M
, RATE_24M
, RATE_12M
, RATE_12M
},
79 {RATE_48M
, RATE_48M
, RATE_24M
, RATE_12M
, RATE_12M
},
80 {RATE_54M
, RATE_54M
, RATE_36M
, RATE_18M
, RATE_18M
}
83 /*--------------------- Static Functions --------------------------*/
85 void s_vCheckSensitivity(
90 void s_uCalculateLinkQual(
95 void s_vCheckPreEDThreshold(
98 /*--------------------- Export Variables --------------------------*/
100 /*--------------------- Export Functions --------------------------*/
104 * Routine Description:
105 * Search known BSS list for Desire SSID or BSSID.
108 * PTR to KnownBSS or NULL
114 void *hDeviceContext
,
115 unsigned char *pbyDesireBSSID
,
116 unsigned char *pbyDesireSSID
,
117 CARD_PHY_TYPE ePhyType
120 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
121 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
122 unsigned char *pbyBSSID
= NULL
;
123 PWLAN_IE_SSID pSSID
= NULL
;
124 PKnownBSS pCurrBSS
= NULL
;
125 PKnownBSS pSelect
= NULL
;
126 unsigned char ZeroBSSID
[WLAN_BSSID_LEN
] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
129 if (pbyDesireBSSID
!= NULL
) {
130 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
131 "BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID
);
132 if ((!is_broadcast_ether_addr(pbyDesireBSSID
)) &&
133 (memcmp(pbyDesireBSSID
, ZeroBSSID
, 6) != 0))
134 pbyBSSID
= pbyDesireBSSID
;
136 if (pbyDesireSSID
!= NULL
) {
137 if (((PWLAN_IE_SSID
)pbyDesireSSID
)->len
!= 0)
138 pSSID
= (PWLAN_IE_SSID
) pbyDesireSSID
;
141 if (pbyBSSID
!= NULL
) {
142 /* match BSSID first */
143 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
144 pCurrBSS
= &(pMgmt
->sBSSList
[ii
]);
145 if (!pDevice
->bLinkPass
)
146 pCurrBSS
->bSelected
= false;
147 if ((pCurrBSS
->bActive
) &&
148 (!pCurrBSS
->bSelected
)) {
149 if (ether_addr_equal(pCurrBSS
->abyBSSID
,
153 if (!memcmp(pSSID
->abySSID
,
154 ((PWLAN_IE_SSID
)pCurrBSS
->abySSID
)->abySSID
,
156 if ((pMgmt
->eConfigMode
== WMAC_CONFIG_AUTO
) ||
157 ((pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
)) ||
158 ((pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
) && WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
))
160 pCurrBSS
->bSelected
= true;
165 if ((pMgmt
->eConfigMode
== WMAC_CONFIG_AUTO
) ||
166 ((pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
)) ||
167 ((pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
) && WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
))
169 pCurrBSS
->bSelected
= true;
178 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
179 pCurrBSS
= &(pMgmt
->sBSSList
[ii
]);
180 /* 2007-0721-01<Add>by MikeLiu */
181 pCurrBSS
->bSelected
= false;
182 if (pCurrBSS
->bActive
) {
185 if (!!memcmp(pSSID
->abySSID
,
186 ((PWLAN_IE_SSID
)pCurrBSS
->abySSID
)->abySSID
,
188 (pSSID
->len
!= ((PWLAN_IE_SSID
)pCurrBSS
->abySSID
)->len
)) {
189 /* SSID not match skip this BSS */
193 if (((pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
) && WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
)) ||
194 ((pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
))
196 /* Type not match skip this BSS */
197 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt
->eConfigMode
, pCurrBSS
->wCapInfo
);
201 if (ePhyType
!= PHY_TYPE_AUTO
) {
202 if (((ePhyType
== PHY_TYPE_11A
) && (PHY_TYPE_11A
!= pCurrBSS
->eNetworkTypeInUse
)) ||
203 ((ePhyType
!= PHY_TYPE_11A
) && (PHY_TYPE_11A
== pCurrBSS
->eNetworkTypeInUse
))) {
204 /* PhyType not match skip this BSS */
205 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType
, pCurrBSS
->eNetworkTypeInUse
);
210 if (pSelect
== NULL
) {
213 /* compare RSSI, select signal strong one */
214 if (pCurrBSS
->uRSSI
< pSelect
->uRSSI
)
219 if (pSelect
!= NULL
) {
220 pSelect
->bSelected
= true;
229 * Routine Description:
239 void *hDeviceContext
,
243 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
244 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
247 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
248 if (bKeepCurrBSSID
) {
249 if (pMgmt
->sBSSList
[ii
].bActive
&&
250 ether_addr_equal(pMgmt
->sBSSList
[ii
].abyBSSID
,
251 pMgmt
->abyCurrBSSID
)) {
256 if ((pMgmt
->sBSSList
[ii
].bActive
) && (pMgmt
->sBSSList
[ii
].uClearCount
< BSS_CLEAR_COUNT
)) {
257 pMgmt
->sBSSList
[ii
].uClearCount
++;
261 pMgmt
->sBSSList
[ii
].bActive
= false;
262 memset(&pMgmt
->sBSSList
[ii
], 0, sizeof(KnownBSS
));
264 BSSvClearAnyBSSJoinRecord(pDevice
);
271 * Routine Description:
272 * search BSS list by BSSID & SSID if matched
280 void *hDeviceContext
,
281 unsigned char *abyBSSID
,
285 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
286 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
287 PKnownBSS pBSSList
= NULL
;
290 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
291 pBSSList
= &(pMgmt
->sBSSList
[ii
]);
292 if (pBSSList
->bActive
) {
293 if (ether_addr_equal(pBSSList
->abyBSSID
, abyBSSID
)) {
294 if (pSSID
->len
== ((PWLAN_IE_SSID
)pBSSList
->abySSID
)->len
) {
295 if (memcmp(pSSID
->abySSID
,
296 ((PWLAN_IE_SSID
)pBSSList
->abySSID
)->abySSID
,
309 * Routine Description:
310 * Insert a BSS set into known BSS list
319 void *hDeviceContext
,
320 unsigned char *abyBSSIDAddr
,
322 unsigned short wBeaconInterval
,
323 unsigned short wCapInfo
,
324 unsigned char byCurrChannel
,
326 PWLAN_IE_SUPP_RATES pSuppRates
,
327 PWLAN_IE_SUPP_RATES pExtSuppRates
,
330 PWLAN_IE_RSN_EXT pRSNWPA
,
331 PWLAN_IE_COUNTRY pIE_Country
,
332 PWLAN_IE_QUIET pIE_Quiet
,
333 unsigned int uIELength
,
334 unsigned char *pbyIEs
,
335 void *pRxPacketContext
338 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
339 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
340 PSRxMgmtPacket pRxPacket
= (PSRxMgmtPacket
)pRxPacketContext
;
341 PKnownBSS pBSSList
= NULL
;
343 bool bParsingQuiet
= false;
344 PWLAN_IE_QUIET pQuiet
= NULL
;
346 pBSSList
= (PKnownBSS
)&(pMgmt
->sBSSList
[0]);
348 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
349 pBSSList
= (PKnownBSS
)&(pMgmt
->sBSSList
[ii
]);
350 if (!pBSSList
->bActive
)
354 if (ii
== MAX_BSS_NUM
) {
355 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Get free KnowBSS node failed.\n");
358 /* save the BSS info */
359 pBSSList
->bActive
= true;
360 memcpy(pBSSList
->abyBSSID
, abyBSSIDAddr
, WLAN_BSSID_LEN
);
361 HIDWORD(pBSSList
->qwBSSTimestamp
) = cpu_to_le32(HIDWORD(qwTimestamp
));
362 LODWORD(pBSSList
->qwBSSTimestamp
) = cpu_to_le32(LODWORD(qwTimestamp
));
363 pBSSList
->wBeaconInterval
= cpu_to_le16(wBeaconInterval
);
364 pBSSList
->wCapInfo
= cpu_to_le16(wCapInfo
);
365 pBSSList
->uClearCount
= 0;
367 if (pSSID
->len
> WLAN_SSID_MAXLEN
)
368 pSSID
->len
= WLAN_SSID_MAXLEN
;
369 memcpy(pBSSList
->abySSID
, pSSID
, pSSID
->len
+ WLAN_IEHDR_LEN
);
371 pBSSList
->uChannel
= byCurrChannel
;
373 if (pSuppRates
->len
> WLAN_RATES_MAXLEN
)
374 pSuppRates
->len
= WLAN_RATES_MAXLEN
;
375 memcpy(pBSSList
->abySuppRates
, pSuppRates
, pSuppRates
->len
+ WLAN_IEHDR_LEN
);
377 if (pExtSuppRates
!= NULL
) {
378 if (pExtSuppRates
->len
> WLAN_RATES_MAXLEN
)
379 pExtSuppRates
->len
= WLAN_RATES_MAXLEN
;
380 memcpy(pBSSList
->abyExtSuppRates
, pExtSuppRates
, pExtSuppRates
->len
+ WLAN_IEHDR_LEN
);
381 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates
->len
);
384 memset(pBSSList
->abyExtSuppRates
, 0, WLAN_IEHDR_LEN
+ WLAN_RATES_MAXLEN
+ 1);
386 pBSSList
->sERP
.byERP
= psERP
->byERP
;
387 pBSSList
->sERP
.bERPExist
= psERP
->bERPExist
;
389 /* check if BSS is 802.11a/b/g */
390 if (pBSSList
->uChannel
> CB_MAX_CHANNEL_24G
) {
391 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11A
;
393 if (pBSSList
->sERP
.bERPExist
)
394 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11G
;
396 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11B
;
399 pBSSList
->byRxRate
= pRxPacket
->byRxRate
;
400 pBSSList
->qwLocalTSF
= pRxPacket
->qwLocalTSF
;
401 pBSSList
->uRSSI
= pRxPacket
->uRSSI
;
402 pBSSList
->bySQ
= pRxPacket
->bySQ
;
404 if ((pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) &&
405 (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
)) {
407 if (pBSSList
== pMgmt
->pCurrBSS
)
408 bParsingQuiet
= true;
411 WPA_ClearRSN(pBSSList
);
413 if (pRSNWPA
!= NULL
) {
414 unsigned int uLen
= pRSNWPA
->len
+ 2;
416 if (uLen
<= (uIELength
- (unsigned int)((unsigned char *)pRSNWPA
- pbyIEs
))) {
417 pBSSList
->wWPALen
= uLen
;
418 memcpy(pBSSList
->byWPAIE
, pRSNWPA
, uLen
);
419 WPA_ParseRSN(pBSSList
, pRSNWPA
);
423 WPA2_ClearRSN(pBSSList
);
426 unsigned int uLen
= pRSN
->len
+ 2;
427 if (uLen
<= (uIELength
- (unsigned int)((unsigned char *)pRSN
- pbyIEs
))) {
428 pBSSList
->wRSNLen
= uLen
;
429 memcpy(pBSSList
->byRSNIE
, pRSN
, uLen
);
430 WPA2vParseRSN(pBSSList
, pRSN
);
434 if ((pMgmt
->eAuthenMode
== WMAC_AUTH_WPA2
) || pBSSList
->bWPA2Valid
) {
435 PSKeyItem pTransmitKey
= NULL
;
436 bool bIs802_1x
= false;
438 for (ii
= 0; ii
< pBSSList
->wAKMSSAuthCount
; ii
++) {
439 if (pBSSList
->abyAKMSSAuthType
[ii
] == WLAN_11i_AKMSS_802_1X
) {
444 if (bIs802_1x
&& (pSSID
->len
== ((PWLAN_IE_SSID
)pMgmt
->abyDesireSSID
)->len
) &&
445 (!memcmp(pSSID
->abySSID
, ((PWLAN_IE_SSID
)pMgmt
->abyDesireSSID
)->abySSID
, pSSID
->len
))) {
446 bAdd_PMKID_Candidate((void *)pDevice
, pBSSList
->abyBSSID
, &pBSSList
->sRSNCapObj
);
448 if (pDevice
->bLinkPass
&& (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
)) {
449 if (KeybGetTransmitKey(&(pDevice
->sKey
), pDevice
->abyBSSID
, PAIRWISE_KEY
, &pTransmitKey
) ||
450 KeybGetTransmitKey(&(pDevice
->sKey
), pDevice
->abyBSSID
, GROUP_KEY
, &pTransmitKey
)) {
451 pDevice
->gsPMKIDCandidate
.StatusType
= Ndis802_11StatusType_PMKID_CandidateList
;
452 pDevice
->gsPMKIDCandidate
.Version
= 1;
460 if (pDevice
->bUpdateBBVGA
) {
461 /* monitor if RSSI is too strong */
462 pBSSList
->byRSSIStatCnt
= 0;
463 RFvRSSITodBm(pDevice
, (unsigned char)(pRxPacket
->uRSSI
), &pBSSList
->ldBmMAX
);
464 pBSSList
->ldBmAverage
[0] = pBSSList
->ldBmMAX
;
465 for (ii
= 1; ii
< RSSI_STAT_COUNT
; ii
++)
466 pBSSList
->ldBmAverage
[ii
] = 0;
469 if ((pIE_Country
!= NULL
) && pMgmt
->b11hEnable
) {
470 set_country_info(pMgmt
->pAdapter
, pBSSList
->eNetworkTypeInUse
,
474 if (bParsingQuiet
&& (pIE_Quiet
!= NULL
)) {
475 if ((((PWLAN_IE_QUIET
)pIE_Quiet
)->len
== 8) &&
476 (((PWLAN_IE_QUIET
)pIE_Quiet
)->byQuietCount
!= 0)) {
478 if (pQuiet
== NULL
) {
479 pQuiet
= (PWLAN_IE_QUIET
)pIE_Quiet
;
480 CARDbSetQuiet(pMgmt
->pAdapter
,
482 pQuiet
->byQuietCount
,
483 pQuiet
->byQuietPeriod
,
484 *((unsigned short *)pQuiet
->abyQuietDuration
),
485 *((unsigned short *)pQuiet
->abyQuietOffset
)
488 pQuiet
= (PWLAN_IE_QUIET
)pIE_Quiet
;
489 CARDbSetQuiet(pMgmt
->pAdapter
,
491 pQuiet
->byQuietCount
,
492 pQuiet
->byQuietPeriod
,
493 *((unsigned short *)pQuiet
->abyQuietDuration
),
494 *((unsigned short *)pQuiet
->abyQuietOffset
)
500 if (bParsingQuiet
&& (pQuiet
!= NULL
)) {
501 CARDbStartQuiet(pMgmt
->pAdapter
);
504 pBSSList
->uIELength
= uIELength
;
505 if (pBSSList
->uIELength
> WLAN_BEACON_FR_MAXLEN
)
506 pBSSList
->uIELength
= WLAN_BEACON_FR_MAXLEN
;
507 memcpy(pBSSList
->abyIEs
, pbyIEs
, pBSSList
->uIELength
);
514 * Routine Description:
515 * Update BSS set in known BSS list
521 /* TODO: input structure modify */
525 void *hDeviceContext
,
527 unsigned short wBeaconInterval
,
528 unsigned short wCapInfo
,
529 unsigned char byCurrChannel
,
532 PWLAN_IE_SUPP_RATES pSuppRates
,
533 PWLAN_IE_SUPP_RATES pExtSuppRates
,
536 PWLAN_IE_RSN_EXT pRSNWPA
,
537 PWLAN_IE_COUNTRY pIE_Country
,
538 PWLAN_IE_QUIET pIE_Quiet
,
540 unsigned int uIELength
,
541 unsigned char *pbyIEs
,
542 void *pRxPacketContext
546 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
547 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
548 PSRxMgmtPacket pRxPacket
= (PSRxMgmtPacket
)pRxPacketContext
;
550 bool bParsingQuiet
= false;
551 PWLAN_IE_QUIET pQuiet
= NULL
;
553 if (pBSSList
== NULL
)
556 HIDWORD(pBSSList
->qwBSSTimestamp
) = cpu_to_le32(HIDWORD(qwTimestamp
));
557 LODWORD(pBSSList
->qwBSSTimestamp
) = cpu_to_le32(LODWORD(qwTimestamp
));
558 pBSSList
->wBeaconInterval
= cpu_to_le16(wBeaconInterval
);
559 pBSSList
->wCapInfo
= cpu_to_le16(wCapInfo
);
560 pBSSList
->uClearCount
= 0;
561 pBSSList
->uChannel
= byCurrChannel
;
563 if (pSSID
->len
> WLAN_SSID_MAXLEN
)
564 pSSID
->len
= WLAN_SSID_MAXLEN
;
566 if ((pSSID
->len
!= 0) && (pSSID
->abySSID
[0] != 0))
567 memcpy(pBSSList
->abySSID
, pSSID
, pSSID
->len
+ WLAN_IEHDR_LEN
);
568 memcpy(pBSSList
->abySuppRates
, pSuppRates
, pSuppRates
->len
+ WLAN_IEHDR_LEN
);
570 if (pExtSuppRates
!= NULL
)
571 memcpy(pBSSList
->abyExtSuppRates
, pExtSuppRates
, pExtSuppRates
->len
+ WLAN_IEHDR_LEN
);
573 memset(pBSSList
->abyExtSuppRates
, 0, WLAN_IEHDR_LEN
+ WLAN_RATES_MAXLEN
+ 1);
574 pBSSList
->sERP
.byERP
= psERP
->byERP
;
575 pBSSList
->sERP
.bERPExist
= psERP
->bERPExist
;
577 /* check if BSS is 802.11a/b/g */
578 if (pBSSList
->uChannel
> CB_MAX_CHANNEL_24G
) {
579 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11A
;
581 if (pBSSList
->sERP
.bERPExist
)
582 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11G
;
584 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11B
;
587 pBSSList
->byRxRate
= pRxPacket
->byRxRate
;
588 pBSSList
->qwLocalTSF
= pRxPacket
->qwLocalTSF
;
590 pBSSList
->uRSSI
= pRxPacket
->uRSSI
;
591 pBSSList
->bySQ
= pRxPacket
->bySQ
;
593 if ((pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) &&
594 (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
)) {
596 if (pBSSList
== pMgmt
->pCurrBSS
)
597 bParsingQuiet
= true;
600 WPA_ClearRSN(pBSSList
); /* mike update */
602 if (pRSNWPA
!= NULL
) {
603 unsigned int uLen
= pRSNWPA
->len
+ 2;
604 if (uLen
<= (uIELength
- (unsigned int)((unsigned char *)pRSNWPA
- pbyIEs
))) {
605 pBSSList
->wWPALen
= uLen
;
606 memcpy(pBSSList
->byWPAIE
, pRSNWPA
, uLen
);
607 WPA_ParseRSN(pBSSList
, pRSNWPA
);
611 WPA2_ClearRSN(pBSSList
); /* mike update */
614 unsigned int uLen
= pRSN
->len
+ 2;
615 if (uLen
<= (uIELength
- (unsigned int)((unsigned char *)pRSN
- pbyIEs
))) {
616 pBSSList
->wRSNLen
= uLen
;
617 memcpy(pBSSList
->byRSNIE
, pRSN
, uLen
);
618 WPA2vParseRSN(pBSSList
, pRSN
);
622 if (pRxPacket
->uRSSI
!= 0) {
623 RFvRSSITodBm(pDevice
, (unsigned char)(pRxPacket
->uRSSI
), &ldBm
);
624 /* monitor if RSSI is too strong */
625 pBSSList
->byRSSIStatCnt
++;
626 pBSSList
->byRSSIStatCnt
%= RSSI_STAT_COUNT
;
627 pBSSList
->ldBmAverage
[pBSSList
->byRSSIStatCnt
] = ldBm
;
628 for (ii
= 0; ii
< RSSI_STAT_COUNT
; ii
++) {
629 if (pBSSList
->ldBmAverage
[ii
] != 0)
630 pBSSList
->ldBmMAX
= max(pBSSList
->ldBmAverage
[ii
], ldBm
);
634 if ((pIE_Country
!= NULL
) && pMgmt
->b11hEnable
) {
635 set_country_info(pMgmt
->pAdapter
, pBSSList
->eNetworkTypeInUse
,
639 if (bParsingQuiet
&& (pIE_Quiet
!= NULL
)) {
640 if ((((PWLAN_IE_QUIET
)pIE_Quiet
)->len
== 8) &&
641 (((PWLAN_IE_QUIET
)pIE_Quiet
)->byQuietCount
!= 0)) {
643 if (pQuiet
== NULL
) {
644 pQuiet
= (PWLAN_IE_QUIET
)pIE_Quiet
;
645 CARDbSetQuiet(pMgmt
->pAdapter
,
647 pQuiet
->byQuietCount
,
648 pQuiet
->byQuietPeriod
,
649 *((unsigned short *)pQuiet
->abyQuietDuration
),
650 *((unsigned short *)pQuiet
->abyQuietOffset
)
653 pQuiet
= (PWLAN_IE_QUIET
)pIE_Quiet
;
654 CARDbSetQuiet(pMgmt
->pAdapter
,
656 pQuiet
->byQuietCount
,
657 pQuiet
->byQuietPeriod
,
658 *((unsigned short *)pQuiet
->abyQuietDuration
),
659 *((unsigned short *)pQuiet
->abyQuietOffset
)
665 if (bParsingQuiet
&& (pQuiet
!= NULL
)) {
666 CARDbStartQuiet(pMgmt
->pAdapter
);
669 pBSSList
->uIELength
= uIELength
;
670 if (pBSSList
->uIELength
> WLAN_BEACON_FR_MAXLEN
)
671 pBSSList
->uIELength
= WLAN_BEACON_FR_MAXLEN
;
672 memcpy(pBSSList
->abyIEs
, pbyIEs
, pBSSList
->uIELength
);
679 * Routine Description:
680 * Search Node DB table to find the index of matched DstAddr
688 BSSDBbIsSTAInNodeDB(void *pMgmtObject
, unsigned char *abyDstAddr
,
689 unsigned int *puNodeIndex
)
691 PSMgmtObject pMgmt
= (PSMgmtObject
) pMgmtObject
;
694 /* Index = 0 reserved for AP Node */
695 for (ii
= 1; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
696 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
697 if (ether_addr_equal(abyDstAddr
,
698 pMgmt
->sNodeDBTable
[ii
].abyMACAddr
)) {
710 * Routine Description:
711 * Find an empty node and allocat it; if there is no empty node,
712 * then use the most inactive one.
719 BSSvCreateOneNode(void *hDeviceContext
, unsigned int *puNodeIndex
)
721 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
722 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
724 unsigned int BigestCount
= 0;
725 unsigned int SelectIndex
;
728 * Index = 0 reserved for AP Node (In STA mode)
729 * Index = 0 reserved for Broadcast/MultiCast (In AP mode)
732 for (ii
= 1; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
733 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
734 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
> BigestCount
) {
735 BigestCount
= pMgmt
->sNodeDBTable
[ii
].uInActiveCount
;
743 /* if not found replace uInActiveCount is largest one */
744 if (ii
== (MAX_NODE_NUM
+ 1)) {
745 *puNodeIndex
= SelectIndex
;
746 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Replace inactive node = %d\n", SelectIndex
);
747 /* clear ps buffer */
748 if (pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
.next
!= NULL
) {
749 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
)) != NULL
)
756 memset(&pMgmt
->sNodeDBTable
[*puNodeIndex
], 0, sizeof(KnownNodeDB
));
757 pMgmt
->sNodeDBTable
[*puNodeIndex
].bActive
= true;
758 pMgmt
->sNodeDBTable
[*puNodeIndex
].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
759 /* for AP mode PS queue */
760 skb_queue_head_init(&pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
);
761 pMgmt
->sNodeDBTable
[*puNodeIndex
].byAuthSequence
= 0;
762 pMgmt
->sNodeDBTable
[*puNodeIndex
].wEnQueueCnt
= 0;
763 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Create node index = %d\n", ii
);
769 * Routine Description:
770 * Remove Node by NodeIndex
779 void *hDeviceContext
,
780 unsigned int uNodeIndex
783 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
784 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
785 unsigned char byMask
[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
788 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[uNodeIndex
].sTxPSQueue
)) != NULL
)
791 memset(&pMgmt
->sNodeDBTable
[uNodeIndex
], 0, sizeof(KnownNodeDB
));
792 /* clear tx bit map */
793 pMgmt
->abyPSTxMap
[pMgmt
->sNodeDBTable
[uNodeIndex
].wAID
>> 3] &= ~byMask
[pMgmt
->sNodeDBTable
[uNodeIndex
].wAID
& 7];
799 * Routine Description:
800 * Update AP Node content in Index 0 of KnownNodeDB
810 void *hDeviceContext
,
811 unsigned short *pwCapInfo
,
812 PWLAN_IE_SUPP_RATES pSuppRates
,
813 PWLAN_IE_SUPP_RATES pExtSuppRates
816 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
817 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
818 unsigned int uRateLen
= WLAN_RATES_MAXLEN
;
820 memset(&pMgmt
->sNodeDBTable
[0], 0, sizeof(KnownNodeDB
));
822 pMgmt
->sNodeDBTable
[0].bActive
= true;
823 if (pDevice
->eCurrentPHYType
== PHY_TYPE_11B
)
824 uRateLen
= WLAN_RATES_MAXLEN_11B
;
825 pMgmt
->abyCurrSuppRates
[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES
)pSuppRates
,
826 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrSuppRates
,
828 pMgmt
->abyCurrExtSuppRates
[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES
)pExtSuppRates
,
829 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrExtSuppRates
,
831 RATEvParseMaxRate((void *)pDevice
,
832 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrSuppRates
,
833 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrExtSuppRates
,
835 &(pMgmt
->sNodeDBTable
[0].wMaxBasicRate
),
836 &(pMgmt
->sNodeDBTable
[0].wMaxSuppRate
),
837 &(pMgmt
->sNodeDBTable
[0].wSuppRate
),
838 &(pMgmt
->sNodeDBTable
[0].byTopCCKBasicRate
),
839 &(pMgmt
->sNodeDBTable
[0].byTopOFDMBasicRate
)
841 memcpy(pMgmt
->sNodeDBTable
[0].abyMACAddr
, pMgmt
->abyCurrBSSID
, WLAN_ADDR_LEN
);
842 pMgmt
->sNodeDBTable
[0].wTxDataRate
= pMgmt
->sNodeDBTable
[0].wMaxSuppRate
;
843 pMgmt
->sNodeDBTable
[0].bShortPreamble
= WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo
);
844 pMgmt
->sNodeDBTable
[0].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
845 netdev_dbg(pDevice
->dev
, "BSSvUpdateAPNode:MaxSuppRate is %d\n",
846 pMgmt
->sNodeDBTable
[0].wMaxSuppRate
);
847 /* auto rate fallback function initiation */
848 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"pMgmt->sNodeDBTable[0].wTxDataRate = %d\n", pMgmt
->sNodeDBTable
[0].wTxDataRate
);
853 * Routine Description:
854 * Add Multicast Node content in Index 0 of KnownNodeDB
863 BSSvAddMulticastNode(
867 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
868 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
870 if (!pDevice
->bEnableHostWEP
)
871 memset(&pMgmt
->sNodeDBTable
[0], 0, sizeof(KnownNodeDB
));
872 memset(pMgmt
->sNodeDBTable
[0].abyMACAddr
, 0xff, WLAN_ADDR_LEN
);
873 pMgmt
->sNodeDBTable
[0].bActive
= true;
874 pMgmt
->sNodeDBTable
[0].bPSEnable
= false;
875 skb_queue_head_init(&pMgmt
->sNodeDBTable
[0].sTxPSQueue
);
876 RATEvParseMaxRate((void *)pDevice
,
877 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrSuppRates
,
878 (PWLAN_IE_SUPP_RATES
)pMgmt
->abyCurrExtSuppRates
,
880 &(pMgmt
->sNodeDBTable
[0].wMaxBasicRate
),
881 &(pMgmt
->sNodeDBTable
[0].wMaxSuppRate
),
882 &(pMgmt
->sNodeDBTable
[0].wSuppRate
),
883 &(pMgmt
->sNodeDBTable
[0].byTopCCKBasicRate
),
884 &(pMgmt
->sNodeDBTable
[0].byTopOFDMBasicRate
)
886 pMgmt
->sNodeDBTable
[0].wTxDataRate
= pMgmt
->sNodeDBTable
[0].wMaxBasicRate
;
887 netdev_dbg(pDevice
->dev
,
888 "BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n",
889 pMgmt
->sNodeDBTable
[0].wTxDataRate
);
890 pMgmt
->sNodeDBTable
[0].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
895 * Routine Description:
898 * Second call back function to update Node DB info & AP link status
905 /* 2008-4-14 <add> by chester for led issue */
906 #ifdef FOR_LED_ON_NOTEBOOK
915 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
916 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
918 PWLAN_IE_SSID pItemSSID
, pCurrSSID
;
919 unsigned int uSleepySTACnt
= 0;
920 unsigned int uNonShortSlotSTACnt
= 0;
921 unsigned int uLongPreambleSTACnt
= 0;
922 viawget_wpa_header
*wpahdr
; /* DavidWang */
924 spin_lock_irq(&pDevice
->lock
);
926 pDevice
->uAssocCount
= 0;
928 pDevice
->byERPFlag
&=
929 ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
930 /* 2008-4-14 <add> by chester for led issue */
931 #ifdef FOR_LED_ON_NOTEBOOK
932 MACvGPIOIn(pDevice
->PortOffset
, &pDevice
->byGPIO
);
933 if (((!(pDevice
->byGPIO
& GPIO0_DATA
) && (!pDevice
->bHWRadioOff
)) ||
934 ((pDevice
->byGPIO
& GPIO0_DATA
) && pDevice
->bHWRadioOff
)) &&
938 if (pDevice
->bHWRadioOff
) {
939 if (!(pDevice
->byGPIO
& GPIO0_DATA
)) {
943 CARDbRadioPowerOff(pDevice
);
944 pMgmt
->sNodeDBTable
[0].bActive
= false;
945 pMgmt
->eCurrMode
= WMAC_MODE_STANDBY
;
946 pMgmt
->eCurrState
= WMAC_STATE_IDLE
;
947 pDevice
->bLinkPass
= false;
950 if (pDevice
->byGPIO
& GPIO0_DATA
) {
954 CARDbRadioPowerOn(pDevice
);
957 if (pDevice
->byGPIO
& GPIO0_DATA
) {
961 CARDbRadioPowerOff(pDevice
);
962 pMgmt
->sNodeDBTable
[0].bActive
= false;
963 pMgmt
->eCurrMode
= WMAC_MODE_STANDBY
;
964 pMgmt
->eCurrState
= WMAC_STATE_IDLE
;
965 pDevice
->bLinkPass
= false;
968 if (!(pDevice
->byGPIO
& GPIO0_DATA
)) {
972 CARDbRadioPowerOn(pDevice
);
979 if (pDevice
->wUseProtectCntDown
> 0) {
980 pDevice
->wUseProtectCntDown
--;
982 /* disable protect mode */
983 pDevice
->byERPFlag
&= ~(WLAN_SET_ERP_USE_PROTECTION(1));
987 pDevice
->byReAssocCount
++;
989 if ((pDevice
->byReAssocCount
> 10) && (!pDevice
->bLinkPass
)) {
990 netdev_info(pDevice
->dev
, "Re-association timeout!!!\n");
991 pDevice
->byReAssocCount
= 0;
992 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
994 union iwreq_data wrqu
;
995 memset(&wrqu
, 0, sizeof(wrqu
));
996 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
997 PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
998 wireless_send_event(pDevice
->dev
, SIOCGIWAP
, &wrqu
, NULL
);
1001 } else if (pDevice
->bLinkPass
)
1002 pDevice
->byReAssocCount
= 0;
1005 #ifdef Calcu_LinkQual
1006 s_uCalculateLinkQual((void *)pDevice
);
1009 for (ii
= 0; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
1010 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
1011 /* increase in-activity counter */
1012 pMgmt
->sNodeDBTable
[ii
].uInActiveCount
++;
1015 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
> MAX_INACTIVE_COUNT
) {
1016 BSSvRemoveOneNode(pDevice
, ii
);
1017 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
1018 "Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT
, ii
);
1022 if (pMgmt
->sNodeDBTable
[ii
].eNodeState
>= NODE_ASSOC
) {
1023 pDevice
->uAssocCount
++;
1025 /* check if Non ERP exist */
1026 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
< ERP_RECOVER_COUNT
) {
1027 if (!pMgmt
->sNodeDBTable
[ii
].bShortPreamble
) {
1028 pDevice
->byERPFlag
|= WLAN_SET_ERP_BARKER_MODE(1);
1029 uLongPreambleSTACnt
++;
1031 if (!pMgmt
->sNodeDBTable
[ii
].bERPExist
) {
1032 pDevice
->byERPFlag
|= WLAN_SET_ERP_NONERP_PRESENT(1);
1033 pDevice
->byERPFlag
|= WLAN_SET_ERP_USE_PROTECTION(1);
1035 if (!pMgmt
->sNodeDBTable
[ii
].bShortSlotTime
)
1036 uNonShortSlotSTACnt
++;
1040 /* check if any STA in PS mode */
1041 if (pMgmt
->sNodeDBTable
[ii
].bPSEnable
)
1046 /* rate fallback check */
1047 if (!pDevice
->bFixRate
) {
1049 /* ii = 0 for multicast node (AP & Adhoc) */
1050 RATEvTxRateFallBack((void *)pDevice
, &(pMgmt
->sNodeDBTable
[ii
]));
1052 /* ii = 0 reserved for unicast AP node (Infra STA) */
1053 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
)
1054 netdev_dbg(pDevice
->dev
,
1055 "SecondCallback:Before:TxDataRate is %d\n",
1056 pMgmt
->sNodeDBTable
[0].wTxDataRate
);
1057 RATEvTxRateFallBack((void *)pDevice
, &(pMgmt
->sNodeDBTable
[ii
]));
1058 netdev_dbg(pDevice
->dev
,
1059 "SecondCallback:After:TxDataRate is %d\n",
1060 pMgmt
->sNodeDBTable
[0].wTxDataRate
);
1066 /* check if pending PS queue */
1067 if (pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
!= 0) {
1068 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Index= %d, Queue = %d pending\n",
1069 ii
, pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
);
1070 if ((ii
> 0) && (pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
> 15)) {
1071 BSSvRemoveOneNode(pDevice
, ii
);
1072 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Pending many queues PS STA Index = %d remove\n", ii
);
1080 if ((pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
) && (pDevice
->eCurrentPHYType
== PHY_TYPE_11G
)) {
1081 /* on/off protect mode */
1082 if (WLAN_GET_ERP_USE_PROTECTION(pDevice
->byERPFlag
)) {
1083 if (!pDevice
->bProtectMode
) {
1084 MACvEnableProtectMD(pDevice
->PortOffset
);
1085 pDevice
->bProtectMode
= true;
1088 if (pDevice
->bProtectMode
) {
1089 MACvDisableProtectMD(pDevice
->PortOffset
);
1090 pDevice
->bProtectMode
= false;
1093 /* on/off short slot time */
1095 if (uNonShortSlotSTACnt
> 0) {
1096 if (pDevice
->bShortSlotTime
) {
1097 pDevice
->bShortSlotTime
= false;
1098 BBvSetShortSlotTime(pDevice
);
1099 vUpdateIFS((void *)pDevice
);
1102 if (!pDevice
->bShortSlotTime
) {
1103 pDevice
->bShortSlotTime
= true;
1104 BBvSetShortSlotTime(pDevice
);
1105 vUpdateIFS((void *)pDevice
);
1109 /* on/off barker long preamble mode */
1111 if (uLongPreambleSTACnt
> 0) {
1112 if (!pDevice
->bBarkerPreambleMd
) {
1113 MACvEnableBarkerPreambleMd(pDevice
->PortOffset
);
1114 pDevice
->bBarkerPreambleMd
= true;
1117 if (pDevice
->bBarkerPreambleMd
) {
1118 MACvDisableBarkerPreambleMd(pDevice
->PortOffset
);
1119 pDevice
->bBarkerPreambleMd
= false;
1125 /* check if any STA in PS mode, enable DTIM multicast deliver */
1126 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
) {
1127 if (uSleepySTACnt
> 0)
1128 pMgmt
->sNodeDBTable
[0].bPSEnable
= true;
1130 pMgmt
->sNodeDBTable
[0].bPSEnable
= false;
1133 pItemSSID
= (PWLAN_IE_SSID
)pMgmt
->abyDesireSSID
;
1134 pCurrSSID
= (PWLAN_IE_SSID
)pMgmt
->abyCurrSSID
;
1136 if ((pMgmt
->eCurrMode
== WMAC_MODE_STANDBY
) ||
1137 (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
)) {
1138 /* assoc with BSS */
1139 if (pMgmt
->sNodeDBTable
[0].bActive
) {
1140 if (pDevice
->bUpdateBBVGA
)
1141 s_vCheckPreEDThreshold((void *)pDevice
);
1143 if ((pMgmt
->sNodeDBTable
[0].uInActiveCount
>= (LOST_BEACON_COUNT
/2)) &&
1144 (pDevice
->byBBVGACurrent
!= pDevice
->abyBBVGA
[0])) {
1145 pDevice
->byBBVGANew
= pDevice
->abyBBVGA
[0];
1146 bScheduleCommand((void *)pDevice
, WLAN_CMD_CHANGE_BBSENSITIVITY
, NULL
);
1149 if (pMgmt
->sNodeDBTable
[0].uInActiveCount
>= LOST_BEACON_COUNT
) {
1150 pMgmt
->sNodeDBTable
[0].bActive
= false;
1151 pMgmt
->eCurrMode
= WMAC_MODE_STANDBY
;
1152 pMgmt
->eCurrState
= WMAC_STATE_IDLE
;
1153 netif_stop_queue(pDevice
->dev
);
1154 pDevice
->bLinkPass
= false;
1155 pDevice
->bRoaming
= true;
1156 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Lost AP beacon [%d] sec, disconnected !\n", pMgmt
->sNodeDBTable
[0].uInActiveCount
);
1157 if ((pDevice
->bWPADEVUp
) && (pDevice
->skb
!= NULL
)) {
1158 wpahdr
= (viawget_wpa_header
*)pDevice
->skb
->data
;
1159 wpahdr
->type
= VIAWGET_DISASSOC_MSG
;
1160 wpahdr
->resp_ie_len
= 0;
1161 wpahdr
->req_ie_len
= 0;
1162 skb_put(pDevice
->skb
, sizeof(viawget_wpa_header
));
1163 pDevice
->skb
->dev
= pDevice
->wpadev
;
1164 skb_reset_mac_header(pDevice
->skb
);
1165 pDevice
->skb
->pkt_type
= PACKET_HOST
;
1166 pDevice
->skb
->protocol
= htons(ETH_P_802_2
);
1167 memset(pDevice
->skb
->cb
, 0, sizeof(pDevice
->skb
->cb
));
1168 netif_rx(pDevice
->skb
);
1169 pDevice
->skb
= dev_alloc_skb((int)pDevice
->rx_buf_sz
);
1171 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1173 union iwreq_data wrqu
;
1174 memset(&wrqu
, 0, sizeof(wrqu
));
1175 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1176 PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
1177 wireless_send_event(pDevice
->dev
, SIOCGIWAP
, &wrqu
, NULL
);
1181 } else if (pItemSSID
->len
!= 0) {
1182 if (pDevice
->uAutoReConnectTime
< 10) {
1183 pDevice
->uAutoReConnectTime
++;
1184 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1186 * network manager support need not do
1189 if (pDevice
->bWPASuppWextEnabled
)
1190 pDevice
->uAutoReConnectTime
= 0;
1194 * mike use old encryption status
1195 * for wpa reauthentication
1197 if (pDevice
->bWPADEVUp
)
1198 pDevice
->eEncryptionStatus
= pDevice
->eOldEncryptionStatus
;
1200 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Roaming ...\n");
1201 BSSvClearBSSList((void *)pDevice
, pDevice
->bLinkPass
);
1202 pMgmt
->eScanType
= WMAC_SCAN_ACTIVE
;
1203 bScheduleCommand((void *)pDevice
, WLAN_CMD_BSSID_SCAN
, pMgmt
->abyDesireSSID
);
1204 bScheduleCommand((void *)pDevice
, WLAN_CMD_SSID
, pMgmt
->abyDesireSSID
);
1205 pDevice
->uAutoReConnectTime
= 0;
1210 if (pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) {
1211 /* if adhoc started which essid is NULL string, rescanning */
1212 if ((pMgmt
->eCurrState
== WMAC_STATE_STARTED
) && (pCurrSSID
->len
== 0)) {
1213 if (pDevice
->uAutoReConnectTime
< 10) {
1214 pDevice
->uAutoReConnectTime
++;
1216 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Adhoc re-scanning ...\n");
1217 pMgmt
->eScanType
= WMAC_SCAN_ACTIVE
;
1218 bScheduleCommand((void *)pDevice
, WLAN_CMD_BSSID_SCAN
, NULL
);
1219 bScheduleCommand((void *)pDevice
, WLAN_CMD_SSID
, NULL
);
1220 pDevice
->uAutoReConnectTime
= 0;
1223 if (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
) {
1224 if (pDevice
->bUpdateBBVGA
)
1225 s_vCheckPreEDThreshold((void *)pDevice
);
1226 if (pMgmt
->sNodeDBTable
[0].uInActiveCount
>= ADHOC_LOST_BEACON_COUNT
) {
1227 DBG_PRT(MSG_LEVEL_NOTICE
, KERN_INFO
"Lost other STA beacon [%d] sec, started !\n", pMgmt
->sNodeDBTable
[0].uInActiveCount
);
1228 pMgmt
->sNodeDBTable
[0].uInActiveCount
= 0;
1229 pMgmt
->eCurrState
= WMAC_STATE_STARTED
;
1230 netif_stop_queue(pDevice
->dev
);
1231 pDevice
->bLinkPass
= false;
1236 spin_unlock_irq(&pDevice
->lock
);
1238 pMgmt
->sTimerSecondCallback
.expires
= RUN_AT(HZ
);
1239 add_timer(&pMgmt
->sTimerSecondCallback
);
1245 * Routine Description:
1248 * Update Tx attemps, Tx failure counter in Node DB
1257 BSSvUpdateNodeTxCounter(
1258 void *hDeviceContext
,
1259 unsigned char byTsr0
,
1260 unsigned char byTsr1
,
1261 unsigned char *pbyBuffer
,
1262 unsigned int uFIFOHeaderSize
1265 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1266 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
1267 unsigned int uNodeIndex
= 0;
1268 unsigned char byTxRetry
= (byTsr0
& TSR0_NCR
);
1269 PSTxBufHead pTxBufHead
;
1270 PS802_11Header pMACHeader
;
1271 unsigned short wRate
;
1272 unsigned short wFallBackRate
= RATE_1M
;
1273 unsigned char byFallBack
;
1275 pTxBufHead
= (PSTxBufHead
) pbyBuffer
;
1276 if (pTxBufHead
->wFIFOCtl
& FIFOCTL_AUTO_FB_0
)
1277 byFallBack
= AUTO_FB_0
;
1278 else if (pTxBufHead
->wFIFOCtl
& FIFOCTL_AUTO_FB_1
)
1279 byFallBack
= AUTO_FB_1
;
1281 byFallBack
= AUTO_FB_NONE
;
1282 wRate
= pTxBufHead
->wReserved
;
1284 /* Only Unicast using support rates */
1285 if (pTxBufHead
->wFIFOCtl
& FIFOCTL_NEEDACK
) {
1286 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"wRate %04X, byTsr0 %02X, byTsr1 %02X\n", wRate
, byTsr0
, byTsr1
);
1287 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) {
1288 pMgmt
->sNodeDBTable
[0].uTxAttempts
+= 1;
1289 if ((byTsr1
& TSR1_TERR
) == 0) {
1290 /* transmit success, TxAttempts at least plus one */
1291 pMgmt
->sNodeDBTable
[0].uTxOk
[MAX_RATE
]++;
1292 if ((byFallBack
== AUTO_FB_NONE
) ||
1293 (wRate
< RATE_18M
)) {
1294 wFallBackRate
= wRate
;
1295 } else if (byFallBack
== AUTO_FB_0
) {
1297 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][byTxRetry
];
1299 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][4];
1300 } else if (byFallBack
== AUTO_FB_1
) {
1302 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][byTxRetry
];
1304 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1306 pMgmt
->sNodeDBTable
[0].uTxOk
[wFallBackRate
]++;
1308 pMgmt
->sNodeDBTable
[0].uTxFailures
++;
1310 pMgmt
->sNodeDBTable
[0].uTxRetry
+= byTxRetry
;
1311 if (byTxRetry
!= 0) {
1312 pMgmt
->sNodeDBTable
[0].uTxFail
[MAX_RATE
] += byTxRetry
;
1313 if ((byFallBack
== AUTO_FB_NONE
) ||
1314 (wRate
< RATE_18M
)) {
1315 pMgmt
->sNodeDBTable
[0].uTxFail
[wRate
] += byTxRetry
;
1316 } else if (byFallBack
== AUTO_FB_0
) {
1317 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1319 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][ii
];
1321 wFallBackRate
= 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
++) {
1327 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][ii
];
1329 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1330 pMgmt
->sNodeDBTable
[0].uTxFail
[wFallBackRate
]++;
1336 if ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) ||
1337 (pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
)) {
1338 pMACHeader
= (PS802_11Header
)(pbyBuffer
+ uFIFOHeaderSize
);
1340 if (BSSDBbIsSTAInNodeDB((void *)pMgmt
, &(pMACHeader
->abyAddr1
[0]), &uNodeIndex
)) {
1341 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxAttempts
+= 1;
1342 if ((byTsr1
& TSR1_TERR
) == 0) {
1343 /* transmit success, TxAttempts at least plus one */
1344 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxOk
[MAX_RATE
]++;
1345 if ((byFallBack
== AUTO_FB_NONE
) ||
1346 (wRate
< RATE_18M
)) {
1347 wFallBackRate
= wRate
;
1348 } else if (byFallBack
== AUTO_FB_0
) {
1350 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][byTxRetry
];
1352 wFallBackRate
= awHWRetry0
[wRate
-RATE_18M
][4];
1353 } else if (byFallBack
== AUTO_FB_1
) {
1355 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][byTxRetry
];
1357 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1359 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxOk
[wFallBackRate
]++;
1361 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFailures
++;
1363 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxRetry
+= byTxRetry
;
1364 if (byTxRetry
!= 0) {
1365 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[MAX_RATE
] += byTxRetry
;
1366 if ((byFallBack
== AUTO_FB_NONE
) ||
1367 (wRate
< RATE_18M
)) {
1368 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wRate
] += byTxRetry
;
1369 } else if (byFallBack
== AUTO_FB_0
) {
1370 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1372 wFallBackRate
= awHWRetry0
[wRate
- RATE_18M
][ii
];
1374 wFallBackRate
= awHWRetry0
[wRate
- RATE_18M
][4];
1375 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wFallBackRate
]++;
1377 } else if (byFallBack
== AUTO_FB_1
) {
1378 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1380 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][ii
];
1382 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1383 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wFallBackRate
]++;
1396 * Routine Description:
1397 * Clear Nodes & skb in DB Table
1402 * hDeviceContext - The adapter context.
1403 * uStartIndex - starting index
1413 BSSvClearNodeDBTable(
1414 void *hDeviceContext
,
1415 unsigned int uStartIndex
1419 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1420 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
1421 struct sk_buff
*skb
;
1424 for (ii
= uStartIndex
; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
1425 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
1426 /* check if sTxPSQueue has been initial */
1427 if (pMgmt
->sNodeDBTable
[ii
].sTxPSQueue
.next
!= NULL
) {
1428 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[ii
].sTxPSQueue
)) != NULL
) {
1429 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"PS skb != NULL %d\n", ii
);
1433 memset(&pMgmt
->sNodeDBTable
[ii
], 0, sizeof(KnownNodeDB
));
1440 void s_vCheckSensitivity(
1441 void *hDeviceContext
1444 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1445 PKnownBSS pBSSList
= NULL
;
1446 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
1449 if ((pDevice
->byLocalID
<= REV_ID_VT3253_A1
) && (pDevice
->byRFType
== RF_RFMD2959
) &&
1450 (pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
)) {
1454 if ((pMgmt
->eCurrState
== WMAC_STATE_ASSOC
) ||
1455 ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) && (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
))) {
1456 pBSSList
= BSSpAddrIsInBSSList(pDevice
, pMgmt
->abyCurrBSSID
, (PWLAN_IE_SSID
)pMgmt
->abyCurrSSID
);
1457 if (pBSSList
!= NULL
) {
1458 /* Update BB Reg if RSSI is too strong */
1459 long LocalldBmAverage
= 0;
1461 for (ii
= 0; ii
< RSSI_STAT_COUNT
; ii
++) {
1462 if (pBSSList
->ldBmAverage
[ii
] != 0) {
1464 LocalldBmAverage
+= pBSSList
->ldBmAverage
[ii
];
1467 if (uNumofdBm
> 0) {
1468 LocalldBmAverage
= LocalldBmAverage
/uNumofdBm
;
1469 for (ii
= 0; ii
< BB_VGA_LEVEL
; ii
++) {
1470 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage
, pDevice
->ldBmThreshold
[ii
], pDevice
->abyBBVGA
[ii
]);
1471 if (LocalldBmAverage
< pDevice
->ldBmThreshold
[ii
]) {
1472 pDevice
->byBBVGANew
= pDevice
->abyBBVGA
[ii
];
1476 if (pDevice
->byBBVGANew
!= pDevice
->byBBVGACurrent
) {
1477 pDevice
->uBBVGADiffCount
++;
1478 if (pDevice
->uBBVGADiffCount
>= BB_VGA_CHANGE_THRESHOLD
)
1479 bScheduleCommand((void *)pDevice
, WLAN_CMD_CHANGE_BBSENSITIVITY
, NULL
);
1481 pDevice
->uBBVGADiffCount
= 0;
1489 BSSvClearAnyBSSJoinRecord(
1490 void *hDeviceContext
1493 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1494 PSMgmtObject pMgmt
= pDevice
->pMgmt
;
1497 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++)
1498 pMgmt
->sBSSList
[ii
].bSelected
= false;
1502 #ifdef Calcu_LinkQual
1503 void s_uCalculateLinkQual(
1504 void *hDeviceContext
1507 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1508 unsigned long TxOkRatio
, TxCnt
;
1509 unsigned long RxOkRatio
, RxCnt
;
1510 unsigned long RssiRatio
;
1513 TxCnt
= pDevice
->scStatistic
.TxNoRetryOkCount
+
1514 pDevice
->scStatistic
.TxRetryOkCount
+
1515 pDevice
->scStatistic
.TxFailCount
;
1516 RxCnt
= pDevice
->scStatistic
.RxFcsErrCnt
+
1517 pDevice
->scStatistic
.RxOkCnt
;
1518 TxOkRatio
= (TxCnt
< 6) ? 4000 : ((pDevice
->scStatistic
.TxNoRetryOkCount
* 4000) / TxCnt
);
1519 RxOkRatio
= (RxCnt
< 6) ? 2000 : ((pDevice
->scStatistic
.RxOkCnt
* 2000) / RxCnt
);
1520 /* decide link quality */
1521 if (!pDevice
->bLinkPass
) {
1522 pDevice
->scStatistic
.LinkQuality
= 0;
1523 pDevice
->scStatistic
.SignalStren
= 0;
1525 RFvRSSITodBm(pDevice
, (unsigned char)(pDevice
->uCurrRSSI
), &ldBm
);
1528 else if (-ldBm
> 90)
1531 RssiRatio
= (40-(-ldBm
-50))*4000/40;
1532 pDevice
->scStatistic
.SignalStren
= RssiRatio
/40;
1533 pDevice
->scStatistic
.LinkQuality
= (RssiRatio
+TxOkRatio
+RxOkRatio
)/100;
1535 pDevice
->scStatistic
.RxFcsErrCnt
= 0;
1536 pDevice
->scStatistic
.RxOkCnt
= 0;
1537 pDevice
->scStatistic
.TxFailCount
= 0;
1538 pDevice
->scStatistic
.TxNoRetryOkCount
= 0;
1539 pDevice
->scStatistic
.TxRetryOkCount
= 0;
1544 void s_vCheckPreEDThreshold(
1545 void *hDeviceContext
1548 PSDevice pDevice
= (PSDevice
)hDeviceContext
;
1549 PKnownBSS pBSSList
= NULL
;
1550 PSMgmtObject pMgmt
= &(pDevice
->sMgmtObj
);
1552 if ((pMgmt
->eCurrState
== WMAC_STATE_ASSOC
) ||
1553 ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) && (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
))) {
1554 pBSSList
= BSSpAddrIsInBSSList(pDevice
, pMgmt
->abyCurrBSSID
, (PWLAN_IE_SSID
)pMgmt
->abyCurrSSID
);
1555 if (pBSSList
!= NULL
)
1556 pDevice
->byBBPreEDRSSI
= (unsigned char) (~(pBSSList
->ldBmAverRange
) + 1);