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