Home | History | Annotate | Download | only in MacServices
      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