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.17-rc3 1022 lines 31 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: wcmd.c 20 * 21 * Purpose: Handles the management command interface functions 22 * 23 * Author: Lyndon Chen 24 * 25 * Date: May 8, 2003 26 * 27 * Functions: 28 * s_vProbeChannel - Active scan channel 29 * s_MgrMakeProbeRequest - Make ProbeRequest packet 30 * CommandTimer - Timer function to handle command 31 * s_bCommandComplete - Command Complete function 32 * bScheduleCommand - Push Command and wait Command Scheduler to do 33 * vCommandTimer- Command call back functions 34 * vCommandTimerWait- Call back timer 35 * bClearBSSID_SCAN- Clear BSSID_SCAN cmd in CMD Queue 36 * 37 * Revision History: 38 * 39 */ 40 41#include "ttype.h" 42#include "tmacro.h" 43#include "device.h" 44#include "mac.h" 45#include "card.h" 46#include "80211hdr.h" 47#include "wcmd.h" 48#include "wmgr.h" 49#include "power.h" 50#include "wctl.h" 51#include "baseband.h" 52#include "rxtx.h" 53#include "rf.h" 54#include "iowpa.h" 55#include "channel.h" 56 57/*--------------------- Static Definitions -------------------------*/ 58 59/*--------------------- Static Classes ----------------------------*/ 60 61/*--------------------- Static Variables --------------------------*/ 62static int msglevel = MSG_LEVEL_INFO; 63/*--------------------- Static Functions --------------------------*/ 64 65static 66void 67s_vProbeChannel( 68 PSDevice pDevice 69); 70 71static 72PSTxMgmtPacket 73s_MgrMakeProbeRequest( 74 PSDevice pDevice, 75 PSMgmtObject pMgmt, 76 unsigned char *pScanBSSID, 77 PWLAN_IE_SSID pSSID, 78 PWLAN_IE_SUPP_RATES pCurrRates, 79 PWLAN_IE_SUPP_RATES pCurrExtSuppRates 80); 81 82static 83bool 84s_bCommandComplete( 85 PSDevice pDevice 86); 87 88/*--------------------- Export Variables --------------------------*/ 89 90/*--------------------- Export Functions --------------------------*/ 91 92/* 93 * Description: 94 * Stop AdHoc beacon during scan process 95 * 96 * Parameters: 97 * In: 98 * pDevice - Pointer to the adapter 99 * Out: 100 * none 101 * 102 * Return Value: none 103 * 104 */ 105static 106void 107vAdHocBeaconStop(PSDevice pDevice) 108{ 109 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 110 bool bStop; 111 112 /* 113 * temporarily stop Beacon packet for AdHoc Server 114 * if all of the following conditions are met: 115 * (1) STA is in AdHoc mode 116 * (2) VT3253 is programmed as automatic Beacon Transmitting 117 * (3) One of the following conditions is met 118 * (3.1) AdHoc channel is in B/G band and the 119 * current scan channel is in A band 120 * or 121 * (3.2) AdHoc channel is in A mode 122 */ 123 bStop = false; 124 if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && 125 (pMgmt->eCurrState >= WMAC_STATE_STARTED)) { 126 if ((pMgmt->uIBSSChannel <= CB_MAX_CHANNEL_24G) && 127 (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) { 128 bStop = true; 129 } 130 if (pMgmt->uIBSSChannel > CB_MAX_CHANNEL_24G) 131 bStop = true; 132 133 } 134 135 if (bStop) 136 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); 137} /* vAdHocBeaconStop */ 138 139/* 140 * Description: 141 * Restart AdHoc beacon after scan process complete 142 * 143 * Parameters: 144 * In: 145 * pDevice - Pointer to the adapter 146 * Out: 147 * none 148 * 149 * Return Value: none 150 * 151 */ 152static 153void 154vAdHocBeaconRestart(PSDevice pDevice) 155{ 156 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 157 158 /* 159 * Restart Beacon packet for AdHoc Server 160 * if all of the following coditions are met: 161 * (1) STA is in AdHoc mode 162 * (2) VT3253 is programmed as automatic Beacon Transmitting 163 */ 164 if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && 165 (pMgmt->eCurrState >= WMAC_STATE_STARTED)) { 166 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); 167 } 168} 169 170/*+ 171 * 172 * Routine Description: 173 * Prepare and send probe request management frames. 174 * 175 * 176 * Return Value: 177 * none. 178 * 179 -*/ 180 181static 182void 183s_vProbeChannel( 184 PSDevice pDevice 185) 186{ 187 //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M 188 unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; 189 unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; 190 //6M, 9M, 12M, 48M 191 unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; 192 unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; 193 unsigned char *pbyRate; 194 PSTxMgmtPacket pTxPacket; 195 PSMgmtObject pMgmt = pDevice->pMgmt; 196 unsigned int ii; 197 198 if (pDevice->eCurrentPHYType == PHY_TYPE_11A) 199 pbyRate = &abyCurrSuppRatesA[0]; 200 else if (pDevice->eCurrentPHYType == PHY_TYPE_11B) 201 pbyRate = &abyCurrSuppRatesB[0]; 202 else 203 pbyRate = &abyCurrSuppRatesG[0]; 204 205 // build an assocreq frame and send it 206 pTxPacket = s_MgrMakeProbeRequest 207 ( 208 pDevice, 209 pMgmt, 210 pMgmt->abyScanBSSID, 211 (PWLAN_IE_SSID)pMgmt->abyScanSSID, 212 (PWLAN_IE_SUPP_RATES)pbyRate, 213 (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG 214 ); 215 216 if (pTxPacket != NULL) { 217 for (ii = 0; ii < 2; ii++) { 218 if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) 219 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail..\n"); 220 else 221 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending..\n"); 222 } 223 } 224} 225 226/*+ 227 * 228 * Routine Description: 229 * Constructs an probe request frame 230 * 231 * 232 * Return Value: 233 * A ptr to Tx frame or NULL on allocation failure 234 * 235 -*/ 236 237static PSTxMgmtPacket 238s_MgrMakeProbeRequest( 239 PSDevice pDevice, 240 PSMgmtObject pMgmt, 241 unsigned char *pScanBSSID, 242 PWLAN_IE_SSID pSSID, 243 PWLAN_IE_SUPP_RATES pCurrRates, 244 PWLAN_IE_SUPP_RATES pCurrExtSuppRates 245 246) 247{ 248 PSTxMgmtPacket pTxPacket = NULL; 249 WLAN_FR_PROBEREQ sFrame; 250 251 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; 252 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBEREQ_FR_MAXLEN); 253 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); 254 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; 255 sFrame.len = WLAN_PROBEREQ_FR_MAXLEN; 256 vMgrEncodeProbeRequest(&sFrame); 257 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( 258 ( 259 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | 260 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ) 261)); 262 memcpy(sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN); 263 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); 264 memcpy(sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN); 265 // Copy the SSID, pSSID->len=0 indicate broadcast SSID 266 sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); 267 sFrame.len += pSSID->len + WLAN_IEHDR_LEN; 268 memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); 269 sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); 270 sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; 271 memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); 272 // Copy the extension rate set 273 if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { 274 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); 275 sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; 276 memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); 277 } 278 pTxPacket->cbMPDULen = sFrame.len; 279 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; 280 281 return pTxPacket; 282} 283 284void 285vCommandTimerWait( 286 void *hDeviceContext, 287 unsigned int MSecond 288) 289{ 290 PSDevice pDevice = (PSDevice)hDeviceContext; 291 292 init_timer(&pDevice->sTimerCommand); 293 pDevice->sTimerCommand.data = (unsigned long) pDevice; 294 pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; 295 // RUN_AT :1 msec ~= (HZ/1024) 296 pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10); 297 add_timer(&pDevice->sTimerCommand); 298} 299 300void 301vCommandTimer( 302 void *hDeviceContext 303) 304{ 305 PSDevice pDevice = (PSDevice)hDeviceContext; 306 PSMgmtObject pMgmt = pDevice->pMgmt; 307 PWLAN_IE_SSID pItemSSID; 308 PWLAN_IE_SSID pItemSSIDCurr; 309 CMD_STATUS Status; 310 unsigned int ii; 311 unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; 312 struct sk_buff *skb; 313 314 if (pDevice->dwDiagRefCount != 0) 315 return; 316 if (!pDevice->bCmdRunning) 317 return; 318 319 spin_lock_irq(&pDevice->lock); 320 321 switch (pDevice->eCommandState) { 322 case WLAN_CMD_SCAN_START: 323 324 pDevice->byReAssocCount = 0; 325 if (pDevice->bRadioOff) { 326 s_bCommandComplete(pDevice); 327 spin_unlock_irq(&pDevice->lock); 328 return; 329 } 330 331 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { 332 s_bCommandComplete(pDevice); 333 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_AP); 334 spin_unlock_irq(&pDevice->lock); 335 return; 336 } 337 338 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_SCAN_START\n"); 339 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID; 340 // wait all Data TD complete 341 if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) { 342 spin_unlock_irq(&pDevice->lock); 343 vCommandTimerWait((void *)pDevice, 10); 344 return; 345 } 346 347 if (pMgmt->uScanChannel == 0) { 348 pMgmt->uScanChannel = pDevice->byMinChannel; 349 // Set Baseband to be more sensitive. 350 351 } 352 if (pMgmt->uScanChannel > pDevice->byMaxChannel) { 353 pMgmt->eScanState = WMAC_NO_SCANNING; 354 355 // Set Baseband's sensitivity back. 356 // Set channel back 357 set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); 358 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel); 359 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) 360 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC); 361 else 362 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_INFRASTRUCTURE); 363 364 vAdHocBeaconRestart(pDevice); 365 s_bCommandComplete(pDevice); 366 367 } else { 368//2008-8-4 <add> by chester 369 if (!is_channel_valid(pMgmt->uScanChannel)) { 370 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d\n", pMgmt->uScanChannel); 371 s_bCommandComplete(pDevice); 372 spin_unlock_irq(&pDevice->lock); 373 return; 374 } 375 if (pMgmt->uScanChannel == pDevice->byMinChannel) { 376 pMgmt->abyScanBSSID[0] = 0xFF; 377 pMgmt->abyScanBSSID[1] = 0xFF; 378 pMgmt->abyScanBSSID[2] = 0xFF; 379 pMgmt->abyScanBSSID[3] = 0xFF; 380 pMgmt->abyScanBSSID[4] = 0xFF; 381 pMgmt->abyScanBSSID[5] = 0xFF; 382 pItemSSID->byElementID = WLAN_EID_SSID; 383 pMgmt->eScanState = WMAC_IS_SCANNING; 384 385 } 386 387 vAdHocBeaconStop(pDevice); 388 389 if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel)) 390 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SCAN Channel: %d\n", pMgmt->uScanChannel); 391 else 392 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SET SCAN Channel Fail: %d\n", pMgmt->uScanChannel); 393 394 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_UNKNOWN); 395 pMgmt->uScanChannel++; 396//2008-8-4 <modify> by chester 397 if (!is_channel_valid(pMgmt->uScanChannel) && 398 pMgmt->uScanChannel <= pDevice->byMaxChannel) { 399 pMgmt->uScanChannel = pDevice->byMaxChannel + 1; 400 pMgmt->eCommandState = WLAN_CMD_SCAN_END; 401 402 } 403 404 if (!pMgmt->b11hEnable || 405 (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) { 406 s_vProbeChannel(pDevice); 407 spin_unlock_irq(&pDevice->lock); 408 vCommandTimerWait((void *)pDevice, WCMD_ACTIVE_SCAN_TIME); 409 return; 410 } else { 411 spin_unlock_irq(&pDevice->lock); 412 vCommandTimerWait((void *)pDevice, WCMD_PASSIVE_SCAN_TIME); 413 return; 414 } 415 416 } 417 418 break; 419 420 case WLAN_CMD_SCAN_END: 421 422 // Set Baseband's sensitivity back. 423 // Set channel back 424 set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); 425 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel); 426 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) 427 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC); 428 else 429 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_INFRASTRUCTURE); 430 431 pMgmt->eScanState = WMAC_NO_SCANNING; 432 vAdHocBeaconRestart(pDevice); 433//2008-0409-07, <Add> by Einsn Liu 434#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT 435 if (pMgmt->eScanType == WMAC_SCAN_PASSIVE) { 436 //send scan event to wpa_Supplicant 437 union iwreq_data wrqu; 438 439 memset(&wrqu, 0, sizeof(wrqu)); 440 wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); 441 } 442#endif 443 s_bCommandComplete(pDevice); 444 break; 445 446 case WLAN_CMD_DISASSOCIATE_START: 447 pDevice->byReAssocCount = 0; 448 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && 449 (pMgmt->eCurrState != WMAC_STATE_ASSOC)) { 450 s_bCommandComplete(pDevice); 451 spin_unlock_irq(&pDevice->lock); 452 return; 453 } else { 454 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Disassociation Packet..\n"); 455 // reason = 8 : disassoc because sta has left 456 vMgrDisassocBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status); 457 pDevice->bLinkPass = false; 458 // unlock command busy 459 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; 460 pItemSSID->len = 0; 461 memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); 462 pMgmt->eCurrState = WMAC_STATE_IDLE; 463 pMgmt->sNodeDBTable[0].bActive = false; 464 } 465 netif_stop_queue(pDevice->dev); 466 pDevice->eCommandState = WLAN_DISASSOCIATE_WAIT; 467 // wait all Control TD complete 468 if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { 469 vCommandTimerWait((void *)pDevice, 10); 470 spin_unlock_irq(&pDevice->lock); 471 return; 472 } 473 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " CARDbRadioPowerOff\n"); 474 //2008-09-02 <mark> by chester 475 s_bCommandComplete(pDevice); 476 break; 477 478 case WLAN_DISASSOCIATE_WAIT: 479 // wait all Control TD complete 480 if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { 481 vCommandTimerWait((void *)pDevice, 10); 482 spin_unlock_irq(&pDevice->lock); 483 return; 484 } 485//2008-09-02 <mark> by chester 486 s_bCommandComplete(pDevice); 487 break; 488 489 case WLAN_CMD_SSID_START: 490 pDevice->byReAssocCount = 0; 491 if (pDevice->bRadioOff) { 492 s_bCommandComplete(pDevice); 493 spin_unlock_irq(&pDevice->lock); 494 return; 495 } 496 pr_debug("chester-abyDesireSSID=%s\n", ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID); 497 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; 498 pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; 499 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " cmd: desire ssid = %s\n", pItemSSID->abySSID); 500 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID); 501 502 if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { 503 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n"); 504 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pItemSSID->len =%d\n", pItemSSID->len); 505 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pItemSSIDCurr->len = %d\n", pItemSSIDCurr->len); 506 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " desire ssid = %s\n", pItemSSID->abySSID); 507 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " curr ssid = %s\n", pItemSSIDCurr->abySSID); 508 } 509 510 if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || 511 ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { 512 if (pItemSSID->len == pItemSSIDCurr->len) { 513 if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) { 514 s_bCommandComplete(pDevice); 515 spin_unlock_irq(&pDevice->lock); 516 return; 517 } 518 } 519 520 netif_stop_queue(pDevice->dev); 521 pDevice->bLinkPass = false; 522 } 523 // set initial state 524 pMgmt->eCurrState = WMAC_STATE_IDLE; 525 pMgmt->eCurrMode = WMAC_MODE_STANDBY; 526 PSvDisablePowerSaving((void *)pDevice); 527 BSSvClearNodeDBTable(pDevice, 0); 528 529 vMgrJoinBSSBegin((void *)pDevice, &Status); 530 // if Infra mode 531 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { 532 // Call mgr to begin the deauthentication 533 // reason = (3) because sta has left ESS 534 if (pMgmt->eCurrState >= WMAC_STATE_AUTH) 535 vMgrDeAuthenBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status); 536 537 // Call mgr to begin the authentication 538 vMgrAuthenBeginSta((void *)pDevice, pMgmt, &Status); 539 if (Status == CMD_STATUS_SUCCESS) { 540 pDevice->byLinkWaitCount = 0; 541 pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT; 542 vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT); 543 spin_unlock_irq(&pDevice->lock); 544 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set eCommandState = WLAN_AUTHENTICATE_WAIT\n"); 545 return; 546 } 547 } 548 // if Adhoc mode 549 else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { 550 if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { 551 if (netif_queue_stopped(pDevice->dev)) 552 netif_wake_queue(pDevice->dev); 553 554 pDevice->bLinkPass = true; 555 556 pMgmt->sNodeDBTable[0].bActive = true; 557 pMgmt->sNodeDBTable[0].uInActiveCount = 0; 558 bClearBSSID_SCAN(pDevice); 559 } else { 560 // start own IBSS 561 vMgrCreateOwnIBSS((void *)pDevice, &Status); 562 if (Status != CMD_STATUS_SUCCESS) 563 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail !\n"); 564 565 BSSvAddMulticastNode(pDevice); 566 } 567 } 568 // if SSID not found 569 else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) { 570 if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA || 571 pMgmt->eConfigMode == WMAC_CONFIG_AUTO) { 572 // start own IBSS 573 vMgrCreateOwnIBSS((void *)pDevice, &Status); 574 if (Status != CMD_STATUS_SUCCESS) 575 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail !\n"); 576 577 BSSvAddMulticastNode(pDevice); 578 if (netif_queue_stopped(pDevice->dev)) 579 netif_wake_queue(pDevice->dev); 580 581 pDevice->bLinkPass = true; 582 } else { 583 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n"); 584#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT 585 { 586 union iwreq_data wrqu; 587 588 memset(&wrqu, 0, sizeof(wrqu)); 589 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 590 pr_debug("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n"); 591 wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); 592 } 593#endif 594 595 } 596 } 597 s_bCommandComplete(pDevice); 598 break; 599 600 case WLAN_AUTHENTICATE_WAIT: 601 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_AUTHENTICATE_WAIT\n"); 602 if (pMgmt->eCurrState == WMAC_STATE_AUTH) { 603 // Call mgr to begin the association 604 pDevice->byLinkWaitCount = 0; 605 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCurrState == WMAC_STATE_AUTH\n"); 606 vMgrAssocBeginSta((void *)pDevice, pMgmt, &Status); 607 if (Status == CMD_STATUS_SUCCESS) { 608 pDevice->byLinkWaitCount = 0; 609 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState = WLAN_ASSOCIATE_WAIT\n"); 610 pDevice->eCommandState = WLAN_ASSOCIATE_WAIT; 611 vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT); 612 spin_unlock_irq(&pDevice->lock); 613 return; 614 } 615 } 616 617 else if (pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) { 618 pr_debug("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n"); 619 } else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if authenticated_frame delay! 620 pDevice->byLinkWaitCount++; 621 pr_debug("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount); 622 spin_unlock_irq(&pDevice->lock); 623 vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT/2); 624 return; 625 } 626 pDevice->byLinkWaitCount = 0; 627 s_bCommandComplete(pDevice); 628 break; 629 630 case WLAN_ASSOCIATE_WAIT: 631 if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { 632 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCurrState == WMAC_STATE_ASSOC\n"); 633 if (pDevice->ePSMode != WMAC_POWER_CAM) 634 PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); 635 636 if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) 637 KeybRemoveAllKey(&(pDevice->sKey), pDevice->abyBSSID, pDevice->PortOffset); 638 639 pDevice->bLinkPass = true; 640 pDevice->byLinkWaitCount = 0; 641 pDevice->byReAssocCount = 0; 642 bClearBSSID_SCAN(pDevice); 643 if (pDevice->byFOETuning) { 644 BBvSetFOE(pDevice->PortOffset); 645 PSbSendNullPacket(pDevice); 646 } 647 if (netif_queue_stopped(pDevice->dev)) 648 netif_wake_queue(pDevice->dev); 649 650#ifdef TxInSleep 651 if (pDevice->IsTxDataTrigger) { //TxDataTimer is not triggered at the first time 652 del_timer(&pDevice->sTimerTxData); 653 init_timer(&pDevice->sTimerTxData); 654 pDevice->sTimerTxData.data = (unsigned long) pDevice; 655 pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; 656 pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback 657 pDevice->fTxDataInSleep = false; 658 pDevice->nTxDataTimeCout = 0; 659 } 660 661 pDevice->IsTxDataTrigger = true; 662 add_timer(&pDevice->sTimerTxData); 663#endif 664 } else if (pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) { 665 printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n"); 666 } else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if associated_frame delay! 667 pDevice->byLinkWaitCount++; 668 pr_debug("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount); 669 spin_unlock_irq(&pDevice->lock); 670 vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT/2); 671 return; 672 } 673 pDevice->byLinkWaitCount = 0; 674 675 s_bCommandComplete(pDevice); 676 break; 677 678 case WLAN_CMD_AP_MODE_START: 679 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_AP_MODE_START\n"); 680 681 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { 682 del_timer(&pMgmt->sTimerSecondCallback); 683 pMgmt->eCurrState = WMAC_STATE_IDLE; 684 pMgmt->eCurrMode = WMAC_MODE_STANDBY; 685 pDevice->bLinkPass = false; 686 if (pDevice->bEnableHostWEP) 687 BSSvClearNodeDBTable(pDevice, 1); 688 else 689 BSSvClearNodeDBTable(pDevice, 0); 690 pDevice->uAssocCount = 0; 691 pMgmt->eCurrState = WMAC_STATE_IDLE; 692 pDevice->bFixRate = false; 693 694 vMgrCreateOwnIBSS((void *)pDevice, &Status); 695 if (Status != CMD_STATUS_SUCCESS) 696 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail !\n"); 697 698 // alway turn off unicast bit 699 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST); 700 pDevice->byRxMode &= ~RCR_UNICAST; 701 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode); 702 BSSvAddMulticastNode(pDevice); 703 if (netif_queue_stopped(pDevice->dev)) 704 netif_wake_queue(pDevice->dev); 705 706 pDevice->bLinkPass = true; 707 add_timer(&pMgmt->sTimerSecondCallback); 708 } 709 s_bCommandComplete(pDevice); 710 break; 711 712 case WLAN_CMD_TX_PSPACKET_START: 713 // DTIM Multicast tx 714 if (pMgmt->sNodeDBTable[0].bRxPSPoll) { 715 while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) { 716 if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) { 717 pMgmt->abyPSTxMap[0] &= ~byMask[0]; 718 pDevice->bMoreData = false; 719 } else { 720 pDevice->bMoreData = true; 721 } 722 if (!device_dma0_xmit(pDevice, skb, 0)) 723 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail\n"); 724 725 pMgmt->sNodeDBTable[0].wEnQueueCnt--; 726 } 727 } 728 729 // PS nodes tx 730 for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { 731 if (pMgmt->sNodeDBTable[ii].bActive && 732 pMgmt->sNodeDBTable[ii].bRxPSPoll) { 733 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n", 734 ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt); 735 while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { 736 if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { 737 // clear tx map 738 pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= 739 ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; 740 pDevice->bMoreData = false; 741 } else { 742 pDevice->bMoreData = true; 743 } 744 if (!device_dma0_xmit(pDevice, skb, ii)) 745 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail\n"); 746 747 pMgmt->sNodeDBTable[ii].wEnQueueCnt--; 748 // check if sta ps enabled, and wait next pspoll. 749 // if sta ps disable, then send all pending buffers. 750 if (pMgmt->sNodeDBTable[ii].bPSEnable) 751 break; 752 } 753 if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { 754 // clear tx map 755 pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= 756 ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; 757 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear\n", ii); 758 } 759 pMgmt->sNodeDBTable[ii].bRxPSPoll = false; 760 } 761 } 762 763 s_bCommandComplete(pDevice); 764 break; 765 766 case WLAN_CMD_RADIO_START: 767 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_RADIO_START\n"); 768 if (pDevice->bRadioCmd) 769 CARDbRadioPowerOn(pDevice); 770 else 771 CARDbRadioPowerOff(pDevice); 772 773 s_bCommandComplete(pDevice); 774 break; 775 776 case WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE: 777 // wait all TD complete 778 if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) { 779 vCommandTimerWait((void *)pDevice, 10); 780 spin_unlock_irq(&pDevice->lock); 781 return; 782 } 783 if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { 784 vCommandTimerWait((void *)pDevice, 10); 785 spin_unlock_irq(&pDevice->lock); 786 return; 787 } 788 pDevice->byBBVGACurrent = pDevice->byBBVGANew; 789 BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); 790 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent); 791 s_bCommandComplete(pDevice); 792 break; 793 794 default: 795 s_bCommandComplete(pDevice); 796 break; 797 798 } //switch 799 spin_unlock_irq(&pDevice->lock); 800} 801 802static 803bool 804s_bCommandComplete( 805 PSDevice pDevice 806) 807{ 808 PWLAN_IE_SSID pSSID; 809 bool bRadioCmd = false; 810 bool bForceSCAN = true; 811 PSMgmtObject pMgmt = pDevice->pMgmt; 812 813 pDevice->eCommandState = WLAN_CMD_IDLE; 814 if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) { 815 //Command Queue Empty 816 pDevice->bCmdRunning = false; 817 return true; 818 } else { 819 pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd; 820 pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID; 821 bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd; 822 bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN; 823 ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE); 824 pDevice->cbFreeCmdQueue++; 825 pDevice->bCmdRunning = true; 826 switch (pDevice->eCommand) { 827 case WLAN_CMD_BSSID_SCAN: 828 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_BSSID_SCAN\n"); 829 pDevice->eCommandState = WLAN_CMD_SCAN_START; 830 pMgmt->uScanChannel = 0; 831 if (pSSID->len != 0) 832 memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 833 else 834 memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 835 836 break; 837 case WLAN_CMD_SSID: 838 pDevice->eCommandState = WLAN_CMD_SSID_START; 839 if (pSSID->len > WLAN_SSID_MAXLEN) 840 pSSID->len = WLAN_SSID_MAXLEN; 841 if (pSSID->len != 0) 842 memcpy(pDevice->pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 843 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_SSID_START\n"); 844 break; 845 case WLAN_CMD_DISASSOCIATE: 846 pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START; 847 break; 848 case WLAN_CMD_RX_PSPOLL: 849 pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START; 850 break; 851 case WLAN_CMD_RUN_AP: 852 pDevice->eCommandState = WLAN_CMD_AP_MODE_START; 853 break; 854 case WLAN_CMD_RADIO: 855 pDevice->eCommandState = WLAN_CMD_RADIO_START; 856 pDevice->bRadioCmd = bRadioCmd; 857 break; 858 case WLAN_CMD_CHANGE_BBSENSITIVITY: 859 pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE; 860 break; 861 862 default: 863 break; 864 865 } 866 867 vCommandTimerWait((void *)pDevice, 0); 868 } 869 870 return true; 871} 872 873bool bScheduleCommand( 874 void *hDeviceContext, 875 CMD_CODE eCommand, 876 unsigned char *pbyItem0 877) 878{ 879 PSDevice pDevice = (PSDevice)hDeviceContext; 880 881 if (pDevice->cbFreeCmdQueue == 0) 882 return false; 883 884 pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand; 885 pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true; 886 memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 887 888 if (pbyItem0 != NULL) { 889 switch (eCommand) { 890 case WLAN_CMD_BSSID_SCAN: 891 memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 892 pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 893 pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false; 894 break; 895 896 case WLAN_CMD_SSID: 897 memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 898 pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 899 break; 900 901 case WLAN_CMD_DISASSOCIATE: 902 pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0); 903 break; 904 905 case WLAN_CMD_RX_PSPOLL: 906 break; 907 908 case WLAN_CMD_RADIO: 909 pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0); 910 break; 911 912 case WLAN_CMD_CHANGE_BBSENSITIVITY: 913 pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE; 914 break; 915 916 default: 917 break; 918 } 919 } 920 921 ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE); 922 pDevice->cbFreeCmdQueue--; 923 924 if (!pDevice->bCmdRunning) 925 s_bCommandComplete(pDevice); 926 927 return true; 928} 929 930/* 931 * Description: 932 * Clear BSSID_SCAN cmd in CMD Queue 933 * 934 * Parameters: 935 * In: 936 * hDeviceContext - Pointer to the adapter 937 * eCommand - Command 938 * Out: 939 * none 940 * 941 * Return Value: true if success; otherwise false 942 * 943 */ 944bool bClearBSSID_SCAN( 945 void *hDeviceContext 946) 947{ 948 PSDevice pDevice = (PSDevice)hDeviceContext; 949 unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx; 950 unsigned int ii; 951 952 if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) { 953 for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii++) { 954 if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN) 955 pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE; 956 ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE); 957 if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx) 958 break; 959 } 960 } 961 return true; 962} 963 964//mike add:reset command timer 965void 966vResetCommandTimer( 967 void *hDeviceContext 968) 969{ 970 PSDevice pDevice = (PSDevice)hDeviceContext; 971 972 //delete timer 973 del_timer(&pDevice->sTimerCommand); 974 //init timer 975 init_timer(&pDevice->sTimerCommand); 976 pDevice->sTimerCommand.data = (unsigned long) pDevice; 977 pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; 978 pDevice->sTimerCommand.expires = RUN_AT(HZ); 979 pDevice->cbFreeCmdQueue = CMD_Q_SIZE; 980 pDevice->uCmdDequeueIdx = 0; 981 pDevice->uCmdEnqueueIdx = 0; 982 pDevice->eCommandState = WLAN_CMD_IDLE; 983 pDevice->bCmdRunning = false; 984 pDevice->bCmdClear = false; 985} 986 987#ifdef TxInSleep 988void 989BSSvSecondTxData( 990 void *hDeviceContext 991) 992{ 993 PSDevice pDevice = (PSDevice)hDeviceContext; 994 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 995 996 pDevice->nTxDataTimeCout++; 997 998 if (pDevice->nTxDataTimeCout < 4) //don't tx data if timer less than 40s 999 { 1000 pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback 1001 add_timer(&pDevice->sTimerTxData); 1002 return; 1003 } 1004 1005 spin_lock_irq(&pDevice->lock); 1006#if 1 1007 if ((pDevice->bLinkPass && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) || //open && sharekey linking 1008 pDevice->fWPA_Authened) { //wpa linking 1009#else 1010 if (pDevice->bLinkPass == true) { 1011#endif 1012 pDevice->fTxDataInSleep = true; 1013 PSbSendNullPacket(pDevice); //send null packet 1014 pDevice->fTxDataInSleep = false; 1015 } 1016 spin_unlock_irq(&pDevice->lock); 1017 1018 pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback 1019 add_timer(&pDevice->sTimerTxData); 1020 return; 1021 } 1022#endif