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-fallback rate control
60 static int msglevel
= MSG_LEVEL_INFO
;
61 /* static int msglevel = MSG_LEVEL_DEBUG; */
63 static const u16 awHWRetry0
[5][5] = {
64 {RATE_18M
, RATE_18M
, RATE_12M
, RATE_12M
, RATE_12M
},
65 {RATE_24M
, RATE_24M
, RATE_18M
, RATE_12M
, RATE_12M
},
66 {RATE_36M
, RATE_36M
, RATE_24M
, RATE_18M
, RATE_18M
},
67 {RATE_48M
, RATE_48M
, RATE_36M
, RATE_24M
, RATE_24M
},
68 {RATE_54M
, RATE_54M
, RATE_48M
, RATE_36M
, RATE_36M
}
70 static const u16 awHWRetry1
[5][5] = {
71 {RATE_18M
, RATE_18M
, RATE_12M
, RATE_6M
, RATE_6M
},
72 {RATE_24M
, RATE_24M
, RATE_18M
, RATE_6M
, RATE_6M
},
73 {RATE_36M
, RATE_36M
, RATE_24M
, RATE_12M
, RATE_12M
},
74 {RATE_48M
, RATE_48M
, RATE_24M
, RATE_12M
, RATE_12M
},
75 {RATE_54M
, RATE_54M
, RATE_36M
, RATE_18M
, RATE_18M
}
78 static void s_vCheckSensitivity(struct vnt_private
*pDevice
);
79 static void s_vCheckPreEDThreshold(struct vnt_private
*pDevice
);
80 static void s_uCalculateLinkQual(struct vnt_private
*pDevice
);
83 * Routine Description:
84 * Search known BSS list for Desire SSID or BSSID.
87 * PTR to KnownBSS or NULL
89 PKnownBSS
BSSpSearchBSSList(struct vnt_private
*pDevice
,
90 u8
*pbyDesireBSSID
, u8
*pbyDesireSSID
,
91 CARD_PHY_TYPE ePhyType
)
93 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
95 PWLAN_IE_SSID pSSID
= NULL
;
96 PKnownBSS pCurrBSS
= NULL
;
97 PKnownBSS pSelect
= NULL
;
98 u8 ZeroBSSID
[WLAN_BSSID_LEN
] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
102 if (pbyDesireBSSID
) {
103 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
104 "BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID
);
105 if (!is_broadcast_ether_addr(pbyDesireBSSID
) &&
106 memcmp(pbyDesireBSSID
, ZeroBSSID
, 6) != 0)
107 pbyBSSID
= pbyDesireBSSID
;
110 ((PWLAN_IE_SSID
) pbyDesireSSID
)->len
!= 0)
111 pSSID
= (PWLAN_IE_SSID
) pbyDesireSSID
;
113 if (pbyBSSID
&& pDevice
->bRoaming
== false) {
114 /* match BSSID first */
115 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
116 pCurrBSS
= &(pMgmt
->sBSSList
[ii
]);
118 pCurrBSS
->bSelected
= false;
120 if (pCurrBSS
->bActive
&&
121 pCurrBSS
->bSelected
== false &&
122 ether_addr_equal(pCurrBSS
->abyBSSID
, pbyBSSID
)) {
125 if (!memcmp(pSSID
->abySSID
,
126 ((PWLAN_IE_SSID
) pCurrBSS
->abySSID
)->abySSID
,
128 (pMgmt
->eConfigMode
== WMAC_CONFIG_AUTO
||
129 (pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
&&
130 WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
)) ||
131 (pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
&&
132 WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
)))) {
134 pCurrBSS
->bSelected
= true;
137 } else if (pMgmt
->eConfigMode
== WMAC_CONFIG_AUTO
||
138 (pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
&&
139 WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
)) ||
140 (pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
&&
141 WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
))) {
142 pCurrBSS
->bSelected
= true;
149 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
150 pCurrBSS
= &(pMgmt
->sBSSList
[ii
]);
152 /* 2007-0721-01<Mark>by MikeLiu
153 * if ((pCurrBSS->bActive) &&
154 * (pCurrBSS->bSelected == false)) { */
156 pCurrBSS
->bSelected
= false;
157 if (pCurrBSS
->bActive
) {
161 (memcmp(pSSID
->abySSID
,
162 ((PWLAN_IE_SSID
) pCurrBSS
->abySSID
)->abySSID
,
165 ((PWLAN_IE_SSID
) pCurrBSS
->abySSID
)->len
)) {
166 /* SSID not match skip this BSS */
170 if ((pMgmt
->eConfigMode
== WMAC_CONFIG_IBSS_STA
&&
171 WLAN_GET_CAP_INFO_ESS(pCurrBSS
->wCapInfo
)) ||
172 (pMgmt
->eConfigMode
== WMAC_CONFIG_ESS_STA
&&
173 WLAN_GET_CAP_INFO_IBSS(pCurrBSS
->wCapInfo
))) {
174 /* Type not match skip this BSS */
175 DBG_PRT(MSG_LEVEL_DEBUG
,
176 KERN_INFO
"BSS type mismatch.... Config[%d] BSS[0x%04x]\n",
182 if (ePhyType
!= PHY_TYPE_AUTO
&&
183 ((ePhyType
== PHY_TYPE_11A
&&
184 PHY_TYPE_11A
!= pCurrBSS
->eNetworkTypeInUse
) ||
185 (ePhyType
!= PHY_TYPE_11A
&&
186 PHY_TYPE_11A
== pCurrBSS
->eNetworkTypeInUse
))) {
187 /* PhyType not match skip this BSS */
188 DBG_PRT(MSG_LEVEL_DEBUG
,
189 KERN_INFO
"Physical type mismatch.... ePhyType[%d] BSS[%d]\n",
191 pCurrBSS
->eNetworkTypeInUse
);
195 pMgmt
->pSameBSS
[jj
].uChannel
= pCurrBSS
->uChannel
;
196 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
197 "BSSpSearchBSSList pSelect1[%pM]\n",
203 /* compare RSSI, select the strongest signal */
204 else if (pCurrBSS
->uRSSI
< pSelect
->uRSSI
)
209 pDevice
->bSameBSSMaxNum
= jj
;
212 pSelect
->bSelected
= true;
213 if (pDevice
->bRoaming
== false) {
214 /* Einsn Add @20070907 */
215 memcpy(pbyDesireSSID
,
217 WLAN_IEHDR_LEN
+ WLAN_SSID_MAXLEN
+ 1);
228 * Routine Description:
234 void BSSvClearBSSList(struct vnt_private
*pDevice
, int bKeepCurrBSSID
)
236 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
239 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
240 if (bKeepCurrBSSID
&&
241 pMgmt
->sBSSList
[ii
].bActive
&&
242 ether_addr_equal(pMgmt
->sBSSList
[ii
].abyBSSID
,
243 pMgmt
->abyCurrBSSID
)) {
246 * there are two BSSID's in list. If that AP is
247 * in hidden ssid mode, one SSID is null, but
248 * other's might not be obvious, so if it
249 * associate's with your STA, you must keep the
250 * two of them!! bKeepCurrBSSID = false;
256 pMgmt
->sBSSList
[ii
].bActive
= false;
257 memset(&pMgmt
->sBSSList
[ii
], 0, sizeof(KnownBSS
));
259 BSSvClearAnyBSSJoinRecord(pDevice
);
263 * Routine Description:
264 * search BSS list by BSSID & SSID if matched
269 PKnownBSS
BSSpAddrIsInBSSList(struct vnt_private
*pDevice
,
273 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
274 PKnownBSS pBSSList
= NULL
;
277 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
278 pBSSList
= &(pMgmt
->sBSSList
[ii
]);
279 if (pBSSList
->bActive
&&
280 ether_addr_equal(pBSSList
->abyBSSID
, abyBSSID
) &&
281 pSSID
->len
== ((PWLAN_IE_SSID
) pBSSList
->abySSID
)->len
&&
282 memcmp(pSSID
->abySSID
,
283 ((PWLAN_IE_SSID
) pBSSList
->abySSID
)->abySSID
,
292 * Routine Description:
293 * Insert a BSS set into known BSS list
298 int BSSbInsertToBSSList(struct vnt_private
*pDevice
,
305 PWLAN_IE_SUPP_RATES pSuppRates
,
306 PWLAN_IE_SUPP_RATES pExtSuppRates
,
309 PWLAN_IE_RSN_EXT pRSNWPA
,
310 PWLAN_IE_COUNTRY pIE_Country
,
311 PWLAN_IE_QUIET pIE_Quiet
,
314 void *pRxPacketContext
)
316 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
317 struct vnt_rx_mgmt
*pRxPacket
=
318 (struct vnt_rx_mgmt
*) pRxPacketContext
;
319 PKnownBSS pBSSList
= NULL
;
321 bool bParsingQuiet
= false;
323 pBSSList
= (PKnownBSS
) &(pMgmt
->sBSSList
[0]);
325 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++) {
326 pBSSList
= (PKnownBSS
) &(pMgmt
->sBSSList
[ii
]);
327 if (!pBSSList
->bActive
)
331 if (ii
== MAX_BSS_NUM
) {
332 DBG_PRT(MSG_LEVEL_DEBUG
,
333 KERN_INFO
"Get free KnowBSS node failed.\n");
336 /* save the BSS info */
337 pBSSList
->bActive
= true;
338 memcpy(pBSSList
->abyBSSID
, abyBSSIDAddr
, WLAN_BSSID_LEN
);
339 pBSSList
->qwBSSTimestamp
= cpu_to_le64(qwTimestamp
);
340 pBSSList
->wBeaconInterval
= cpu_to_le16(wBeaconInterval
);
341 pBSSList
->wCapInfo
= cpu_to_le16(wCapInfo
);
342 pBSSList
->uClearCount
= 0;
344 if (pSSID
->len
> WLAN_SSID_MAXLEN
)
345 pSSID
->len
= WLAN_SSID_MAXLEN
;
346 memcpy(pBSSList
->abySSID
, pSSID
, pSSID
->len
+ WLAN_IEHDR_LEN
);
348 pBSSList
->uChannel
= byCurrChannel
;
350 if (pSuppRates
->len
> WLAN_RATES_MAXLEN
)
351 pSuppRates
->len
= WLAN_RATES_MAXLEN
;
352 memcpy(pBSSList
->abySuppRates
, pSuppRates
,
353 pSuppRates
->len
+ WLAN_IEHDR_LEN
);
356 if (pExtSuppRates
->len
> WLAN_RATES_MAXLEN
)
357 pExtSuppRates
->len
= WLAN_RATES_MAXLEN
;
358 memcpy(pBSSList
->abyExtSuppRates
, pExtSuppRates
,
359 pExtSuppRates
->len
+ WLAN_IEHDR_LEN
);
360 DBG_PRT(MSG_LEVEL_DEBUG
,
361 KERN_INFO
"BSSbInsertToBSSList: pExtSuppRates->len = %d\n",
365 memset(pBSSList
->abyExtSuppRates
, 0,
366 WLAN_IEHDR_LEN
+ WLAN_RATES_MAXLEN
+ 1);
368 pBSSList
->sERP
.byERP
= psERP
->byERP
;
369 pBSSList
->sERP
.bERPExist
= psERP
->bERPExist
;
371 /* Check if BSS is 802.11a/b/g */
372 if (pBSSList
->uChannel
> CB_MAX_CHANNEL_24G
)
373 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11A
;
374 else if (pBSSList
->sERP
.bERPExist
== true)
375 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11G
;
377 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11B
;
379 pBSSList
->byRxRate
= pRxPacket
->byRxRate
;
380 pBSSList
->qwLocalTSF
= pRxPacket
->qwLocalTSF
;
381 pBSSList
->uRSSI
= pRxPacket
->uRSSI
;
382 pBSSList
->bySQ
= pRxPacket
->bySQ
;
384 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
&&
385 pMgmt
->eCurrState
== WMAC_STATE_ASSOC
&&
387 pBSSList
== pMgmt
->pCurrBSS
)
388 bParsingQuiet
= true;
390 WPA_ClearRSN(pBSSList
);
393 unsigned int uLen
= pRSNWPA
->len
+ 2;
395 if (uLen
<= (uIELength
-
396 (unsigned int) (u32
) ((u8
*) pRSNWPA
- pbyIEs
))) {
397 pBSSList
->wWPALen
= uLen
;
398 memcpy(pBSSList
->byWPAIE
, pRSNWPA
, uLen
);
399 WPA_ParseRSN(pBSSList
, pRSNWPA
);
403 WPA2_ClearRSN(pBSSList
);
406 unsigned int uLen
= pRSN
->len
+ 2;
408 if (uLen
<= (uIELength
-
409 (unsigned int) (u32
) ((u8
*) pRSN
- pbyIEs
))) {
410 pBSSList
->wRSNLen
= uLen
;
411 memcpy(pBSSList
->byRSNIE
, pRSN
, uLen
);
412 WPA2vParseRSN(pBSSList
, pRSN
);
416 if (pMgmt
->eAuthenMode
== WMAC_AUTH_WPA2
||
417 pBSSList
->bWPA2Valid
== true) {
419 PSKeyItem pTransmitKey
= NULL
;
420 bool bIs802_1x
= false;
422 for (ii
= 0; ii
< pBSSList
->wAKMSSAuthCount
; ii
++) {
423 if (pBSSList
->abyAKMSSAuthType
[ii
] ==
424 WLAN_11i_AKMSS_802_1X
) {
429 if (bIs802_1x
== true &&
430 pSSID
->len
== ((PWLAN_IE_SSID
) pMgmt
->abyDesireSSID
)->len
&&
431 !memcmp(pSSID
->abySSID
,
432 ((PWLAN_IE_SSID
) pMgmt
->abyDesireSSID
)->abySSID
,
435 bAdd_PMKID_Candidate((void *) pDevice
,
437 &pBSSList
->sRSNCapObj
);
439 if (pDevice
->bLinkPass
== true &&
440 pMgmt
->eCurrState
== WMAC_STATE_ASSOC
&&
441 (KeybGetTransmitKey(&(pDevice
->sKey
),
444 &pTransmitKey
) == true ||
445 KeybGetTransmitKey(&(pDevice
->sKey
),
448 &pTransmitKey
) == true)) {
449 pDevice
->gsPMKIDCandidate
.StatusType
=
450 Ndis802_11StatusType_PMKID_CandidateList
;
451 pDevice
->gsPMKIDCandidate
.Version
= 1;
458 /* Monitor if RSSI is too strong. */
459 pBSSList
->byRSSIStatCnt
= 0;
461 vnt_rf_rssi_to_dbm(pDevice
, (u8
)pRxPacket
->uRSSI
, &pBSSList
->ldBmMAX
);
463 pBSSList
->ldBmAverage
[0] = pBSSList
->ldBmMAX
;
464 pBSSList
->ldBmAverRange
= pBSSList
->ldBmMAX
;
465 for (ii
= 1; ii
< RSSI_STAT_COUNT
; ii
++)
466 pBSSList
->ldBmAverage
[ii
] = 0;
468 pBSSList
->uIELength
= uIELength
;
469 if (pBSSList
->uIELength
> WLAN_BEACON_FR_MAXLEN
)
470 pBSSList
->uIELength
= WLAN_BEACON_FR_MAXLEN
;
471 memcpy(pBSSList
->abyIEs
, pbyIEs
, pBSSList
->uIELength
);
477 * Routine Description:
478 * Update BSS set in known BSS list
483 /* TODO: input structure modify */
484 int BSSbUpdateToBSSList(struct vnt_private
*pDevice
,
491 PWLAN_IE_SUPP_RATES pSuppRates
,
492 PWLAN_IE_SUPP_RATES pExtSuppRates
,
495 PWLAN_IE_RSN_EXT pRSNWPA
,
496 PWLAN_IE_COUNTRY pIE_Country
,
497 PWLAN_IE_QUIET pIE_Quiet
,
501 void *pRxPacketContext
)
503 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
504 struct vnt_rx_mgmt
*pRxPacket
=
505 (struct vnt_rx_mgmt
*) pRxPacketContext
;
507 signed long ldBm
, ldBmSum
;
508 bool bParsingQuiet
= false;
513 pBSSList
->qwBSSTimestamp
= cpu_to_le64(qwTimestamp
);
515 pBSSList
->wBeaconInterval
= cpu_to_le16(wBeaconInterval
);
516 pBSSList
->wCapInfo
= cpu_to_le16(wCapInfo
);
517 pBSSList
->uClearCount
= 0;
518 pBSSList
->uChannel
= byCurrChannel
;
520 if (pSSID
->len
> WLAN_SSID_MAXLEN
)
521 pSSID
->len
= WLAN_SSID_MAXLEN
;
523 if (pSSID
->len
!= 0 && pSSID
->abySSID
[0] != 0)
524 memcpy(pBSSList
->abySSID
, pSSID
, pSSID
->len
+ WLAN_IEHDR_LEN
);
525 memcpy(pBSSList
->abySuppRates
, pSuppRates
,
526 pSuppRates
->len
+ WLAN_IEHDR_LEN
);
529 memcpy(pBSSList
->abyExtSuppRates
, pExtSuppRates
,
530 pExtSuppRates
->len
+ WLAN_IEHDR_LEN
);
532 memset(pBSSList
->abyExtSuppRates
, 0,
533 WLAN_IEHDR_LEN
+ WLAN_RATES_MAXLEN
+ 1);
534 pBSSList
->sERP
.byERP
= psERP
->byERP
;
535 pBSSList
->sERP
.bERPExist
= psERP
->bERPExist
;
537 /* Check if BSS is 802.11a/b/g */
538 if (pBSSList
->uChannel
> CB_MAX_CHANNEL_24G
)
539 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11A
;
540 else if (pBSSList
->sERP
.bERPExist
== true)
541 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11G
;
543 pBSSList
->eNetworkTypeInUse
= PHY_TYPE_11B
;
545 pBSSList
->byRxRate
= pRxPacket
->byRxRate
;
546 pBSSList
->qwLocalTSF
= pRxPacket
->qwLocalTSF
;
548 pBSSList
->uRSSI
= pRxPacket
->uRSSI
;
549 pBSSList
->bySQ
= pRxPacket
->bySQ
;
551 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
&&
552 pMgmt
->eCurrState
== WMAC_STATE_ASSOC
&&
554 pBSSList
== pMgmt
->pCurrBSS
)
555 bParsingQuiet
= true;
557 WPA_ClearRSN(pBSSList
); /* mike update */
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 vnt_rf_rssi_to_dbm(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
);
609 * Routine Description:
610 * Search Node DB table to find the index of matched DstAddr
615 int BSSbIsSTAInNodeDB(struct vnt_private
*pDevice
,
619 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
622 /* Index = 0 reserved for AP Node */
623 for (ii
= 1; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
624 if (pMgmt
->sNodeDBTable
[ii
].bActive
&&
625 ether_addr_equal(abyDstAddr
,
626 pMgmt
->sNodeDBTable
[ii
].abyMACAddr
)) {
636 * Routine Description:
637 * Find an empty node and allocate it; if no empty node
638 * is found, then use the most inactive one.
643 void BSSvCreateOneNode(struct vnt_private
*pDevice
, u32
*puNodeIndex
)
645 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
651 /* Index = 0 reserved for AP Node (In STA mode)
652 Index = 0 reserved for Broadcast/MultiCast (In AP mode) */
654 for (ii
= 1; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
655 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
656 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
> BigestCount
) {
658 pMgmt
->sNodeDBTable
[ii
].uInActiveCount
;
666 /* if not found replace uInActiveCount with the largest one. */
667 if (ii
== (MAX_NODE_NUM
+ 1)) {
668 *puNodeIndex
= SelectIndex
;
669 DBG_PRT(MSG_LEVEL_DEBUG
,
670 KERN_INFO
"Replace inactive node = %d\n", SelectIndex
);
671 /* clear ps buffer */
672 if (pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
.next
) {
673 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
)))
680 memset(&pMgmt
->sNodeDBTable
[*puNodeIndex
], 0, sizeof(KnownNodeDB
));
681 pMgmt
->sNodeDBTable
[*puNodeIndex
].bActive
= true;
682 pMgmt
->sNodeDBTable
[*puNodeIndex
].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
683 /* for AP mode PS queue */
684 skb_queue_head_init(&pMgmt
->sNodeDBTable
[*puNodeIndex
].sTxPSQueue
);
685 pMgmt
->sNodeDBTable
[*puNodeIndex
].byAuthSequence
= 0;
686 pMgmt
->sNodeDBTable
[*puNodeIndex
].wEnQueueCnt
= 0;
687 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Create node index = %d\n", ii
);
691 * Routine Description:
692 * Remove Node by NodeIndex
698 void BSSvRemoveOneNode(struct vnt_private
*pDevice
, u32 uNodeIndex
)
700 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
701 u8 byMask
[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
704 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[uNodeIndex
].sTxPSQueue
)))
707 memset(&pMgmt
->sNodeDBTable
[uNodeIndex
], 0, sizeof(KnownNodeDB
));
708 /* clear tx bit map */
709 pMgmt
->abyPSTxMap
[pMgmt
->sNodeDBTable
[uNodeIndex
].wAID
>> 3] &=
710 ~byMask
[pMgmt
->sNodeDBTable
[uNodeIndex
].wAID
& 7];
714 * Routine Description:
715 * Update AP Node content in Index 0 of KnownNodeDB
721 void BSSvUpdateAPNode(struct vnt_private
*pDevice
,
723 PWLAN_IE_SUPP_RATES pSuppRates
,
724 PWLAN_IE_SUPP_RATES pExtSuppRates
)
726 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
727 u32 uRateLen
= WLAN_RATES_MAXLEN
;
729 memset(&pMgmt
->sNodeDBTable
[0], 0, sizeof(KnownNodeDB
));
731 pMgmt
->sNodeDBTable
[0].bActive
= true;
732 if (pDevice
->byBBType
== BB_TYPE_11B
)
733 uRateLen
= WLAN_RATES_MAXLEN_11B
;
734 pMgmt
->abyCurrSuppRates
[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES
) pSuppRates
,
735 (PWLAN_IE_SUPP_RATES
) pMgmt
->abyCurrSuppRates
,
737 pMgmt
->abyCurrExtSuppRates
[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES
) pExtSuppRates
,
738 (PWLAN_IE_SUPP_RATES
) pMgmt
->abyCurrExtSuppRates
,
740 RATEvParseMaxRate((void *) pDevice
,
741 (PWLAN_IE_SUPP_RATES
) pMgmt
->abyCurrSuppRates
,
742 (PWLAN_IE_SUPP_RATES
) pMgmt
->abyCurrExtSuppRates
,
744 &(pMgmt
->sNodeDBTable
[0].wMaxBasicRate
),
745 &(pMgmt
->sNodeDBTable
[0].wMaxSuppRate
),
746 &(pMgmt
->sNodeDBTable
[0].wSuppRate
),
747 &(pMgmt
->sNodeDBTable
[0].byTopCCKBasicRate
),
748 &(pMgmt
->sNodeDBTable
[0].byTopOFDMBasicRate
));
749 memcpy(pMgmt
->sNodeDBTable
[0].abyMACAddr
, pMgmt
->abyCurrBSSID
,
751 pMgmt
->sNodeDBTable
[0].wTxDataRate
= pMgmt
->sNodeDBTable
[0].wMaxSuppRate
;
752 pMgmt
->sNodeDBTable
[0].bShortPreamble
=
753 WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo
);
754 pMgmt
->sNodeDBTable
[0].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
755 /* Auto rate fallback function initiation.
756 * RATEbInit(pDevice); */
757 DBG_PRT(MSG_LEVEL_DEBUG
,
758 KERN_INFO
"pMgmt->sNodeDBTable[0].wTxDataRate = %d\n",
759 pMgmt
->sNodeDBTable
[0].wTxDataRate
);
764 * Routine Description:
765 * Add Multicast Node content in Index 0 of KnownNodeDB
771 void BSSvAddMulticastNode(struct vnt_private
*pDevice
)
773 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
775 memset(&pMgmt
->sNodeDBTable
[0], 0, sizeof(KnownNodeDB
));
777 memset(pMgmt
->sNodeDBTable
[0].abyMACAddr
, 0xff, WLAN_ADDR_LEN
);
778 pMgmt
->sNodeDBTable
[0].bActive
= true;
779 pMgmt
->sNodeDBTable
[0].bPSEnable
= false;
780 skb_queue_head_init(&pMgmt
->sNodeDBTable
[0].sTxPSQueue
);
781 RATEvParseMaxRate((void *) pDevice
,
782 (PWLAN_IE_SUPP_RATES
) pMgmt
->abyCurrSuppRates
,
783 (PWLAN_IE_SUPP_RATES
) pMgmt
->abyCurrExtSuppRates
,
785 &(pMgmt
->sNodeDBTable
[0].wMaxBasicRate
),
786 &(pMgmt
->sNodeDBTable
[0].wMaxSuppRate
),
787 &(pMgmt
->sNodeDBTable
[0].wSuppRate
),
788 &(pMgmt
->sNodeDBTable
[0].byTopCCKBasicRate
),
789 &(pMgmt
->sNodeDBTable
[0].byTopOFDMBasicRate
));
790 pMgmt
->sNodeDBTable
[0].wTxDataRate
= pMgmt
->sNodeDBTable
[0].wMaxBasicRate
;
791 pMgmt
->sNodeDBTable
[0].uRatePollTimeout
= FALLBACK_POLL_SECOND
;
796 * Routine Description:
799 * Second call back function to update Node DB info & AP link status
805 void BSSvSecondCallBack(struct work_struct
*work
)
807 struct vnt_private
*pDevice
= container_of(work
,
808 struct vnt_private
, second_callback_work
.work
);
809 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
811 PWLAN_IE_SSID pItemSSID
, pCurrSSID
;
812 u32 uSleepySTACnt
= 0;
813 u32 uNonShortSlotSTACnt
= 0;
814 u32 uLongPreambleSTACnt
= 0;
816 if (pDevice
->Flags
& fMP_DISCONNECTED
)
819 pDevice
->uAssocCount
= 0;
821 /* Power Saving Mode Tx Burst */
822 if (pDevice
->bEnablePSMode
== true) {
823 pDevice
->ulPSModeWaitTx
++;
824 if (pDevice
->ulPSModeWaitTx
>= 2) {
825 pDevice
->ulPSModeWaitTx
= 0;
826 pDevice
->bPSModeTxBurst
= false;
830 pDevice
->byERPFlag
&=
831 ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
833 if (pDevice
->wUseProtectCntDown
> 0) {
834 pDevice
->wUseProtectCntDown
--;
836 /* disable protect mode */
837 pDevice
->byERPFlag
&= ~(WLAN_SET_ERP_USE_PROTECTION(1));
840 if (pDevice
->byReAssocCount
> 0) {
841 pDevice
->byReAssocCount
++;
842 if (pDevice
->byReAssocCount
> 10 &&
843 pDevice
->bLinkPass
!= true) { /* 10 sec timeout */
844 printk("Re-association timeout!!!\n");
845 pDevice
->byReAssocCount
= 0;
846 /* if (pDevice->bWPASuppWextEnabled == true) */
848 union iwreq_data wrqu
;
849 memset(&wrqu
, 0, sizeof(wrqu
));
850 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
851 PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
852 wireless_send_event(pDevice
->dev
, SIOCGIWAP
,
855 } else if (pDevice
->bLinkPass
== true) {
856 pDevice
->byReAssocCount
= 0;
860 pMgmt
->eLastState
= pMgmt
->eCurrState
;
862 s_uCalculateLinkQual(pDevice
);
864 for (ii
= 0; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
866 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
867 /* Increase in-activity counter */
868 pMgmt
->sNodeDBTable
[ii
].uInActiveCount
++;
871 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
>
872 MAX_INACTIVE_COUNT
) {
873 BSSvRemoveOneNode(pDevice
, ii
);
874 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
875 "Inactive timeout [%d] sec, STA index = [%d] remove\n",
876 MAX_INACTIVE_COUNT
, ii
);
880 if (pMgmt
->sNodeDBTable
[ii
].eNodeState
>=
883 pDevice
->uAssocCount
++;
885 /* check if Non ERP exist */
886 if (pMgmt
->sNodeDBTable
[ii
].uInActiveCount
<
888 if (!pMgmt
->sNodeDBTable
[ii
].bShortPreamble
) {
889 pDevice
->byERPFlag
|=
890 WLAN_SET_ERP_BARKER_MODE(1);
891 uLongPreambleSTACnt
++;
893 if (!pMgmt
->sNodeDBTable
[ii
].bERPExist
) {
894 pDevice
->byERPFlag
|=
895 WLAN_SET_ERP_NONERP_PRESENT(1);
896 pDevice
->byERPFlag
|=
897 WLAN_SET_ERP_USE_PROTECTION(1);
899 if (!pMgmt
->sNodeDBTable
[ii
].bShortSlotTime
)
900 uNonShortSlotSTACnt
++;
904 /* check if any STA in PS mode */
905 if (pMgmt
->sNodeDBTable
[ii
].bPSEnable
)
910 /* Rate fallback check */
911 if (!pDevice
->bFixRate
) {
913 /* ii = 0 for multicast node (AP & Adhoc) */
914 RATEvTxRateFallBack((void *) pDevice
,
915 &(pMgmt
->sNodeDBTable
[ii
]));
916 } else if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) {
917 /* ii = 0 reserved for unicast AP node (Infra STA) */
918 RATEvTxRateFallBack((void *) pDevice
,
919 &(pMgmt
->sNodeDBTable
[ii
]));
924 /* check if pending PS queue */
925 if (pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
!= 0) {
926 DBG_PRT(MSG_LEVEL_DEBUG
,
927 KERN_INFO
"Index= %d, Queue = %d pending\n",
929 pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
);
931 pMgmt
->sNodeDBTable
[ii
].wEnQueueCnt
> 15) {
932 BSSvRemoveOneNode(pDevice
, ii
);
933 DBG_PRT(MSG_LEVEL_NOTICE
,
934 KERN_INFO
"Pending many queues PS STA Index = %d remove\n",
943 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
&&
944 pDevice
->byBBType
== BB_TYPE_11G
) {
946 /* on/off protect mode */
947 if (WLAN_GET_ERP_USE_PROTECTION(pDevice
->byERPFlag
)) {
948 if (!pDevice
->bProtectMode
) {
949 MACvEnableProtectMD(pDevice
);
950 pDevice
->bProtectMode
= true;
952 } else if (pDevice
->bProtectMode
) {
953 MACvDisableProtectMD(pDevice
);
954 pDevice
->bProtectMode
= false;
956 /* on/off short slot time */
958 if (uNonShortSlotSTACnt
> 0) {
959 if (pDevice
->bShortSlotTime
) {
960 pDevice
->bShortSlotTime
= false;
961 BBvSetShortSlotTime(pDevice
);
962 vUpdateIFS((void *) pDevice
);
964 } else if (!pDevice
->bShortSlotTime
) {
965 pDevice
->bShortSlotTime
= true;
966 BBvSetShortSlotTime(pDevice
);
967 vUpdateIFS((void *) pDevice
);
970 /* on/off barker long preamble mode */
972 if (uLongPreambleSTACnt
> 0) {
973 if (!pDevice
->bBarkerPreambleMd
) {
974 MACvEnableBarkerPreambleMd(pDevice
);
975 pDevice
->bBarkerPreambleMd
= true;
977 } else if (pDevice
->bBarkerPreambleMd
) {
978 MACvDisableBarkerPreambleMd(pDevice
);
979 pDevice
->bBarkerPreambleMd
= false;
984 /* Check if any STA in PS mode, enable DTIM multicast deliver */
985 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
) {
986 if (uSleepySTACnt
> 0)
987 pMgmt
->sNodeDBTable
[0].bPSEnable
= true;
989 pMgmt
->sNodeDBTable
[0].bPSEnable
= false;
992 pItemSSID
= (PWLAN_IE_SSID
) pMgmt
->abyDesireSSID
;
993 pCurrSSID
= (PWLAN_IE_SSID
) pMgmt
->abyCurrSSID
;
995 if (pMgmt
->eCurrMode
== WMAC_MODE_STANDBY
||
996 pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) {
998 if (pMgmt
->sNodeDBTable
[0].bActive
) { /* Assoc with BSS */
1000 s_vCheckSensitivity(pDevice
);
1001 s_vCheckPreEDThreshold(pDevice
);
1003 if (pMgmt
->sNodeDBTable
[0].uInActiveCount
>=
1004 (LOST_BEACON_COUNT
/2) &&
1005 pDevice
->byBBVGACurrent
!= pDevice
->abyBBVGA
[0]) {
1006 pDevice
->byBBVGANew
= pDevice
->abyBBVGA
[0];
1007 bScheduleCommand((void *) pDevice
,
1008 WLAN_CMD_CHANGE_BBSENSITIVITY
,
1012 if (pMgmt
->sNodeDBTable
[0].uInActiveCount
>=
1013 LOST_BEACON_COUNT
) {
1014 pMgmt
->sNodeDBTable
[0].bActive
= false;
1015 pMgmt
->eCurrMode
= WMAC_MODE_STANDBY
;
1016 pMgmt
->eCurrState
= WMAC_STATE_IDLE
;
1017 netif_stop_queue(pDevice
->dev
);
1018 pDevice
->bLinkPass
= false;
1020 vnt_mac_set_led(pDevice
, LEDSTS_STS
,
1023 pDevice
->bRoaming
= true;
1024 pDevice
->bIsRoaming
= false;
1026 DBG_PRT(MSG_LEVEL_NOTICE
,
1027 KERN_INFO
"Lost AP beacon [%d] sec, disconnected !\n",
1028 pMgmt
->sNodeDBTable
[0].uInActiveCount
);
1029 /* let wpa supplicant know AP may disconnect */
1031 union iwreq_data wrqu
;
1032 memset(&wrqu
, 0, sizeof(wrqu
));
1033 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1034 PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
1035 wireless_send_event(pDevice
->dev
,
1041 } else if (pItemSSID
->len
!= 0) {
1043 if ((pDevice
->bEnableRoaming
== true) &&
1044 (!(pMgmt
->Cisco_cckm
))) {
1045 DBG_PRT(MSG_LEVEL_DEBUG
,
1046 KERN_INFO
"bRoaming %d, !\n",
1048 DBG_PRT(MSG_LEVEL_DEBUG
,
1049 KERN_INFO
"bIsRoaming %d, !\n",
1050 pDevice
->bIsRoaming
);
1051 if ((pDevice
->bRoaming
== true) &&
1052 (pDevice
->bIsRoaming
== true)) {
1053 DBG_PRT(MSG_LEVEL_DEBUG
,
1054 KERN_INFO
"Fast Roaming ...\n");
1055 BSSvClearBSSList((void *) pDevice
,
1056 pDevice
->bLinkPass
);
1057 bScheduleCommand((void *) pDevice
,
1058 WLAN_CMD_BSSID_SCAN
,
1059 pMgmt
->abyDesireSSID
);
1060 bScheduleCommand((void *) pDevice
,
1062 pMgmt
->abyDesireSSID
);
1063 pDevice
->uAutoReConnectTime
= 0;
1064 pDevice
->uIsroamingTime
= 0;
1065 pDevice
->bRoaming
= false;
1066 } else if (pDevice
->bRoaming
== false &&
1067 pDevice
->bIsRoaming
== true) {
1068 pDevice
->uIsroamingTime
++;
1069 if (pDevice
->uIsroamingTime
>= 20)
1070 pDevice
->bIsRoaming
= false;
1072 } else if (pDevice
->uAutoReConnectTime
< 10) {
1073 pDevice
->uAutoReConnectTime
++;
1074 /* network manager support need not do Roaming scan??? */
1075 if (pDevice
->bWPASuppWextEnabled
== true)
1076 pDevice
->uAutoReConnectTime
= 0;
1078 /* mike use old encryption status for wpa reauthen */
1079 if (pDevice
->bWPADEVUp
)
1080 pDevice
->eEncryptionStatus
=
1081 pDevice
->eOldEncryptionStatus
;
1083 DBG_PRT(MSG_LEVEL_DEBUG
,
1084 KERN_INFO
"Roaming ...\n");
1085 BSSvClearBSSList((void *) pDevice
,
1086 pDevice
->bLinkPass
);
1087 pMgmt
->eScanType
= WMAC_SCAN_ACTIVE
;
1088 bScheduleCommand((void *) pDevice
,
1089 WLAN_CMD_BSSID_SCAN
,
1090 pMgmt
->abyDesireSSID
);
1091 bScheduleCommand((void *) pDevice
,
1093 pMgmt
->abyDesireSSID
);
1094 pDevice
->uAutoReConnectTime
= 0;
1099 if (pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
) {
1100 /* if adhoc started which essid is NULL string, rescanning. */
1101 if (pMgmt
->eCurrState
== WMAC_STATE_STARTED
&&
1102 pCurrSSID
->len
== 0) {
1103 if (pDevice
->uAutoReConnectTime
< 10) {
1104 pDevice
->uAutoReConnectTime
++;
1106 DBG_PRT(MSG_LEVEL_NOTICE
,
1107 KERN_INFO
"Adhoc re-scanning ...\n");
1108 pMgmt
->eScanType
= WMAC_SCAN_ACTIVE
;
1109 bScheduleCommand((void *) pDevice
,
1110 WLAN_CMD_BSSID_SCAN
, NULL
);
1111 bScheduleCommand((void *) pDevice
,
1112 WLAN_CMD_SSID
, NULL
);
1113 pDevice
->uAutoReConnectTime
= 0;
1116 if (pMgmt
->eCurrState
== WMAC_STATE_JOINTED
) {
1118 s_vCheckSensitivity(pDevice
);
1119 s_vCheckPreEDThreshold(pDevice
);
1121 if (pMgmt
->sNodeDBTable
[0].uInActiveCount
>=
1122 ADHOC_LOST_BEACON_COUNT
) {
1123 DBG_PRT(MSG_LEVEL_NOTICE
,
1124 KERN_INFO
"Lost other STA beacon [%d] sec, started !\n",
1125 pMgmt
->sNodeDBTable
[0].uInActiveCount
);
1126 pMgmt
->sNodeDBTable
[0].uInActiveCount
= 0;
1127 pMgmt
->eCurrState
= WMAC_STATE_STARTED
;
1128 netif_stop_queue(pDevice
->dev
);
1129 pDevice
->bLinkPass
= false;
1130 vnt_mac_set_led(pDevice
, LEDSTS_STS
,
1136 if (pDevice
->bLinkPass
== true) {
1137 if ((pMgmt
->eAuthenMode
< WMAC_AUTH_WPA
||
1138 pDevice
->fWPA_Authened
== true) &&
1139 (++pDevice
->tx_data_time_out
> 40)) {
1140 pDevice
->tx_trigger
= true;
1142 PSbSendNullPacket(pDevice
);
1144 pDevice
->tx_trigger
= false;
1145 pDevice
->tx_data_time_out
= 0;
1148 if (netif_queue_stopped(pDevice
->dev
))
1149 netif_wake_queue(pDevice
->dev
);
1152 schedule_delayed_work(&pDevice
->second_callback_work
, HZ
);
1156 * Routine Description:
1159 * Update Tx attemps, Tx failure counter in Node DB
1165 void BSSvUpdateNodeTxCounter(struct vnt_private
*pDevice
, u8 byTSR
, u8 byPktNO
)
1167 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
1168 struct vnt_tx_pkt_info
*pkt_info
= pDevice
->pkt_info
;
1172 u16 wFallBackRate
= RATE_1M
;
1179 byPktNum
= (byPktNO
& 0x0F) >> 4;
1180 byTxRetry
= (byTSR
& 0xF0) >> 4;
1181 wRate
= (u16
) (byPktNO
& 0xF0) >> 4;
1182 wFIFOCtl
= pkt_info
[byPktNum
].fifo_ctl
;
1183 pbyDestAddr
= pkt_info
[byPktNum
].dest_addr
;
1185 if (wFIFOCtl
& FIFOCTL_AUTO_FB_0
)
1186 byFallBack
= AUTO_FB_0
;
1187 else if (wFIFOCtl
& FIFOCTL_AUTO_FB_1
)
1188 byFallBack
= AUTO_FB_1
;
1190 byFallBack
= AUTO_FB_NONE
;
1192 /* Only Unicast using support rates */
1193 if (wFIFOCtl
& FIFOCTL_NEEDACK
) {
1194 if (pMgmt
->eCurrMode
== WMAC_MODE_ESS_STA
) {
1195 pMgmt
->sNodeDBTable
[0].uTxAttempts
+= 1;
1196 if (!(byTSR
& (TSR_TMO
| TSR_RETRYTMO
))) {
1197 /* transmit success, TxAttempts at least plus one */
1198 pMgmt
->sNodeDBTable
[0].uTxOk
[MAX_RATE
]++;
1199 if ((byFallBack
== AUTO_FB_NONE
) ||
1200 (wRate
< RATE_18M
)) {
1201 wFallBackRate
= wRate
;
1202 } else if (byFallBack
== AUTO_FB_0
) {
1205 awHWRetry0
[wRate
-RATE_18M
][byTxRetry
];
1208 awHWRetry0
[wRate
-RATE_18M
][4];
1209 } else if (byFallBack
== AUTO_FB_1
) {
1212 awHWRetry1
[wRate
-RATE_18M
][byTxRetry
];
1214 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1216 pMgmt
->sNodeDBTable
[0].uTxOk
[wFallBackRate
]++;
1218 pMgmt
->sNodeDBTable
[0].uTxFailures
++;
1220 pMgmt
->sNodeDBTable
[0].uTxRetry
+= byTxRetry
;
1221 if (byTxRetry
!= 0) {
1222 pMgmt
->sNodeDBTable
[0].uTxFail
[MAX_RATE
] += byTxRetry
;
1223 if (byFallBack
== AUTO_FB_NONE
||
1225 pMgmt
->sNodeDBTable
[0].uTxFail
[wRate
] += byTxRetry
;
1226 } else if (byFallBack
== AUTO_FB_0
) {
1227 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1230 awHWRetry0
[wRate
-RATE_18M
][ii
];
1233 awHWRetry0
[wRate
-RATE_18M
][4];
1234 pMgmt
->sNodeDBTable
[0].uTxFail
[wFallBackRate
]++;
1236 } else if (byFallBack
== AUTO_FB_1
) {
1237 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1240 awHWRetry1
[wRate
-RATE_18M
][ii
];
1243 awHWRetry1
[wRate
-RATE_18M
][4];
1244 pMgmt
->sNodeDBTable
[0].uTxFail
[wFallBackRate
]++;
1250 if ((pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
||
1251 pMgmt
->eCurrMode
== WMAC_MODE_ESS_AP
) &&
1252 BSSbIsSTAInNodeDB((void *) pDevice
,
1255 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxAttempts
+= 1;
1256 if (!(byTSR
& (TSR_TMO
| TSR_RETRYTMO
))) {
1257 /* transmit success, TxAttempts at least plus one */
1258 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxOk
[MAX_RATE
]++;
1259 if ((byFallBack
== AUTO_FB_NONE
) ||
1260 (wRate
< RATE_18M
)) {
1261 wFallBackRate
= wRate
;
1262 } else if (byFallBack
== AUTO_FB_0
) {
1265 awHWRetry0
[wRate
-RATE_18M
][byTxRetry
];
1268 awHWRetry0
[wRate
-RATE_18M
][4];
1269 } else if (byFallBack
== AUTO_FB_1
) {
1272 awHWRetry1
[wRate
-RATE_18M
][byTxRetry
];
1275 awHWRetry1
[wRate
-RATE_18M
][4];
1277 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxOk
[wFallBackRate
]++;
1279 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFailures
++;
1281 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxRetry
+= byTxRetry
;
1282 if (byTxRetry
!= 0) {
1283 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[MAX_RATE
] += byTxRetry
;
1284 if ((byFallBack
== AUTO_FB_NONE
) ||
1285 (wRate
< RATE_18M
)) {
1286 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wRate
] += byTxRetry
;
1287 } else if (byFallBack
== AUTO_FB_0
) {
1288 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1291 awHWRetry0
[wRate
-RATE_18M
][ii
];
1294 awHWRetry0
[wRate
-RATE_18M
][4];
1295 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wFallBackRate
]++;
1297 } else if (byFallBack
== AUTO_FB_1
) {
1298 for (ii
= 0; ii
< byTxRetry
; ii
++) {
1300 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][ii
];
1302 wFallBackRate
= awHWRetry1
[wRate
-RATE_18M
][4];
1303 pMgmt
->sNodeDBTable
[uNodeIndex
].uTxFail
[wFallBackRate
]++;
1312 * Routine Description:
1313 * Clear Nodes & skb in DB Table
1318 * hDeviceContext - The adapter context.
1319 * uStartIndex - starting index
1326 void BSSvClearNodeDBTable(struct vnt_private
*pDevice
, u32 uStartIndex
)
1328 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
1329 struct sk_buff
*skb
;
1332 for (ii
= uStartIndex
; ii
< (MAX_NODE_NUM
+ 1); ii
++) {
1333 if (pMgmt
->sNodeDBTable
[ii
].bActive
) {
1334 /* check if sTxPSQueue has been initial */
1335 if (pMgmt
->sNodeDBTable
[ii
].sTxPSQueue
.next
) {
1336 while ((skb
= skb_dequeue(&pMgmt
->sNodeDBTable
[ii
].sTxPSQueue
))) {
1337 DBG_PRT(MSG_LEVEL_DEBUG
,
1338 KERN_INFO
"PS skb != NULL %d\n",
1343 memset(&pMgmt
->sNodeDBTable
[ii
], 0, sizeof(KnownNodeDB
));
1348 static void s_vCheckSensitivity(struct vnt_private
*pDevice
)
1350 PKnownBSS pBSSList
= NULL
;
1351 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
1354 if (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
||
1355 (pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
&&
1356 pMgmt
->eCurrState
== WMAC_STATE_JOINTED
)) {
1357 pBSSList
= BSSpAddrIsInBSSList(pDevice
, pMgmt
->abyCurrBSSID
,
1358 (PWLAN_IE_SSID
) pMgmt
->abyCurrSSID
);
1360 /* Update BB register if RSSI is too strong */
1361 signed long LocalldBmAverage
= 0;
1362 signed long uNumofdBm
= 0;
1363 for (ii
= 0; ii
< RSSI_STAT_COUNT
; ii
++) {
1364 if (pBSSList
->ldBmAverage
[ii
] != 0) {
1366 LocalldBmAverage
+= pBSSList
->ldBmAverage
[ii
];
1369 if (uNumofdBm
> 0) {
1370 LocalldBmAverage
= LocalldBmAverage
/uNumofdBm
;
1371 for (ii
= 0; ii
< BB_VGA_LEVEL
; ii
++) {
1372 DBG_PRT(MSG_LEVEL_DEBUG
,
1373 KERN_INFO
"LocalldBmAverage:%ld, %ld %02x\n",
1375 pDevice
->ldBmThreshold
[ii
],
1376 pDevice
->abyBBVGA
[ii
]);
1377 if (LocalldBmAverage
< pDevice
->ldBmThreshold
[ii
]) {
1378 pDevice
->byBBVGANew
=
1379 pDevice
->abyBBVGA
[ii
];
1383 if (pDevice
->byBBVGANew
!=
1384 pDevice
->byBBVGACurrent
) {
1385 pDevice
->uBBVGADiffCount
++;
1386 if (pDevice
->uBBVGADiffCount
>=
1387 BB_VGA_CHANGE_THRESHOLD
)
1388 bScheduleCommand(pDevice
,
1389 WLAN_CMD_CHANGE_BBSENSITIVITY
,
1392 pDevice
->uBBVGADiffCount
= 0;
1399 static void s_uCalculateLinkQual(struct vnt_private
*pDevice
)
1401 struct net_device_stats
*stats
= &pDevice
->stats
;
1402 unsigned long TxOkRatio
, TxCnt
;
1403 unsigned long RxOkRatio
, RxCnt
;
1404 unsigned long RssiRatio
;
1408 TxCnt
= stats
->tx_packets
+ pDevice
->wstats
.discard
.retries
;
1410 RxCnt
= stats
->rx_packets
+ stats
->rx_frame_errors
;
1412 TxOkRatio
= (TxCnt
< 6) ? 4000:((stats
->tx_packets
* 4000) / TxCnt
);
1414 RxOkRatio
= (RxCnt
< 6) ? 2000 :
1415 ((stats
->rx_packets
* 2000) / RxCnt
);
1417 /* decide link quality */
1418 if (pDevice
->bLinkPass
!= true) {
1419 pDevice
->wstats
.qual
.qual
= 0;
1421 vnt_rf_rssi_to_dbm(pDevice
, (u8
) (pDevice
->uCurrRSSI
), &ldBm
);
1424 else if (-ldBm
> 90)
1427 RssiRatio
= (40-(-ldBm
-50)) * 4000 / 40;
1429 qual
= (RssiRatio
+ TxOkRatio
+ RxOkRatio
) / 100;
1431 pDevice
->wstats
.qual
.qual
= (u8
) qual
;
1433 pDevice
->wstats
.qual
.qual
= 100;
1437 void BSSvClearAnyBSSJoinRecord(struct vnt_private
*pDevice
)
1439 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
1442 for (ii
= 0; ii
< MAX_BSS_NUM
; ii
++)
1443 pMgmt
->sBSSList
[ii
].bSelected
= false;
1448 static void s_vCheckPreEDThreshold(struct vnt_private
*pDevice
)
1450 PKnownBSS pBSSList
= NULL
;
1451 struct vnt_manager
*pMgmt
= &pDevice
->vnt_mgmt
;
1453 if (pMgmt
->eCurrState
== WMAC_STATE_ASSOC
||
1454 (pMgmt
->eCurrMode
== WMAC_MODE_IBSS_STA
&&
1455 pMgmt
->eCurrState
== WMAC_STATE_JOINTED
)) {
1456 pBSSList
= BSSpAddrIsInBSSList(pDevice
,
1457 pMgmt
->abyCurrBSSID
,
1458 (PWLAN_IE_SSID
) pMgmt
->abyCurrSSID
);
1460 pDevice
->byBBPreEDRSSI
=
1461 (u8
) (~(pBSSList
->ldBmAverRange
) + 1);
1462 BBvUpdatePreEDThreshold(pDevice
, false);