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