TI_STATUS scanSRVSM_releasePS( TI_HANDLE hScanSrv ) { scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv; TI_STATUS psStatus; /* stop timer */ if ( TI_TRUE == pScanSRV->bTimerRunning ) { tmr_StopTimer (pScanSRV->hScanSrvTimer); pScanSRV->bTimerRunning = TI_FALSE; } /* if exit from driver mode requested, do so */ if ( TI_TRUE == pScanSRV->bExitFromDriverMode ) { /* here we need to get an answer if we succeeded to exit driver mode */ psStatus = powerSrv_ReleasePS( pScanSRV->hPowerSrv, pScanSRV->bSendNullData, hScanSrv, MacServices_scanSRV_powerSaveCB); } else /* no need to exit PS - send PS_SUCCESS */ { return scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS ); } switch (psStatus) { /* if successful */ case POWER_SAVE_802_11_IS_CURRENT: /* send a PS_SUCCESS event */ return scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS ); /* if pending */ case POWER_SAVE_802_11_PENDING: case TI_OK: /* stay in the PS_EXIT state */ break; /* if not successful */ default: /* send a PS_FAIL event */ return scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_FAIL ); } return TI_OK; }
/** * \\n * \date 10-Jan-2005\n * \brief Request to enter driver mode from the power manager module.\n * * Function Scope \e Private.\n * \param hScanSrv - handle to the scan SRV object.\n * \return TI_OK if successful, TI_NOK otherwise.\n */ TI_STATUS scanSRVSM_requestPS( TI_HANDLE hScanSrv ) { scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv; TI_STATUS psStatus; psStatus = powerSrv_ReservePS( pScanSRV->hPowerSrv, pScanSRV->psRequest, pScanSRV->bSendNullData, hScanSrv, MacServices_scanSRV_powerSaveCB); switch (psStatus) { /* if successful */ case POWER_SAVE_802_11_IS_CURRENT: /* send a PS_SUCCESS event */ return scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS ); /* if pending */ case POWER_SAVE_802_11_PENDING: case TI_OK: /* send a PS_PEND event */ return scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_PEND ); /* if not successful */ default: /* mark not to exit from driver mode (no entry was performed) */ pScanSRV->bExitFromDriverMode = TI_FALSE; /* if still wishing to scan */ if ( pScanSRV->bScanOnDriverModeFailure ) { /* send a PS_SUCCESS event - scan will proceed regardless of the error */ scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS ); } /* otherwise, return */ else { /* mark the return code */ pScanSRV->returnStatus = TI_NOK; /* send a PS_FAIL event */ scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_FAIL ); } break; } return TI_OK; }
/** * \author Ronen Kalish\n * \date 29-Dec-2004\n * \brief Sends a Stop Scan command to FW, no matter if we are in scan progress or not * * Function Scope \e Public.\n * \param hMacServices - handle to the MacServices object.\n * \param bSendNullData - indicates whether to send Null data when exiting driver mode.\n * \param commandResponseFunc - CB function which called after downloading the command. \n * \param commandResponseObj - The CB function Obj (Notice : last 2 params are NULL in Legacy run). \n * \return OK if successful (various, TBD codes if not).\n */ TI_STATUS MacServices_scanSRV_stopScan( TI_HANDLE hMacServices, BOOLEAN bSendNullData, CmdResponseCB_t ScanCommandResponseCB, TI_HANDLE CB_handle ) { scanSRV_t *pScanSRV = (scanSRV_t*)((MacServices_t*)hMacServices)->hScanSRV; int stopScanStatus; WLAN_REPORT_INFORMATION( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("Stop scan request received.\n") ); /* update the driver mode exit flag */ pScanSRV->bSendNullData = bSendNullData; if ( TRUE == pScanSRV->bSPSScan ) { stopScanStatus = whalCtrl_StopSPSScan( pScanSRV->hHalCtrl , (void *)ScanCommandResponseCB, CB_handle); } else { stopScanStatus = whalCtrl_StopScan( pScanSRV->hHalCtrl,(void *)ScanCommandResponseCB, CB_handle); } if (OK != stopScanStatus) { return NOK; } /* send a stop scan event */ return scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_STOP_SCAN ); }
/** * \author Yuval Adler\n * \date 27-Sep-2005\n * \brief This function is the CB which is called as response to 'StartScan' or 'StopScan' \n. * here we check if there is a GWSI command response , and call it if necessary .\n * Function Scope \e Private.\n * \param hScanSrv - handle to the scan SRV object.\n * \param MboxStatus - mailbox status. \n */ void MacServices_scanSRVCommandMailBoxCB(TI_HANDLE hScanSrv,UINT16 MboxStatus) { scanSRV_t* pScanSRV = (scanSRV_t*)hScanSrv; UINT16 responseStatus; CmdResponseCB_t CB_Func; TI_HANDLE CB_Handle; WLAN_REPORT_INFORMATION( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("%s status %u\n",__FUNCTION__,MboxStatus) ); /* set response to OK or NOK */ responseStatus = ((MboxStatus > 0) ? NOK : OK); /* if we have a Response Function (only in GWSI) we set it back to NULL and then we call it */ if (pScanSRV->commandResponseFunc != NULL) { CB_Func = pScanSRV->commandResponseFunc; CB_Handle = pScanSRV->commandResponseObj; pScanSRV->commandResponseFunc = NULL; pScanSRV->commandResponseObj = NULL; CB_Func(CB_Handle, responseStatus); } /* if scan request failed */ if ( OK != responseStatus ) { WLAN_REPORT_ERROR( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("Mail box returned error , quitting scan.\n" )); /* send a scan complete event. This will do all necessary clean-up (timer, power manager, notifying scan complete) */ scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_SCAN_COMPLETE ); } }
/** * \author Ronen Kalish\n * \date 29-Dec-2004\n * \brief called when a scan timer expires. Completes the scan and starts a recovery process. * * Function Scope \e Public.\n * \param hScanSRV - handle to the scan SRV object.\n */ void MacServices_scanSRV_scanTimerExpired( TI_HANDLE hScanSRV ) { scanSRV_t *pScanSRV = (scanSRV_t*)hScanSRV; /* mark that no scan complete occured (see sanSRV_scan for more detailed explanation) */ pScanSRV->bNoScanCompleteFlag = TRUE; /* send a TIMER_EXPIRED event */ scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_TIMER_EXPIRED ); }
/** * \author Ronen Kalish\n * \date 17-Jan-2005\n * \brief Notifies the scan SRV of a FW reset (that had originally been reported by a different module).\n * * Function Scope \e Public.\n * \param hMacServices - handle to the MacServices object.\n * \return OK if successful (various, TBD codes if not).\n */ TI_STATUS MacServices_scanSRV_stopOnFWReset( TI_HANDLE hMacServices ) { scanSRV_t *pScanSRV = (scanSRV_t*)((MacServices_t*)hMacServices)->hScanSRV; WLAN_REPORT_INFORMATION( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("FW reset notification received.\n") ); /* mark the return status */ pScanSRV->returnStatus = NOK; /* send a FW reset event */ return scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_FW_RESET ); }
/** * \author Ronen Kalish\n * \date 29-Dec-2004\n * \brief callback function used by the power server to notify driver mode result * this CB is used in requesting PS and exiting PS. * Function Scope \e Public.\n * \param hScanSRV - handle to the scan SRV object.\n * \param psStatus - the power save request status.\n */ void MacServices_scanSRV_powerSaveCB( TI_HANDLE hScanSRV, UINT8 PSMode,UINT8 psStatus ) { scanSRV_t *pScanSRV = (scanSRV_t*)hScanSRV; WLAN_REPORT_INFORMATION( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("PS Call Back status %d .\n",psStatus) ); /* if driver mode enter/exit succeedded */ if ( (ENTER_POWER_SAVE_SUCCESS == psStatus) || (EXIT_POWER_SAVE_SUCCESS == psStatus) ) { WLAN_REPORT_INFORMATION( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("PS successful.\n") ); /* send a PS_SUCCESS event */ scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS ); } /* driver mode entry failed, and scan is requested even on PS failure but we are entering PS and not Exiting */ else if ( (TRUE == pScanSRV->bScanOnDriverModeFailure) && ( ENTER_POWER_SAVE_FAIL == psStatus) ) { WLAN_REPORT_INFORMATION( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("PS enter failed, continune scan .\n") ); /* send a PS_SUCCESS event */ scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS ); } /* driver mode enter or exit failed */ else { /* if we are trying to enter PS and fail to do so - return error on scan complete */ if ( ENTER_POWER_SAVE_FAIL == psStatus) { WLAN_REPORT_WARNING( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("PS enter failed . quiting scan .\n") ); /* Set the return status */ pScanSRV->returnStatus = NOK; } /* send a PS FAIL event */ scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_FAIL ); } }
/** * \author Ronen Kalish\n * \date 29-Dec-2004\n * \brief Callback function used by the HAL ctrl to notify scan complete * * Function Scope \e Public.\n * \param hScanSRV - handle to the scan SRV object.\n * \param str - pointer to scan result buffer (holding SPS status for SPS scan only!).\n * \param strLen - scan result buffer length (should ALWAYS be 2, even for non SPS scans).\n */ void MacServices_scanSRV_scanCompleteCB( TI_HANDLE hScanSRV, char* str, UINT32 strLen ) { scanSRV_t *pScanSRV = (scanSRV_t*)hScanSRV; WLAN_REPORT_INFORMATION( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("Scan complete notification from TNET.\n") ); /* nullify the consecutive no scan complete events counter - only if this is a scan complete that does not happen afetr a stop scan (due to a timer expiry) */ if ( FALSE == pScanSRV->bNoScanCompleteFlag ) { pScanSRV->currentNumberOfConsecutiveNoScanCompleteEvents = 0; } /* copy scan results according to scan type (only meaningful for SPS scan) */ if ( FALSE == pScanSRV->bSPSScan ) { /* normal scan - no result is available */ pScanSRV->bTSFError = FALSE; WLAN_REPORT_INFORMATION( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("Normal scan completed.\n") ); } else { /* SPS scan - first byte indicates whether a TSF error (AP recovery) occured */ if ( 0 != str[ 0 ] ) { pScanSRV->bTSFError = TRUE; } else { pScanSRV->bTSFError = FALSE; } /* next two bytes indicates on which channels scan was attempted */ /* pScanSRV->SPSScanResult = ENDIAN_HANDLE_WORD( *((UINT16*)&(str[ 1 ])) ); */ /* Swap of aligned UINT16* */ COPY_UNALIGNED_WORD(&pScanSRV->SPSScanResult, &str[1]); pScanSRV->SPSScanResult = ENDIAN_HANDLE_WORD( pScanSRV->SPSScanResult ); WLAN_REPORT_INFORMATION( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("SPS scan completed. TSF error: %s, SPS result: %x\n", (TRUE == pScanSRV->bTSFError ? "Yes": "No"), pScanSRV->SPSScanResult) ); } /* send a SCAN_COMPLETE event */ scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_SCAN_COMPLETE ); }
/** * \\n * \date 10-Jan-2005\n * \brief Handles a timer expiry event - starts a recovery process. * * Function Scope \e Private.\n * \param hScanSrv - handle to the scan SRV object.\n * \return TI_OK if successful, TI_NOK otherwise.\n */ TI_STATUS scanSRVSM_handleTimerExpiry( TI_HANDLE hScanSrv ) { scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv; /* No scan complete event will trigger recovery only after a consecutive configurable number of no scan complete events occurred. */ pScanSRV->currentNumberOfConsecutiveNoScanCompleteEvents++; if ( pScanSRV->currentNumberOfConsecutiveNoScanCompleteEvents >= pScanSRV->numberOfNoScanCompleteToRecovery ) { pScanSRV->currentNumberOfConsecutiveNoScanCompleteEvents = 0; /* mark the return status */ pScanSRV->returnStatus = TI_NOK; /* mark that the timer is no longer running */ pScanSRV->bTimerRunning = TI_FALSE; /* call the recovery module */ pScanSRV->failureEventFunc(pScanSRV->failureEventObj ,NO_SCAN_COMPLETE_FAILURE); } else { /* send a top scan command, which can help solving the FW bug described above */ if ( TI_FALSE == pScanSRV->bSPSScan ) { cmdBld_CmdStopScan (pScanSRV->hCmdBld, pScanSRV->eScanTag, NULL, NULL); } else { cmdBld_CmdStopSPSScan (pScanSRV->hCmdBld, pScanSRV->eScanTag, NULL, NULL); } /* imitate a scan complete event to the SM */ pScanSRV->bTSFError = TI_FALSE; pScanSRV->SPSScanResult = 0xffff; scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_SCAN_COMPLETE ); } return TI_OK; }
/** * \\n * \date 10-Jan-2005\n * \brief Send the scan command to the firmware.\n * * Function Scope \e Private.\n * \param hScanSrv - handle to the scan SRV object.\n * \return TI_OK if successful, TI_NOK otherwise.\n */ TI_STATUS scanSRVSM_startActualScan( TI_HANDLE hScanSrv ) { scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv; /* start the timer */ pScanSRV->bTimerRunning = TI_TRUE; tmr_StartTimer (pScanSRV->hScanSrvTimer, MacServices_scanSRV_scanTimerExpired, (TI_HANDLE)pScanSRV, MacServices_scanSRVcalculateScanTimeout (hScanSrv, pScanSRV->scanParams, !pScanSRV->bDtimOverlapping), TI_FALSE); /* start the scan */ /* we send the MacServices_scanSRVCommandMailBoxCB to be called when this command is recieved */ if ( SCAN_TYPE_SPS == pScanSRV->scanParams->scanType ) { pScanSRV->returnStatus = cmdBld_CmdStartSPSScan (pScanSRV->hCmdBld, pScanSRV->scanParams, pScanSRV->eScanTag, (void *)MacServices_scanSRVCommandMailBoxCB, hScanSrv); } else { pScanSRV->returnStatus = cmdBld_CmdStartScan (pScanSRV->hCmdBld, pScanSRV->scanParams, pScanSRV->eScanTag, pScanSRV->bHighPriority , (void *)MacServices_scanSRVCommandMailBoxCB, hScanSrv); } /* if scan request failed */ if ( TI_OK != pScanSRV->returnStatus ) { /* send a scan complete event. This will do all necessary clean-up (timer, power manager, notifying scan complete) */ scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_SCAN_COMPLETE ); } return TI_OK; }
/** * \author Ronen Kalish\n * \date 29-Dec-2004\n * \brief Performs a scan * * Function Scope \e Public.\n * \param hMacServices - handle to the MacServices object.\n * \param scanParams - the scan specific parameters.\n * \param bHighPriority - whether to perform a high priority (overlaps DTIM) scan.\n * \param bDriverMode - whether to try to enter driver mode (with PS on) before issuing the scan command.\n * \param bScanOnDriverModeError - whether to proceed with the scan if requested to enter driver mode and failed.\n * \param psRequest - Parameter sent to PowerSaveServer on PS request to indicate PS on or "keep current" * \param bSendNullData - whether to send Null data when exiting driver mode on scan complete.\n * \param commandResponseFunc - CB function which called after downloading the command. \n * \param commandResponseObj - The CB function Obj (Notice : last 2 params are NULL in Legacy run). \n * \param psRequest - Parameter sent to PowerSaveServer on PS request to indicate PS on or "keep current" * \return OK if successful (various, TBD codes if not).\n */ TI_STATUS MacServices_scanSRV_scan( TI_HANDLE hMacServices, scan_Params_t *scanParams, BOOLEAN bHighPriority, BOOLEAN bDriverMode, BOOLEAN bScanOnDriverModeError, PowerMgr_802_11_PsMode_e psRequest, BOOLEAN bSendNullData, CmdResponseCB_t commandResponseFunc, TI_HANDLE commandResponseObj) { scanSRV_t *pScanSRV = (scanSRV_t*)((MacServices_t*)hMacServices)->hScanSRV; WLAN_REPORT_INFORMATION( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("Scan request received.\n") ); /* sanity check - scan can only start if the scan SRV is idle */ if ( SCAN_SRV_STATE_IDLE != pScanSRV->SMState ) { WLAN_REPORT_WARNING( pScanSRV->hReport, SCAN_SRV_MODULE_LOG, ("Scan request while scan is running!\n") ); return NOK; } /* Response function for GWSI only. In Legacy run we get NULL and never use it. */ pScanSRV->commandResponseFunc = commandResponseFunc; pScanSRV->commandResponseObj = commandResponseObj; pScanSRV->bInRequest = TRUE; pScanSRV->returnStatus = OK; /* copy scan paramaters */ pScanSRV->scanParams = scanParams; pScanSRV->bHighPriority = bHighPriority; pScanSRV->bScanOnDriverModeFailure = bScanOnDriverModeError; pScanSRV->bSendNullData = bSendNullData; pScanSRV->psRequest = psRequest; if ( SCAN_TYPE_SPS == scanParams->scanType ) { pScanSRV->bSPSScan = TRUE; } else { pScanSRV->bSPSScan = FALSE; } /* check whether the scan will overlap DTIM frame */ if ( (FALSE == bHighPriority) && (TRUE == bDriverMode) ) { pScanSRV->bDtimOverlapping = FALSE; } else { pScanSRV->bDtimOverlapping = TRUE; } /* mark the no scan complete flag. The purpose of this flag is to be able to identify whether the scan complete is a normal process, or was it generated because a no scan ocmplete was identified, a stop scan command was snet to the FW, and thus a scan complete was received. In the former case we nullify the consecutive no scan complete counter, whereas in the latter we do not. */ pScanSRV->bNoScanCompleteFlag = FALSE; /* if required to enter driver mode */ if ( TRUE == bDriverMode ) { pScanSRV->bExitFromDriverMode = TRUE; /* send a PS_REQUEST event */ scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&(pScanSRV->SMState), SCAN_SRV_EVENT_REQUEST_PS ); } /* no driver mode required */ else { pScanSRV->bExitFromDriverMode = FALSE; /* send a PS_SUCCESS event - will start the scan */ scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS ); } pScanSRV->bInRequest = FALSE; return pScanSRV->returnStatus; }