1 /* 2 * ScanSrv.c 3 * 4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /** \file ScanSrv.c 35 * \brief This file include the scan SRV module implementation 36 * 37 * \see ScanSrv.h, ScanSrvSm.h, ScanSrvSm.c 38 */ 39 40 41 #define __FILE_ID__ FILE_ID_115 42 #include "report.h" 43 #include "timer.h" 44 #include "ScanSrv.h" 45 #include "ScanSrvSM.h" 46 #include "MacServices.h" 47 #include "MacServices_api.h" 48 #include "eventMbox_api.h" 49 #include "CmdBld.h" 50 51 /** 52 * \\n 53 * \date 16-Oct-2004\n 54 * \brief Creates the scan SRV object 55 * 56 * Function Scope \e Public.\n 57 * \param hOS - handle to the OS object.\n 58 * \return a handle to the scan SRV object, NULL if an error occurred.\n 59 */ 60 TI_HANDLE MacServices_scanSRV_create( TI_HANDLE hOS ) 61 { 62 /* allocate the scan SRV object */ 63 scanSRV_t *pScanSRV = os_memoryAlloc( hOS, sizeof(scanSRV_t)); 64 if ( NULL == pScanSRV ) 65 { 66 WLAN_OS_REPORT( ("ERROR: Failed to create scan SRV module")); 67 return NULL; 68 } 69 70 os_memoryZero( pScanSRV->hOS, pScanSRV, sizeof(scanSRV_t)); 71 72 /* allocate the state machine */ 73 if ( TI_OK != fsm_Create( hOS, &(pScanSRV->SM), SCAN_SRV_NUM_OF_STATES, SCAN_SRV_NUM_OF_EVENTS )) 74 { 75 WLAN_OS_REPORT( ("ERROR: Failed to allocate scan SRV state machine")); 76 os_memoryFree( hOS, pScanSRV, sizeof(scanSRV_t)); 77 return NULL; 78 } 79 80 /* store the OS handle */ 81 pScanSRV->hOS = hOS; 82 83 return pScanSRV; 84 } 85 86 /** 87 * \\n 88 * \date 29-Dec-2004\n 89 * \brief Finalizes the scan SRV module (releasing memory and timer) 90 * 91 * Function Scope \e Public.\n 92 * \param hScanSRV - handle to the scan SRV object.\n 93 */ 94 void MacServices_scanSRV_destroy( TI_HANDLE hScanSRV ) 95 { 96 scanSRV_t *pScanSRV = (scanSRV_t*)hScanSRV; 97 98 /* free timer */ 99 if (pScanSRV->hScanSrvTimer) 100 { 101 tmr_DestroyTimer (pScanSRV->hScanSrvTimer); 102 } 103 104 /* free memory */ 105 fsm_Unload( pScanSRV->hOS, pScanSRV->SM ); 106 os_memoryFree( pScanSRV->hOS, (TI_HANDLE)pScanSRV , sizeof(scanSRV_t)); 107 } 108 109 /** 110 * \\n 111 * \date 29-Dec-2004\n 112 * \brief Initializes the scan SRV module, registers SCAN_COMPLETE to HAL. 113 * 114 * Function Scope \e Public.\n 115 * \param hScanSRV - handle to the scan SRV object.\n 116 * \param Handles of other modules.\n 117 */ 118 TI_STATUS MacServices_scanSRV_init (TI_HANDLE hMacServices, 119 TI_HANDLE hReport, 120 TI_HANDLE hTWD, 121 TI_HANDLE hTimer, 122 TI_HANDLE hEventMbox, 123 TI_HANDLE hCmdBld) 124 { 125 MacServices_t* pMacServices = (MacServices_t*)hMacServices; 126 scanSRV_t *pScanSRV = pMacServices->hScanSRV; 127 128 /* store handles */ 129 pScanSRV->hTWD = hTWD; 130 pScanSRV->hTimer = hTimer; 131 pScanSRV->hReport = hReport; 132 pScanSRV->hEventMbox = hEventMbox; 133 pScanSRV->hPowerSrv = pMacServices->hPowerSrv; 134 pScanSRV->hCmdBld = hCmdBld; 135 pScanSRV->commandResponseFunc = NULL; 136 pScanSRV->commandResponseObj = NULL; 137 138 /* create the timer */ 139 pScanSRV->hScanSrvTimer = tmr_CreateTimer (pScanSRV->hTimer); 140 if (pScanSRV->hScanSrvTimer == NULL) 141 { 142 TRACE0(pScanSRV->hReport, REPORT_SEVERITY_ERROR, "MacServices_scanSRV_init(): Failed to create hScanSrvTimer!\n"); 143 return TI_NOK; 144 } 145 146 /* init state machine */ 147 scanSRVSM_init ((TI_HANDLE)pScanSRV); 148 149 /* Register our scan complete handler to the HAL events mailbox */ 150 eventMbox_RegisterEvent (pScanSRV->hEventMbox, 151 TWD_OWN_EVENT_SCAN_CMPLT, 152 (void *)MacServices_scanSRV_scanCompleteCB, 153 (TI_HANDLE)pScanSRV); 154 eventMbox_RegisterEvent (pScanSRV->hEventMbox, 155 TWD_OWN_EVENT_SPS_SCAN_CMPLT, 156 (void *)MacServices_scanSRV_scanCompleteCB, 157 (TI_HANDLE)pScanSRV); 158 159 /* init other stuff */ 160 pScanSRV->currentNumberOfConsecutiveNoScanCompleteEvents = 0; 161 162 TRACE0( hReport, REPORT_SEVERITY_INIT, ".....Scan SRV configured successfully.\n"); 163 164 return TI_OK; 165 } 166 167 /** 168 * \brief Restart the scan SRV module upon recovery. 169 * 170 * Function Scope \e Public.\n 171 * \param hScanSRV - handle to the scan SRV object.\n 172 */ 173 void scanSRV_restart (TI_HANDLE hScanSRV) 174 { 175 scanSRV_t *pScanSRV = (scanSRV_t *)hScanSRV; 176 /* init state machine */ 177 /* initialize current state */ 178 pScanSRV->SMState = SCAN_SRV_STATE_IDLE; 179 180 if (pScanSRV->bTimerRunning) 181 { 182 tmr_StopTimer (pScanSRV->hScanSrvTimer); 183 pScanSRV->bTimerRunning = TI_FALSE; 184 } 185 } 186 187 /** 188 * \\n 189 * \date 26-July-2006\n 190 * \brief Configures the scan SRV module with initialization values 191 * 192 * Function Scope \e Public.\n 193 * \param hScanSRV - handle to the scan SRV object.\n 194 * \param hReport - handle to the report object.\n 195 * \param hTWD - handle to the HAL ctrl object.\n 196 */ 197 void MacServices_scanSrv_config( TI_HANDLE hMacServices, TScanSrvInitParams* pInitParams ) 198 { 199 MacServices_t* pMacServices = (MacServices_t*)hMacServices; 200 scanSRV_t *pScanSRV = pMacServices->hScanSRV; 201 202 pScanSRV->numberOfNoScanCompleteToRecovery = pInitParams->numberOfNoScanCompleteToRecovery; 203 204 /* Set Triggered scan time out per channel */ 205 pScanSRV->uTriggeredScanTimeOut = pInitParams->uTriggeredScanTimeOut; 206 TWD_CmdSetSplitScanTimeOut (pScanSRV->hTWD, pScanSRV->uTriggeredScanTimeOut); 207 } 208 209 /** 210 * \\n 211 * \date 29-Dec-2004\n 212 * \brief Registers a complete callback for scan complete notifications. 213 * 214 * Function Scope \e Public.\n 215 * \param hMacServices - handle to the MacServices object.\n 216 * \param scanCompleteCB - the complete callback function.\n 217 * \param hScanCompleteObj - handle to the object passed to the scan complete callback function.\n 218 */ 219 void MacServices_scanSRV_registerScanCompleteCB( TI_HANDLE hMacServices, 220 TScanSrvCompleteCb scanCompleteCB, TI_HANDLE hScanCompleteObj ) 221 { 222 scanSRV_t *pScanSRV = (scanSRV_t*)((MacServices_t*)hMacServices)->hScanSRV; 223 224 pScanSRV->scanCompleteNotificationFunc = scanCompleteCB; 225 pScanSRV->scanCompleteNotificationObj = hScanCompleteObj; 226 } 227 228 /** 229 * \brief Registers a failure event callback for scan error notifications. 230 * 231 * Function Scope \e member.\n 232 * \param hScanSRV - handle to the Scan SRV object.\n 233 * \param failureEventCB - the failure event callback function.\n 234 * \param hFailureEventObj - handle to the object passed to the failure event callback function.\n 235 */ 236 void scanSRV_registerFailureEventCB( TI_HANDLE hScanSRV, 237 void * failureEventCB, TI_HANDLE hFailureEventObj ) 238 { 239 scanSRV_t *pScanSRV = (scanSRV_t*)(hScanSRV); 240 241 pScanSRV->failureEventFunc = (TFailureEventCb)failureEventCB; 242 pScanSRV->failureEventObj = hFailureEventObj; 243 } 244 245 /** 246 * \\n 247 * \date 27-Sep-2005\n 248 * \brief This function is the CB which is called as response to 'StartScan' or 'StopScan' \n. 249 * here we check if there is a GWSI command response , and call it if necessary .\n 250 * Function Scope \e Private.\n 251 * \param hScanSrv - handle to the scan SRV object.\n 252 * \param MboxStatus - mailbox status. \n 253 */ 254 void MacServices_scanSRVCommandMailBoxCB(TI_HANDLE hScanSrv,TI_UINT16 MboxStatus) 255 { 256 scanSRV_t* pScanSRV = (scanSRV_t*)hScanSrv; 257 TI_UINT16 responseStatus; 258 TCmdResponseCb CB_Func; 259 TI_HANDLE CB_Handle; 260 261 TRACE1( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, " status %u\n",MboxStatus); 262 263 /* set response to TI_OK or TI_NOK */ 264 responseStatus = ((MboxStatus > 0) ? TI_NOK : TI_OK); 265 266 /* if we have a Response Function (only in GWSI) we set it back to NULL and then 267 we call it */ 268 if (pScanSRV->commandResponseFunc != NULL) 269 { 270 CB_Func = pScanSRV->commandResponseFunc; 271 CB_Handle = pScanSRV->commandResponseObj; 272 273 pScanSRV->commandResponseFunc = NULL; 274 pScanSRV->commandResponseObj = NULL; 275 276 CB_Func(CB_Handle, responseStatus); 277 } 278 /* if scan request failed */ 279 if ( TI_OK != responseStatus ) 280 { 281 TRACE0( pScanSRV->hReport, REPORT_SEVERITY_ERROR, "Mail box returned error , quitting scan.\n"); 282 283 /* send a scan complete event. This will do all necessary clean-up (timer, power manager, notifying scan complete) */ 284 scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_SCAN_COMPLETE ); 285 } 286 } 287 288 /** 289 * \\n 290 * \date 29-Dec-2004\n 291 * \brief Performs a scan 292 * 293 * Function Scope \e Public.\n 294 * \param hMacServices - handle to the MacServices object.\n 295 * \param scanParams - the scan specific parameters.\n 296 * \param eScanresultTag - tag used for result and scan complete tracking 297 * \param bHighPriority - whether to perform a high priority (overlaps DTIM) scan.\n 298 * \param bDriverMode - whether to try to enter driver mode (with PS on) before issuing the scan command.\n 299 * \param bScanOnDriverModeError - whether to proceed with the scan if requested to enter driver mode and failed.\n 300 * \param psRequest - Parameter sent to PowerSaveServer on PS request to indicate PS on or "keep current" 301 * \param bSendNullData - whether to send Null data when exiting driver mode on scan complete.\n 302 * \param commandResponseFunc - CB function which called after downloading the command. \n 303 * \param commandResponseObj - The CB function Obj (Notice : last 2 params are NULL in Legacy run). \n 304 * \param psRequest - Parameter sent to PowerSaveServer on PS request to indicate PS on or "keep current" 305 * \return TI_OK if successful (various, TBD codes if not).\n 306 */ 307 TI_STATUS MacServices_scanSRV_scan( TI_HANDLE hMacServices, TScanParams *scanParams, EScanResultTag eScanTag, 308 TI_BOOL bHighPriority, TI_BOOL bDriverMode, TI_BOOL bScanOnDriverModeError, 309 E80211PsMode psRequest, TI_BOOL bSendNullData, 310 TCmdResponseCb commandResponseFunc, TI_HANDLE commandResponseObj) 311 { 312 scanSRV_t *pScanSRV = (scanSRV_t*)((MacServices_t*)hMacServices)->hScanSRV; 313 314 315 TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "Scan request received.\n"); 316 317 /* sanity check - scan can only start if the scan SRV is idle */ 318 if ( SCAN_SRV_STATE_IDLE != pScanSRV->SMState ) 319 { 320 TRACE0( pScanSRV->hReport, REPORT_SEVERITY_WARNING, "Scan request while scan is running!\n"); 321 return TI_NOK; 322 } 323 324 /* Response function for GWSI only. In Legacy run we get NULL and never use it. */ 325 pScanSRV->commandResponseFunc = commandResponseFunc; 326 pScanSRV->commandResponseObj = commandResponseObj; 327 328 pScanSRV->bInRequest = TI_TRUE; 329 pScanSRV->returnStatus = TI_OK; 330 331 /* copy scan paramaters */ 332 pScanSRV->scanParams = scanParams; 333 pScanSRV->eScanTag = eScanTag; 334 pScanSRV->uResultCount = 0; 335 pScanSRV->bHighPriority = bHighPriority; 336 pScanSRV->bScanOnDriverModeFailure = bScanOnDriverModeError; 337 pScanSRV->bSendNullData = bSendNullData; 338 pScanSRV->psRequest = psRequest; 339 340 if ( SCAN_TYPE_SPS == scanParams->scanType ) 341 { 342 pScanSRV->bSPSScan = TI_TRUE; 343 344 } 345 else 346 { 347 pScanSRV->bSPSScan = TI_FALSE; 348 } 349 350 351 /* check whether the scan will overlap DTIM frame */ 352 if ( (TI_FALSE == bHighPriority) && (TI_TRUE == bDriverMode)) 353 { 354 pScanSRV->bDtimOverlapping = TI_FALSE; 355 } 356 else 357 { 358 pScanSRV->bDtimOverlapping = TI_TRUE; 359 } 360 361 /* mark the no scan complete flag. The purpose of this flag is to be able to identify 362 whether the scan complete is a normal process, or was it generated because a no scan ocmplete 363 was identified, a stop scan command was snet to the FW, and thus a scan complete was received. 364 In the former case we nullify the consecutive no scan complete counter, whereas in the latter 365 we do not. */ 366 pScanSRV->bNoScanCompleteFlag = TI_FALSE; 367 368 /* if required to enter driver mode */ 369 if ( TI_TRUE == bDriverMode ) 370 { 371 pScanSRV->bExitFromDriverMode = TI_TRUE; 372 /* send a PS_REQUEST event */ 373 scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&(pScanSRV->SMState), SCAN_SRV_EVENT_REQUEST_PS ); 374 } 375 /* no driver mode required */ 376 else 377 { 378 pScanSRV->bExitFromDriverMode = TI_FALSE; 379 /* send a PS_SUCCESS event - will start the scan */ 380 scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS ); 381 } 382 383 pScanSRV->bInRequest = TI_FALSE; 384 385 return pScanSRV->returnStatus; 386 } 387 388 /** 389 * \\n 390 * \date 29-Dec-2004\n 391 * \brief Sends a Stop Scan command to FW, no matter if we are in scan progress or not 392 * 393 * Function Scope \e Public.\n 394 * \param hMacServices - handle to the MacServices object.\n 395 * \param eScanTag - scan tag, used for scan complete and result tracking 396 * \param bSendNullData - indicates whether to send Null data when exiting driver mode.\n 397 * \param commandResponseFunc - CB function which called after downloading the command. \n 398 * \param commandResponseObj - The CB function Obj (Notice : last 2 params are NULL in Legacy run). \n 399 * \return TI_OK if successful (various, TBD codes if not).\n 400 */ 401 TI_STATUS MacServices_scanSRV_stopScan( TI_HANDLE hMacServices, EScanResultTag eScanTag, TI_BOOL bSendNullData, 402 TCmdResponseCb ScanCommandResponseCB, TI_HANDLE CB_handle ) 403 { 404 scanSRV_t *pScanSRV = (scanSRV_t*)((MacServices_t*)hMacServices)->hScanSRV; 405 TI_INT32 stopScanStatus; 406 407 TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "Stop scan request received.\n"); 408 409 /* update the driver mode exit flag */ 410 pScanSRV->bSendNullData = bSendNullData; 411 412 if ( TI_TRUE == pScanSRV->bSPSScan ) 413 { 414 stopScanStatus = cmdBld_CmdStopSPSScan (pScanSRV->hCmdBld, eScanTag, (void *)ScanCommandResponseCB, CB_handle); 415 } 416 else 417 { 418 stopScanStatus = cmdBld_CmdStopScan (pScanSRV->hCmdBld, eScanTag, (void *)ScanCommandResponseCB, CB_handle); 419 } 420 421 if (TI_OK != stopScanStatus) 422 { 423 return TI_NOK; 424 } 425 426 /* send a stop scan event */ 427 scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_STOP_SCAN ); 428 429 return pScanSRV->returnStatus; 430 } 431 432 /** 433 * \\n 434 * \date 17-Jan-2005\n 435 * \brief Notifies the scan SRV of a FW reset (that had originally been reported by a different module).\n 436 * 437 * Function Scope \e Public.\n 438 * \param hMacServices - handle to the MacServices object.\n 439 * \return TI_OK if successful (various, TBD codes if not).\n 440 */ 441 TI_STATUS MacServices_scanSRV_stopOnFWReset( TI_HANDLE hMacServices ) 442 { 443 scanSRV_t *pScanSRV = (scanSRV_t*)((MacServices_t*)hMacServices)->hScanSRV; 444 445 TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "FW reset notification received.\n"); 446 447 /* mark the return status */ 448 pScanSRV->returnStatus = TI_NOK; 449 450 /* send a FW reset event */ 451 return scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_FW_RESET ); 452 } 453 454 /** 455 * \\n 456 * \date 29-Dec-2004\n 457 * \brief callback function used by the power server to notify driver mode result 458 * this CB is used in requesting PS and exiting PS. 459 * Function Scope \e Public.\n 460 * \param hScanSRV - handle to the scan SRV object.\n 461 * \param psStatus - the power save request status.\n 462 */ 463 void MacServices_scanSRV_powerSaveCB( TI_HANDLE hScanSRV, TI_UINT8 PSMode,TI_UINT8 psStatus ) 464 { 465 scanSRV_t *pScanSRV = (scanSRV_t*)hScanSRV; 466 467 TRACE1( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "PS Call Back status %d .\n",psStatus); 468 469 /* if driver mode enter/exit succeedded */ 470 if ( (ENTER_POWER_SAVE_SUCCESS == psStatus) || (EXIT_POWER_SAVE_SUCCESS == psStatus)) 471 { 472 TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "PS successful.\n"); 473 474 /* send a PS_SUCCESS event */ 475 scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS ); 476 } 477 /* driver mode entry failed, and scan is requested even on PS failure but we are entering PS and not Exiting */ 478 else if ( (TI_TRUE == pScanSRV->bScanOnDriverModeFailure) && ( ENTER_POWER_SAVE_FAIL == psStatus)) 479 { 480 TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "PS enter failed, continune scan .\n"); 481 482 /* send a PS_SUCCESS event */ 483 scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS ); 484 } 485 /* driver mode enter or exit failed */ 486 else 487 { 488 /* if we are trying to enter PS and fail to do so - return error on scan complete */ 489 if ( ENTER_POWER_SAVE_FAIL == psStatus) 490 { 491 TRACE0( pScanSRV->hReport, REPORT_SEVERITY_WARNING, "PS enter failed . quiting scan .\n"); 492 /* Set the return status */ 493 pScanSRV->returnStatus = TI_NOK; 494 } 495 496 /* send a PS FAIL event */ 497 scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_FAIL ); 498 } 499 } 500 501 502 /** 503 * \\n 504 * \date 29-Dec-2004\n 505 * \brief Callback function used by the HAL ctrl to notify scan complete 506 * 507 * Function Scope \e Public.\n 508 * \param hScanSRV - handle to the scan SRV object.\n 509 * \param str - pointer to scan result buffer (holding SPS status for SPS scan only!).\n 510 * \param strLen - scan result buffer length (should ALWAYS be 2, even for non SPS scans).\n 511 */ 512 void MacServices_scanSRV_scanCompleteCB( TI_HANDLE hScanSRV, char* str, TI_UINT32 strLen ) 513 { 514 scanSRV_t *pScanSRV = (scanSRV_t*)hScanSRV; 515 scanCompleteResults_t *pResult = (scanCompleteResults_t*)str; 516 517 TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "Scan complete notification from TNET.\n"); 518 519 /* nullify the consecutive no scan complete events counter - only if this is a scan complete that 520 does not happen afetr a stop scan (due to a timer expiry) */ 521 if ( TI_FALSE == pScanSRV->bNoScanCompleteFlag ) 522 { 523 pScanSRV->currentNumberOfConsecutiveNoScanCompleteEvents = 0; 524 } 525 526 /* copy result counter and scan tag */ 527 pScanSRV->uResultCount = pResult->numberOfScanResults; 528 pScanSRV->eScanTag = (EScanResultTag)pResult->scanTag; 529 530 /* copy scan SPS addmitted channels and SPS result */ 531 if (TI_FALSE == pScanSRV->bSPSScan) 532 { 533 /* normal scan - no result is available */ 534 pScanSRV->bTSFError = TI_FALSE; 535 TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "Normal scan completed.\n"); 536 } 537 else 538 { 539 /* SPS scan - first byte indicates whether a TSF error (AP recovery) occured */ 540 if ( 0 != (pResult->scheduledScanStatus >> 24)) 541 { 542 pScanSRV->bTSFError = TI_TRUE; 543 } 544 else 545 { 546 pScanSRV->bTSFError = TI_FALSE; 547 } 548 549 /* next two bytes indicates on which channels scan was attempted */ 550 pScanSRV->SPSScanResult = (TI_UINT16)(pResult->scheduledScanStatus >> 16) | 0xff; 551 pScanSRV->SPSScanResult = ENDIAN_HANDLE_WORD( pScanSRV->SPSScanResult ); 552 TRACE1( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "SPS scan completed. TSF error: , SPS result: %x\n", pScanSRV->SPSScanResult); 553 } 554 555 /* send a SCAN_COMPLETE event */ 556 scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_SCAN_COMPLETE ); 557 } 558 559 /** 560 * \\n 561 * \date 29-Dec-2004\n 562 * \brief called when a scan timer expires. Completes the scan and starts a recovery process. 563 * 564 * Function Scope \e Public.\n 565 * \param hScanSRV - handle to the scan SRV object.\n 566 * \param bTwdInitOccured - Indicates if TWDriver recovery occured since timer started.\n 567 */ 568 void MacServices_scanSRV_scanTimerExpired (TI_HANDLE hScanSRV, TI_BOOL bTwdInitOccured) 569 { 570 scanSRV_t *pScanSRV = (scanSRV_t*)hScanSRV; 571 572 /* mark that no scan complete occured (see sanSRV_scan for more detailed explanation) */ 573 pScanSRV->bNoScanCompleteFlag = TI_TRUE; 574 575 /* send a TIMER_EXPIRED event */ 576 scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_TIMER_EXPIRED ); 577 } 578 579 /** 580 * \\n 581 * \date 29-Dec-2004\n 582 * \brief Calculates the maximal time required for a scan operation 583 * 584 * Function Scope \e Public.\n 585 * \param hScanSRV - handle to the scan SRV object.\n 586 * \param scanParams - the scan parameters 587 * \param bConsiderDTIM - whether this scan overlaps DTIM 588 * \return the time (in milliseconds) 589 */ 590 TI_UINT32 MacServices_scanSRVcalculateScanTimeout( TI_HANDLE hScanSRV, TScanParams* scanParams, TI_BOOL bConsiderDTIM ) 591 { 592 TI_UINT32 i, uDtimPeriodMs, uBeaconIntervalMs, timeout = 0; 593 scanSRV_t *pScanSRV = (scanSRV_t*)hScanSRV; 594 595 /******************************************************************************** 596 timeout calculation is performed according to scan type: 597 1. for normal scan, multiply the channel time by the number of channels. 598 if this scan is not overlapping DTIM, add the DTIM period (in case 599 starting the scan right now will cause the very last milliseconds of the 600 scan to overlap the next DTIM). Add the guard time. 601 2. for triggered scan, multiply the channel time plus the trigger time 602 constant (the maximum time between two frames from the Tid 603 according to which the scan is triggered) by the number of channels. 604 DTIM period is added only as precaution - since the scan is divided to 605 channels, only very few of them will be delayed due to DTIM (in the worst 606 case), and this delay would be only the length of one channel scan. 607 Eventually, Add the guard time. 608 3. for SPS scan: Measure the time from current TSF to the TSF at which the 609 scan is scheduled to finish (done by the scan manager, and passed as 610 a parameter in the scan structure). Add guard time. DTIM overlapping is not 611 considered because if the scan overlaps DTIM the channels which are 612 scheduled during the DTIM (if any) won't be scanned. 613 ********************************************************************************/ 614 615 /* get DTIM time, if scanning in connected mode and need to consider DTIM */ 616 if ( bConsiderDTIM ) 617 { 618 /* new dtimPeriod calculation */ 619 uBeaconIntervalMs = MacServices_scanSRVConvertTUToMsec (pScanSRV->uBeaconInterval); 620 uDtimPeriodMs = uBeaconIntervalMs * pScanSRV->uDtimPeriod; 621 } 622 else 623 { 624 uDtimPeriodMs = 0; 625 } 626 627 switch (scanParams->scanType) 628 { 629 case SCAN_TYPE_NORMAL_ACTIVE: 630 case SCAN_TYPE_NORMAL_PASSIVE: 631 /* the timeout is the scan duration on all channels */ 632 for ( i = 0; i < scanParams->numOfChannels; i++ ) 633 { 634 timeout += scanParams->channelEntry[ i ].normalChannelEntry.maxChannelDwellTime; 635 } 636 timeout = (timeout / 1000) + uDtimPeriodMs + SCAN_SRV_FW_GUARD_TIME_MS; 637 break; 638 639 case SCAN_TYPE_TRIGGERED_ACTIVE: 640 case SCAN_TYPE_TRIGGERED_PASSIVE: 641 /* the timeout is the scan duration on all channels, plus the maximum time that can pass 642 between two different frames from the same Tid */ 643 for ( i = 0; i < scanParams->numOfChannels; i++ ) 644 { 645 timeout += scanParams->channelEntry[ i ].normalChannelEntry.maxChannelDwellTime; 646 } 647 timeout = (timeout / 1000) + uDtimPeriodMs + 648 ((pScanSRV->uTriggeredScanTimeOut / 1000 + 1) * scanParams->numOfChannels) + 649 SCAN_SRV_FW_GUARD_TIME_MS; 650 break; 651 652 case SCAN_TYPE_SPS: 653 timeout = scanParams->SPSScanDuration + SCAN_SRV_FW_GUARD_TIME_MS; 654 break; 655 656 default: 657 TRACE1( pScanSRV->hReport, REPORT_SEVERITY_ERROR, "Trying to calculate timeout for undefined scan type %d\n", scanParams->scanType); 658 break; 659 } 660 TRACE1( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "scanSRVcalculateScanTimeout, timeout = %d\n", timeout); 661 662 return timeout; 663 } 664 665 /** 666 * \\n 667 * \date 16-Jan-2005\n 668 * \brief Convert time units (1024 usecs) to millisecs 669 * 670 * Function Scope \e Private.\n 671 * \param tu - the time in time units 672 * \return the time in milliseconds 673 */ 674 TI_UINT32 MacServices_scanSRVConvertTUToMsec( TI_UINT32 tu ) 675 { 676 return (tu * 1024) / 1000; 677 } 678 679 680 /** 681 * \\n 682 * \brief Save DTIM and Beacon periods for scan timeout calculations 683 * 684 * Function Scope \e Public.\n 685 * \param hMacServices - module object 686 * \param uDtimPeriod - DTIM period in number of beacons 687 * \param uBeaconInterval - Beacon perios in TUs (1024 msec) 688 * \return void 689 */ 690 void MacServices_scanSrv_UpdateDtimTbtt (TI_HANDLE hMacServices, 691 TI_UINT8 uDtimPeriod, 692 TI_UINT16 uBeaconInterval) 693 { 694 scanSRV_t *pScanSRV = (scanSRV_t*)((MacServices_t*)hMacServices)->hScanSRV; 695 696 pScanSRV->uDtimPeriod = uDtimPeriod; 697 pScanSRV->uBeaconInterval = uBeaconInterval; 698 } 699 700 701 #ifdef TI_DBG 702 /** 703 * \\n 704 * \date God knows when...\n 705 * \brief Prints Scan Server SM status.\n 706 * 707 * Function Scope \e Public.\n 708 * \param hMacServices - handle to the Mac Services object.\n 709 * \return always TI_OK.\n 710 */ 711 void MacServices_scanSrv_printDebugStatus(TI_HANDLE hMacServices) 712 { 713 scanSRV_t *pScanSRV = (scanSRV_t*)((MacServices_t*)hMacServices)->hScanSRV; 714 715 WLAN_OS_REPORT(("scanSrv State=")); 716 switch (pScanSRV->SMState) 717 { 718 case SCAN_SRV_STATE_IDLE: 719 WLAN_OS_REPORT((" IDLE\n")); 720 break; 721 case SCAN_SRV_STATE_PS_WAIT: 722 WLAN_OS_REPORT((" PS_WAIT\n")); 723 break; 724 case SCAN_SRV_STATE_PS_EXIT: 725 WLAN_OS_REPORT((" PS_EXIT\n")); 726 break; 727 case SCAN_SRV_STATE_SCANNING: 728 WLAN_OS_REPORT((" SCANNING\n")); 729 break; 730 case SCAN_SRV_STATE_STOPPING: 731 WLAN_OS_REPORT((" STOPPING\n")); 732 break; 733 default: 734 WLAN_OS_REPORT((" Invalid State=%d\n",pScanSRV->SMState)); 735 break; 736 737 } 738 739 if (NULL != pScanSRV->scanParams) 740 { 741 WLAN_OS_REPORT(("scanSrv bExitFromDriverMode=%d, bHighPriority=%d, bInRequest=%d,\n \ 742 bScanOnDriverModeFailure=%d, bSendNullData=%d, bSPSScan=%d, bTimerRunning=%d, \n \ 743 psRequest=%d, scanType=%d\n", 744 pScanSRV->bExitFromDriverMode, 745 pScanSRV->bHighPriority, 746 pScanSRV->bInRequest, 747 pScanSRV->bScanOnDriverModeFailure, 748 pScanSRV->bSendNullData, 749 pScanSRV->bSPSScan, 750 pScanSRV->bTimerRunning, 751 pScanSRV->psRequest, 752 pScanSRV->scanParams->scanType)); 753 } 754 } 755 #endif 756 757