Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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