1 /**************************************************************************** 2 **+-----------------------------------------------------------------------+** 3 **| |** 4 **| Copyright(c) 1998 - 2008 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 ****************************************************************************/ 35 36 37 /*******************************************************************************/ 38 /* */ 39 /* MODULE: recoveryMgr.c */ 40 /* PURPOSE: The responsibility of RecoveryMgr module is to provide main API */ 41 /* to HelthMonitor that invokes the recovery process if failure is */ 42 /* detected. It performs disable/enable inputs from outside, calls */ 43 /* restart of TWD and informs STAD modules that recovery has been */ 44 /* performed. */ 45 /* */ 46 /*******************************************************************************/ 47 48 #include "paramOut.h" 49 #include "osApi.h" 50 #include "DataCtrl_Api.h" 51 #include "report.h" 52 #include "recoveryMgr.h" 53 #include "recoveryMgr_API.h" 54 #include "TNETW_Driver_api.h" 55 56 #include "healthMonitor.h" 57 #include "PowerMgr_API.h" 58 #include "siteMgrApi.h" 59 #include "currBss.h" 60 #include "whalCtrl.h" 61 62 #include "TNETW_Driver.h" 63 #include "TNETWIF.h" 64 #include "SoftGeminiApi.h" 65 66 /* static function */ 67 #ifdef USE_RECOVERY 68 static void recoveryMgr_SM(TI_HANDLE hRecoveryMgr); 69 static TI_STATUS recoveryMgr_notifyStadAboutRecovery(TI_HANDLE hRecoveryMgr); 70 #endif /* USE_RECOVERY */ 71 72 /******************************************************************************* 73 * PUBLIC FUNCTIONS IMPLEMENTATION * 74 ********************************************************************************/ 75 76 /************************************************************************* 77 * recoveryMgr_create * 78 ************************************************************************** 79 * DESCRIPTION: This function initializes the RecoveryMgr module. 80 * 81 * INPUT: hOs - handle to Os Abstraction Layer 82 * 83 * RETURN: Handle to the allocated RecoveryMgr module 84 *************************************************************************/ 85 TI_HANDLE recoveryMgr_create(TI_HANDLE hOs) 86 { 87 #ifdef USE_RECOVERY 88 recoverMgr_t *hRecoveryMgr; 89 90 /* allocate RecoverMgr module */ 91 hRecoveryMgr = os_memoryAlloc(hOs, (sizeof(recoverMgr_t))); 92 93 if(!hRecoveryMgr) 94 { 95 WLAN_OS_REPORT(("Error allocating the RecoverMgr Module\n")); 96 return NULL; 97 } 98 99 /* Reset RecoverMgr module */ 100 os_memoryZero(hOs, hRecoveryMgr, (sizeof(recoverMgr_t))); 101 102 hRecoveryMgr->hOs = hOs; 103 104 return(hRecoveryMgr); 105 #else 106 return NULL; 107 #endif /* USE_RECOVERY */ 108 } /* recoveryMgr_create */ 109 110 111 112 /*************************************************************************** 113 * recoveryMgr_config * 114 **************************************************************************** 115 * DESCRIPTION: This function configures the recoveryMgr module 116 * 117 * RETURNS: OK - Configuration successful 118 * NOK - Configuration unsuccessful 119 ***************************************************************************/ 120 TI_STATUS recoveryMgr_config(TI_HANDLE hRecoveryMgr, 121 TI_HANDLE hReport, 122 TI_HANDLE hTxData, 123 TI_HANDLE hTnetwDrv, 124 TI_HANDLE hScr, 125 TI_HANDLE hCurrBss, 126 TI_HANDLE hPowerMgr, 127 TI_HANDLE hHealthMonitor, 128 TI_HANDLE hSoftGemini) 129 { 130 #ifdef USE_RECOVERY 131 recoverMgr_t *pRecoverMgr = (recoverMgr_t *)hRecoveryMgr; 132 133 /* configure modules handles */ 134 pRecoverMgr->hReport = hReport; 135 pRecoverMgr->hTxData = hTxData; 136 pRecoverMgr->hTnetwDrv = hTnetwDrv; 137 pRecoverMgr->hScr = hScr; 138 pRecoverMgr->hCurrBss = hCurrBss; 139 pRecoverMgr->hPowerMgr = hPowerMgr; 140 141 pRecoverMgr->hHealthMonitor = hHealthMonitor; 142 pRecoverMgr->hSoftGemini = hSoftGemini; 143 144 pRecoverMgr->fRecoveryInProcess = FALSE; 145 pRecoverMgr->smState = REC_MGR_STATE_IDLE; 146 147 WLAN_REPORT_INIT(pRecoverMgr->hReport, RECOVERY_MGR_MODULE_LOG, 148 (".....RecoveryMgr configured successfully\n")); 149 #endif /* USE_RECOVERY */ 150 return OK; 151 } /* recoveryMgr_config */ 152 153 /*************************************************************************** 154 * recoveryMgr_destroy * 155 **************************************************************************** 156 * DESCRIPTION: This function unload the RecoverMgr module. It frees 157 * the RecoveryMgr module 158 * 159 * INPUTS: hRecoveryMgr - the object 160 * 161 * OUTPUT: 162 * 163 * RETURNS: OK - Unload succesfull 164 * NOK - Unload unsuccesfull 165 ***************************************************************************/ 166 TI_STATUS recoveryMgr_destroy(TI_HANDLE hRecoveryMgr) 167 { 168 #ifdef USE_RECOVERY 169 recoverMgr_t *pRecoverMgr = (recoverMgr_t *)hRecoveryMgr; 170 171 /* free RecoverMgr Module */ 172 os_memoryFree(pRecoverMgr->hOs, pRecoverMgr, sizeof(recoverMgr_t)); 173 #endif /* USE_RECOVERY */ 174 return OK; 175 } 176 177 178 /********************************************************************************************** 179 * recoveryMgr_SM() 180 ********************************************************************************************** 181 * DESCRIPTION: 182 ============ 183 This is the recoveryMgr state machine. 184 The inceptive event for RecoveryMgr SM is invoking the recovery process by HelthMonitor. 185 After disabling Outside Inputs and starting TWD Restart, RecoveryMgr SM waits end of TWD Restart, 186 then informs STAD about recovery and enables Outside Inputs. 187 The SM supports both Sync and Async accesses to the HW. 188 It loops and progresses from state to state as long as the HW is accessed synchronously. 189 Once the access is Asynchronous (TNETWIF_PENDING), it exits and is called later 190 by the TNETWIF when the HW is ready. 191 That's why it uses unspecified-mode accesses (e.g. TNETWIF_ReadMemOpt) which 192 selects either Sync or Async automatically according to the platform and length. 193 Yet, the short transactions (EOB and Interrupt-Request 32 bit writes) are done using Sync 194 access to simplify the SM 195 NOTE: MCS projects may require full Sync/Async support, so the Sync accesses may need to be modified. 196 197 NOTE: The recoveryMgr-SM detailed description is provided in "CE-2.0 Recovery LLD.doc". 198 199 **********************************************************************************************/ 200 #ifdef USE_RECOVERY 201 static void recoveryMgr_SM(TI_HANDLE hRecoveryMgr) 202 { 203 recoverMgr_t *pRecoverMgr = (recoverMgr_t *)hRecoveryMgr; 204 healthMonitor_t *pHealthMonitor = (healthMonitor_t *)pRecoverMgr->hHealthMonitor; 205 206 #ifdef TI_DBG 207 if (hRecoveryMgr == NULL) 208 { 209 WLAN_REPORT_ERROR(pRecoverMgr->hReport, RECOVERY_MGR_MODULE_LOG, 210 ("recoveryMgr_SM(): **** Called with NULL handle!! ****\n")); 211 return; 212 } 213 #endif /* TI_DBG */ 214 215 WLAN_REPORT_INFORMATION(pRecoverMgr->hReport, RECOVERY_MGR_MODULE_LOG, 216 ("recoveryMgr_SM(): smState=%d\n", pRecoverMgr->smState)); 217 218 /* 219 * Loop through the states sequence as long as the process is synchronous. 220 * Exit when finished or if an Asynchronous process is required. In this case 221 * the SM process will be resumed later (called back by TNETWIF). 222 */ 223 switch (pRecoverMgr->smState) 224 { 225 226 case REC_MGR_STATE_IDLE: 227 WLAN_REPORT_INFORMATION(pRecoverMgr->hReport, RECOVERY_MGR_MODULE_LOG, 228 (".....REC_MGR_STATE_IDLE\n")); 229 230 healthMonitor_suspendPeriodicTest(pRecoverMgr->hHealthMonitor); 231 232 /* disabling Outside Inputs and starting TWD Restart */ 233 pRecoverMgr->fDisableInputsFromOs = TRUE; 234 235 /* suspend TX */ 236 txData_stop(pHealthMonitor->hTxData); 237 238 /* Disabling the IRQ line so the recovery will be an atomic action */ 239 os_disableIrq (pRecoverMgr->hOs); 240 241 pRecoverMgr->smState = REC_MGR_STATE_WAIT_TWD_RESTART; 242 243 TnetwDrv_StartRecovery(pRecoverMgr->hTnetwDrv, 244 (void*)recoveryMgr_endOfRecovery, 245 hRecoveryMgr); 246 247 return; 248 249 case REC_MGR_STATE_WAIT_TWD_RESTART: 250 WLAN_REPORT_INFORMATION(pRecoverMgr->hReport, RECOVERY_MGR_MODULE_LOG, 251 (".....REC_MGR_STATE_WAIT_TWD_RESTART\n")); 252 /* informs STAD about recovery */ 253 recoveryMgr_notifyStadAboutRecovery(hRecoveryMgr); 254 255 /* TX resume */ 256 txData_startAfterRecovery(pHealthMonitor->hTxData); 257 258 pRecoverMgr->fDisableInputsFromOs = FALSE; 259 260 /* call inside CmdMBox_SetModeNormal */ 261 whalCtrl_exitFromInitMode(((healthMonitor_t *)pRecoverMgr->hHealthMonitor)->hHalCtrl); 262 263 /* send the min power level to the FW */ 264 MacServices_powerAutho_ExitFromInit(((TnetwDrv_t *)pRecoverMgr->hTnetwDrv)->hMacServices); 265 266 /* Soft Gemini Section */ 267 SoftGemini_handleRecovery(pRecoverMgr->hSoftGemini); 268 269 WLAN_OS_REPORT((".....recoveryMgr: End Of Recovery\n")); 270 271 healthMonitor_resumePeriodicTest(pRecoverMgr->hHealthMonitor); 272 273 pRecoverMgr->fRecoveryInProcess = FALSE; 274 275 pRecoverMgr->smState = REC_MGR_STATE_IDLE; 276 return; /* recovery process ended */ 277 278 default: 279 WLAN_REPORT_ERROR(pRecoverMgr->hReport, RECOVERY_MGR_MODULE_LOG, 280 ("recoveryMgr_SM(): Unexpected state, smState=%d\n", pRecoverMgr->smState)); 281 return; 282 283 } /* switch (pRecoverMgr->smState) */ 284 } /* recoveryMgr_SM */ 285 #endif /* USE_RECOVERY */ 286 287 /*************************************************************************** 288 * recoveryMgr_recoveryProcess * 289 **************************************************************************** 290 * DESCRIPTION: Main interface that called if the WLAN driver detects error 291 * during the Monitoring process. 292 * 293 * INPUTS: hRecoveryMgr - the object 294 * 295 * OUTPUT: 296 * 297 * RETURNS: OK - Recovery Process started 298 * NOK - Recovery cannot started because it's in process already 299 ***************************************************************************/ 300 TI_STATUS recoveryMgr_recoveryProcess(TI_HANDLE hRecoveryMgr) 301 { 302 #ifdef USE_RECOVERY 303 recoverMgr_t *pRecoverMgr = (recoverMgr_t *)hRecoveryMgr; 304 healthMonitor_t *pHealthMonitor = (healthMonitor_t *)pRecoverMgr->hHealthMonitor; 305 WHAL_CTRL *pWhalCtrl = (WHAL_CTRL *)pHealthMonitor->hHalCtrl; 306 WlanParams_T *pWlanParams = whal_ParamsGetWlanParams(pWhalCtrl->pWhalParams); 307 308 if(!pWlanParams->RecoveryEnable) 309 { 310 WLAN_OS_REPORT(("recoveryMgr_recoveryProcess: Recovery is disabled in tiwlan.ini, abort recovery process\n")); 311 return OK; 312 } 313 else 314 WLAN_OS_REPORT((".....recoveryMgr_recoveryProcess\n")); 315 316 if(pRecoverMgr->fRecoveryInProcess == FALSE) 317 { 318 pHealthMonitor->numOfRecoveryPerformed++; 319 pRecoverMgr->fRecoveryInProcess = TRUE; 320 recoveryMgr_SM(hRecoveryMgr); 321 return OK; 322 } 323 else 324 { 325 WLAN_REPORT_ERROR(pRecoverMgr->hReport, RECOVERY_MGR_MODULE_LOG, 326 ("recoveryProcess(): **** Recovery in process already!! ****\n")); 327 return NOK; 328 } 329 #else 330 return OK; 331 #endif /* USE_RECOVERY */ 332 } /* recoveryMgr_recoveryProcess */ 333 334 335 336 337 /*************************************************************************** 338 * recoveryMgr_endOfRecovery * 339 **************************************************************************** 340 * DESCRIPTION: This function is the CB from the RecoveryCtrl that will 341 * issue the "EndOfTwdRestart" event to the RecoveryMgr SM. 342 * Indicates that TWD has performed its recovery. 343 * 344 * INPUTS: hRecoveryMgr - the object 345 * 346 * OUTPUT: 347 * 348 * RETURNS: OK - succesfull 349 * NOK - unsuccesfull 350 ***************************************************************************/ 351 TI_STATUS recoveryMgr_endOfRecovery(TI_HANDLE hRecoveryMgr) 352 { 353 #ifdef USE_RECOVERY 354 recoverMgr_t *pRecoverMgr = (recoverMgr_t *)hRecoveryMgr; 355 356 WLAN_REPORT_INIT(pRecoverMgr->hReport, RECOVERY_MGR_MODULE_LOG, 357 (".....recoveryMgr_endOfRecovery\n")); 358 359 recoveryMgr_SM(hRecoveryMgr); 360 #endif /* USE_RECOVERY */ 361 return OK; 362 } /* recoveryMgr_endOfRecovery */ 363 364 /*************************************************************************** 365 * recoveryMgr_notifyStadAboutRecovery * 366 **************************************************************************** 367 * DESCRIPTION: Inform STAD that recovery has been performed: inform TX, 368 * SCR, Current BSS and Power Mgr about FW reset. 369 * 370 * INPUTS: hRecoveryMgr - the object 371 * 372 * OUTPUT: 373 * 374 * RETURNS: OK - succesfull 375 * NOK - unsuccesfull 376 ***************************************************************************/ 377 #ifdef USE_RECOVERY 378 static TI_STATUS recoveryMgr_notifyStadAboutRecovery(TI_HANDLE hRecoveryMgr) 379 { 380 recoverMgr_t *pRecoverMgr = (recoverMgr_t *)hRecoveryMgr; 381 healthMonitor_t *pHealthMonitor = (healthMonitor_t *)pRecoverMgr->hHealthMonitor; 382 383 txData_recoveryIndication (pHealthMonitor->hTxData); 384 TnetwDrv_RecoveryCtrlBlk(pHealthMonitor->hTnetwDrv); 385 386 scr_notifyFWReset( pRecoverMgr->hScr ); 387 currBSS_performRecovery(pRecoverMgr->hCurrBss); 388 PowerMgr_notifyFWReset(pRecoverMgr->hPowerMgr); 389 390 return OK; 391 } /* recoveryMgr_notifyStadAboutRecovery */ 392 #endif /* USE_RECOVERY */ 393 /*************************************************************************** 394 * recoveryMgr_recoveryProcess * 395 **************************************************************************** 396 * DESCRIPTION: check if Inputs From OS are Disabled. 397 * 398 * INPUTS: hRecoveryMgr - the object 399 * 400 * OUTPUT: 401 * 402 * RETURN: TRUE - Inputs From OS are Disabled 403 * FALSE - Inputs From OS are not Disabled 404 ***************************************************************************/ 405 BOOL recoveryMgr_areInputsFromOsDisabled(TI_HANDLE hRecoveryMgr) 406 { 407 #ifdef USE_RECOVERY 408 recoverMgr_t *pRecoverMgr = (recoverMgr_t *)hRecoveryMgr; 409 410 return (pRecoverMgr->fDisableInputsFromOs); 411 #else 412 return FALSE; 413 #endif /* USE_RECOVERY */ 414 } /* recoveryMgr_recoveryProcess */ 415 416 417 418