DrvMain.c revision 12d754a18612383f03b960dfad4dbcaba72df370
1/* 2 * DrvMain.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 35/** \file DrvMain.c 36 * \brief The DrvMain module. Handles driver init, stop and recovery processes. 37 * 38 * \see DrvMain.h 39 */ 40 41#define __FILE_ID__ FILE_ID_49 42#include "tidef.h" 43#include "osApi.h" 44#include "report.h" 45#include "context.h" 46#include "timer.h" 47#include "CmdHndlr.h" 48#include "DrvMain.h" 49#include "scrApi.h" 50#include "EvHandler.h" 51#include "connApi.h" 52#include "siteMgrApi.h" 53#include "sme.h" 54#include "SoftGeminiApi.h" 55#include "roamingMngrApi.h" 56#include "qosMngr_API.h" 57#include "TrafficMonitor.h" 58#include "PowerMgr_API.h" 59#include "EvHandler.h" 60#include "apConn.h" 61#include "currBss.h" 62#include "SwitchChannelApi.h" 63#include "ScanCncn.h" 64#include "healthMonitor.h" 65#include "scanMngrApi.h" 66#include "regulatoryDomainApi.h" 67#include "measurementMgrApi.h" 68#ifdef XCC_MODULE_INCLUDED 69#include "XCCMngr.h" 70#endif 71#include "TxnQueue.h" 72#include "TWDriver.h" 73#include "debug.h" 74#include "host_platform.h" 75#include "StaCap.h" 76#include "WlanDrvCommon.h" 77#include "DrvMainModules.h" 78#include "CmdDispatcher.h" 79 80 81#define SM_WATCHDOG_TIME_MS 20000 /* SM processes timeout is 20 sec. */ 82 83 84/* Handle failure status from the SM callbacks by triggering the SM with FAILURE event */ 85#define HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus) \ 86 if (eStatus != TI_OK) { drvMain_SmEvent (hDrvMain, SM_EVENT_FAILURE); return; } 87 88/* The DrvMain SM states */ 89typedef enum 90{ 91 /* 0 */ SM_STATE_IDLE, 92 /* 1 */ SM_STATE_WAIT_INI_FILE, 93 /* 2 */ SM_STATE_WAIT_NVS_FILE, 94 /* 3 */ SM_STATE_HW_INIT, 95 /* 4 */ SM_STATE_DOWNLOAD_FW_FILE, 96 /* 5 */ SM_STATE_WAIT_FW_FILE, 97 /* 6 */ SM_STATE_FW_INIT, 98 /* 7 */ SM_STATE_FW_CONFIG, 99 /* 8 */ SM_STATE_OPERATIONAL, 100 /* 9 */ SM_STATE_DISCONNECTING, 101 /* 10 */ SM_STATE_STOPPING, 102 /* 11 */ SM_STATE_STOPPED, 103 /* 12 */ SM_STATE_STOPPING_ON_FAIL, 104 /* 13 */ SM_STATE_FAILED 105 106} ESmState; 107 108/* The DrvMain SM events */ 109typedef enum 110{ 111 /* 0 */ SM_EVENT_START, 112 /* 1 */ SM_EVENT_INI_FILE_READY, 113 /* 2 */ SM_EVENT_NVS_FILE_READY, 114 /* 3 */ SM_EVENT_HW_INIT_COMPLETE, 115 /* 4 */ SM_EVENT_FW_FILE_READY, 116 /* 5 */ SM_EVENT_FW_INIT_COMPLETE, 117 /* 6 */ SM_EVENT_FW_CONFIG_COMPLETE, 118 /* 7 */ SM_EVENT_STOP, 119 /* 8 */ SM_EVENT_RECOVERY, 120 /* 9 */ SM_EVENT_DISCONNECTED, 121 /* 10 */ SM_EVENT_STOP_COMPLETE, 122 /* 11 */ SM_EVENT_FAILURE 123 124} ESmEvent; 125 126/* The module's object */ 127typedef struct 128{ 129 TStadHandlesList tStadHandles; /* All STAD modules handles (distributed in driver init process) */ 130 TI_BOOL bRecovery; /* Indicates if we are during recovery process */ 131 ESmState eSmState; /* The DrvMain SM state. */ 132 ESmEvent ePendingEvent;/* A pending event issued when the SM is busy */ 133 TI_UINT32 uPendingEventsCount; /* Counts the number of events pending for SM execution */ 134 TFileInfo tFileInfo; /* Information of last file retrieved by os_GetFile() */ 135 TI_UINT32 uContextId; /* ID allocated to this module on registration to context module */ 136 EActionType eAction; /* The last action (start/stop) inserted to the driver */ 137 void *hSignalObj; /* The signal object used for waiting for action completion */ 138 TI_HANDLE hWatchdogTimer;/* SM Watchdog timer - expires upon deadlock in Start/Stop/Recovery processes. */ 139 TBusDrvCfg tBusDrvCfg; /* A union (struc per each supported bus type) for the bus driver configuration */ 140 141} TDrvMain; 142 143 144static void drvMain_Init (TI_HANDLE hDrvMain); 145static void drvMain_InitHwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus); 146static void drvMain_InitFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus); 147static void drvMain_ConfigFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus); 148static void drvMain_TwdStopCb (TI_HANDLE hDrvMain, TI_STATUS eStatus); 149static void drvMain_InitFailCb (TI_HANDLE hDrvMain, TI_STATUS eStatus); 150static void drvMain_InitLocals (TDrvMain *pDrvMain); 151/* static void drvMain_SmWatchdogTimeout (TI_HANDLE hDrvMain); */ 152static void drvMain_SmEvent (TI_HANDLE hDrvMain, ESmEvent eEvent); 153static void drvMain_Sm (TI_HANDLE hDrvMain, ESmEvent eEvent); 154 155/* External functions prototypes */ 156 157/** \brief WLAN Driver I/F Get file 158 * 159 * \param hOs - OS module object handle 160 * \param pFileInfo - Pointer to output file information 161 * \return TI_OK on success or TI_NOK on failure 162 * 163 * \par Description 164 * This function provides access to a requested init file: 165 * It provides the requested file information and call the requester callback. 166 * Note that in Linux the files were previously loaded to driver memory by the loader 167 * 168 * \sa 169 */ 170extern int wlanDrvIf_GetFile (TI_HANDLE hOs, TFileInfo *pFileInfo); 171/** \brief WLAN Driver I/F Update Driver State 172 * 173 * \param hOs - OS module object handle 174 * \param eDriverState - New Driver State 175 * \return void 176 * 177 * \par Description 178 * This function Update the driver state (Idle | Running | Stopped |Failed): 179 * 180 * \sa 181 */ 182extern void wlanDrvIf_UpdateDriverState (TI_HANDLE hOs, EDriverSteadyState eDriverState); 183/** \brief WLAN Driver I/F Set MAC Address 184 * 185 * \param hOs - OS module object handle 186 * \param pMacAddr - Pointer to MAC address to set 187 * \return void 188 * 189 * \par Description 190 * This function Update the driver MAC address by copy it to the network interface structure 191 * 192 * \sa 193 */ 194extern void wlanDrvIf_SetMacAddress (TI_HANDLE hOs, TI_UINT8 *pMacAddr); 195/** \brief OS Init Table INI File 196 * 197 * \param hOs - OS module object handle 198 * \param InitTable - Pointer to initialization table 199 * \param file_buf - Pointer to Input buffer from INI file 200 * \param file_length - Length of input buffer from INI file 201 * \return void 202 * 203 * \par Description 204 * This function perform Initializing of init table accrding to data from INI file and driver defaults 205 * 206 * \sa 207 */ 208extern int osInitTable_IniFile (TI_HANDLE hOs, TInitTable *InitTable, char *file_buf, int file_length); 209 210 211 212/* 213 * \fn drvMain_Create 214 * \brief Create the driver modules 215 * 216 * Create all STAD and TWD modules. 217 * Then call all modules init functions which initializes their handles and variables. 218 * 219 * \note 220 * \param hOs - Handle to the Os Abstraction Layer 221 * \param pDrvMainHndl - Pointer for returning the DrvMain handle. 222 * \param pCmdHndlr - Pointer for returning the CmdHndlr handle. 223 * \param pContext - Pointer for returning the Context handle. 224 * \param pTxDataQ - Pointer for returning the TxDataQ handle. 225 * \param pTxMgmtQ - Pointer for returning the TxMgmtQ handle. 226 * \param pTxCtrl - Pointer for returning the TxCtrl handle. 227 * \param pTwd - Pointer for returning the TWD handle. 228 * \param pEvHandler - Pointer for returning the EvHndler handle. 229 * \return Handle to the DrvMain module (NULL if failed) 230 * \sa 231 */ 232TI_STATUS drvMain_Create (TI_HANDLE hOs, 233 TI_HANDLE *pDrvMainHndl, 234 TI_HANDLE *pCmdHndlr, 235 TI_HANDLE *pContext, 236 TI_HANDLE *pTxDataQ, 237 TI_HANDLE *pTxMgmtQ, 238 TI_HANDLE *pTxCtrl, 239 TI_HANDLE *pTwd, 240 TI_HANDLE *pEvHandler) 241{ 242 /* Create the DrvMain module object. */ 243 TDrvMain *pDrvMain = (TDrvMain *) os_memoryAlloc (hOs, sizeof(TDrvMain)); 244 245 if (pDrvMain == NULL) 246 { 247 return TI_NOK; 248 } 249 250 os_memoryZero (hOs, (void *)pDrvMain, sizeof(TDrvMain)); 251 252 pDrvMain->tStadHandles.hDrvMain = (TI_HANDLE)pDrvMain; 253 pDrvMain->tStadHandles.hOs = hOs; 254 255 /* Create watchdog timer to detect deadlocks in the DrvMain SM processes. */ 256 /* return thr timer later on */ 257 /*pDrvMain->hWatchdogTimer = os_timerCreate (hOs, drvMain_SmWatchdogTimeout, (TI_HANDLE)pDrvMain); 258 if (pDrvMain->hWatchdogTimer == NULL) 259 { 260 drvMain_Destroy (pDrvMain); 261 return TI_NOK; 262 }*/ 263 264/* 265 * Create all driver modules 266 * ========================= 267 */ 268 269 pDrvMain->tStadHandles.hContext = context_Create (hOs); 270 if (pDrvMain->tStadHandles.hContext == NULL) 271 { 272 drvMain_Destroy (pDrvMain); 273 return TI_NOK; 274 } 275 276 pDrvMain->tStadHandles.hTimer = tmr_Create (hOs); 277 if (pDrvMain->tStadHandles.hTimer == NULL) 278 { 279 drvMain_Destroy (pDrvMain); 280 return TI_NOK; 281 } 282 283 pDrvMain->tStadHandles.hSCR = scr_create (hOs); 284 if (pDrvMain->tStadHandles.hSCR == NULL) 285 { 286 drvMain_Destroy (pDrvMain); 287 return TI_NOK; 288 } 289 290 pDrvMain->tStadHandles.hTxnQ = txnQ_Create (hOs); 291 if (pDrvMain->tStadHandles.hTxnQ == NULL) 292 { 293 drvMain_Destroy (pDrvMain); 294 return TI_NOK; 295 } 296 297 pDrvMain->tStadHandles.hEvHandler = EvHandler_Create (hOs); 298 if (pDrvMain->tStadHandles.hEvHandler == NULL) 299 { 300 drvMain_Destroy (pDrvMain); 301 return TI_NOK; 302 } 303 304 pDrvMain->tStadHandles.hReport = report_Create (hOs); 305 if (pDrvMain->tStadHandles.hReport == NULL) 306 { 307 drvMain_Destroy (pDrvMain); 308 return TI_NOK; 309 } 310 311 pDrvMain->tStadHandles.hConn = conn_create (hOs); 312 if (pDrvMain->tStadHandles.hConn == NULL) 313 { 314 drvMain_Destroy (pDrvMain); 315 return TI_NOK; 316 } 317 318 pDrvMain->tStadHandles.hScanCncn = scanCncn_Create (hOs); 319 if (pDrvMain->tStadHandles.hScanCncn == NULL) 320 { 321 drvMain_Destroy (pDrvMain); 322 return TI_NOK; 323 } 324 325 pDrvMain->tStadHandles.hSme = sme_Create (hOs); 326 if (pDrvMain->tStadHandles.hSme == NULL) 327 { 328 drvMain_Destroy (pDrvMain); 329 return TI_NOK; 330 } 331 332 pDrvMain->tStadHandles.hSiteMgr = siteMgr_create (hOs); 333 if (pDrvMain->tStadHandles.hSiteMgr == NULL) 334 { 335 drvMain_Destroy (pDrvMain); 336 return TI_NOK; 337 } 338 339 pDrvMain->tStadHandles.hMlmeSm = mlme_create (hOs); 340 if (pDrvMain->tStadHandles.hMlmeSm == NULL) 341 { 342 drvMain_Destroy (pDrvMain); 343 return TI_NOK; 344 } 345 346 pDrvMain->tStadHandles.hAuth = auth_create (hOs); 347 if (pDrvMain->tStadHandles.hAuth == NULL) 348 { 349 drvMain_Destroy (pDrvMain); 350 return TI_NOK; 351 } 352 353 pDrvMain->tStadHandles.hAssoc = assoc_create (hOs); 354 if (pDrvMain->tStadHandles.hAssoc == NULL) 355 { 356 drvMain_Destroy (pDrvMain); 357 return TI_NOK; 358 } 359 360 pDrvMain->tStadHandles.hRxData = rxData_create (hOs); 361 if (pDrvMain->tStadHandles.hRxData == NULL) 362 { 363 drvMain_Destroy (pDrvMain); 364 return TI_NOK; 365 } 366 367 pDrvMain->tStadHandles.hTxCtrl = txCtrl_Create (hOs); 368 if (pDrvMain->tStadHandles.hTxCtrl == NULL) 369 { 370 drvMain_Destroy (pDrvMain); 371 return TI_NOK; 372 } 373 374 pDrvMain->tStadHandles.hTxDataQ = txDataQ_Create(hOs); 375 if (pDrvMain->tStadHandles.hTxDataQ == NULL) 376 { 377 drvMain_Destroy (pDrvMain); 378 return TI_NOK; 379 } 380 381 pDrvMain->tStadHandles.hTxMgmtQ = txMgmtQ_Create(hOs); 382 if (pDrvMain->tStadHandles.hTxMgmtQ == NULL) 383 { 384 drvMain_Destroy (pDrvMain); 385 return TI_NOK; 386 } 387 388 pDrvMain->tStadHandles.hTxPort = txPort_create (hOs); 389 if (pDrvMain->tStadHandles.hTxPort == NULL) 390 { 391 drvMain_Destroy (pDrvMain); 392 return TI_NOK; 393 } 394 395 pDrvMain->tStadHandles.hCtrlData = ctrlData_create (hOs); 396 if (pDrvMain->tStadHandles.hCtrlData == NULL) 397 { 398 drvMain_Destroy (pDrvMain); 399 return TI_NOK; 400 } 401 402 pDrvMain->tStadHandles.hTrafficMon = TrafficMonitor_create (hOs); 403 if (pDrvMain->tStadHandles.hTrafficMon == NULL) 404 { 405 drvMain_Destroy (pDrvMain); 406 return TI_NOK; 407 } 408 409 pDrvMain->tStadHandles.hRsn = rsn_create (hOs); 410 if (pDrvMain->tStadHandles.hRsn == NULL) 411 { 412 drvMain_Destroy (pDrvMain); 413 return TI_NOK; 414 } 415 416 pDrvMain->tStadHandles.hRegulatoryDomain = regulatoryDomain_create (hOs); 417 if (pDrvMain->tStadHandles.hRegulatoryDomain == NULL) 418 { 419 drvMain_Destroy (pDrvMain); 420 return TI_NOK; 421 } 422 423 pDrvMain->tStadHandles.hMeasurementMgr = measurementMgr_create (hOs); 424 if (pDrvMain->tStadHandles.hMeasurementMgr == NULL) 425 { 426 drvMain_Destroy (pDrvMain); 427 return TI_NOK; 428 } 429 430 pDrvMain->tStadHandles.hSoftGemini = SoftGemini_create (hOs); 431 if (pDrvMain->tStadHandles.hSoftGemini == NULL) 432 { 433 drvMain_Destroy (pDrvMain); 434 return TI_NOK; 435 } 436 437#ifdef XCC_MODULE_INCLUDED 438 pDrvMain->tStadHandles.hXCCMngr = XCCMngr_create (hOs); 439 if (pDrvMain->tStadHandles.hXCCMngr == NULL) 440 { 441 drvMain_Destroy (pDrvMain); 442 return TI_NOK; 443 } 444#else 445 pDrvMain->tStadHandles.hXCCMngr = NULL; 446#endif 447 448 pDrvMain->tStadHandles.hRoamingMngr = roamingMngr_create (hOs); 449 if (pDrvMain->tStadHandles.hRoamingMngr == NULL) 450 { 451 drvMain_Destroy (pDrvMain); 452 return TI_NOK; 453 } 454 455 pDrvMain->tStadHandles.hAPConnection = apConn_create (hOs); 456 if (pDrvMain->tStadHandles.hAPConnection == NULL) 457 { 458 drvMain_Destroy (pDrvMain); 459 return TI_NOK; 460 } 461 462 pDrvMain->tStadHandles.hCurrBss = currBSS_create (hOs); 463 if (pDrvMain->tStadHandles.hCurrBss == NULL) 464 { 465 drvMain_Destroy (pDrvMain); 466 return TI_NOK; 467 } 468 469 pDrvMain->tStadHandles.hQosMngr = qosMngr_create (hOs); 470 if (pDrvMain->tStadHandles.hQosMngr == NULL) 471 { 472 drvMain_Destroy (pDrvMain); 473 return TI_NOK; 474 } 475 476 pDrvMain->tStadHandles.hPowerMgr = PowerMgr_create (hOs); 477 if (pDrvMain->tStadHandles.hPowerMgr == NULL) 478 { 479 drvMain_Destroy (pDrvMain); 480 return TI_NOK; 481 } 482 483 pDrvMain->tStadHandles.hSwitchChannel = switchChannel_create (hOs); 484 if (pDrvMain->tStadHandles.hSwitchChannel == NULL) 485 { 486 drvMain_Destroy (pDrvMain); 487 return TI_NOK; 488 } 489 490 pDrvMain->tStadHandles.hScanMngr = scanMngr_create (hOs); 491 if (NULL == pDrvMain->tStadHandles.hScanMngr) 492 { 493 drvMain_Destroy (pDrvMain); 494 return TI_NOK; 495 } 496 497 pDrvMain->tStadHandles.hHealthMonitor = healthMonitor_create (hOs); 498 if (NULL == pDrvMain->tStadHandles.hHealthMonitor) 499 { 500 drvMain_Destroy (pDrvMain); 501 return TI_NOK; 502 } 503 504 pDrvMain->tStadHandles.hTWD = TWD_Create (hOs); 505 if (pDrvMain->tStadHandles.hTWD == NULL) 506 { 507 drvMain_Destroy (pDrvMain); 508 return TI_NOK; 509 } 510 511 pDrvMain->tStadHandles.hCmdHndlr = cmdHndlr_Create (hOs, pDrvMain->tStadHandles.hEvHandler); 512 if (pDrvMain->tStadHandles.hCmdHndlr == NULL) 513 { 514 drvMain_Destroy (pDrvMain); 515 return TI_NOK; 516 } 517 518 pDrvMain->tStadHandles.hCmdDispatch = cmdDispatch_Create (hOs); 519 if (pDrvMain->tStadHandles.hCmdDispatch == NULL) 520 { 521 drvMain_Destroy (pDrvMain); 522 return TI_NOK; 523 } 524 525 pDrvMain->tStadHandles.hStaCap = StaCap_Create (hOs); 526 if (pDrvMain->tStadHandles.hStaCap == NULL) 527 { 528 drvMain_Destroy (pDrvMain); 529 return TI_NOK; 530 } 531 532 /* Bind all modules handles */ 533 drvMain_Init ((TI_HANDLE)pDrvMain); 534 535 536 /* Provide required handles to the OAL */ 537 *pDrvMainHndl = (TI_HANDLE)pDrvMain; 538 *pCmdHndlr = pDrvMain->tStadHandles.hCmdHndlr; 539 *pContext = pDrvMain->tStadHandles.hContext; 540 *pTxDataQ = pDrvMain->tStadHandles.hTxDataQ; 541 *pTxMgmtQ = pDrvMain->tStadHandles.hTxMgmtQ; 542 *pTxCtrl = pDrvMain->tStadHandles.hTxCtrl; 543 *pTwd = pDrvMain->tStadHandles.hTWD; 544 *pEvHandler = pDrvMain->tStadHandles.hEvHandler; 545 546 WLAN_INIT_REPORT (("drvMain_Create: success\n")); 547 548 return TI_OK; 549} 550 551 552/* 553 * \fn drvMain_Destroy 554 * \brief Destroy driver 555 * 556 * Destroy all STAD and TWD modules and resources. 557 * 558 * \note 559 * \param hDrvMain - The DrvMain object 560 * \return TI_OK if succeeded, TI_NOK if failed. 561 * \sa drvMain_Create 562 */ 563TI_STATUS drvMain_Destroy (TI_HANDLE hDrvMain) 564{ 565 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 566 567 hPlatform_Wlan_Hardware_DeInit (); 568 569 if (pDrvMain == NULL) 570 { 571 return TI_NOK; 572 } 573 574 if (pDrvMain->tStadHandles.hScanMngr != NULL) 575 { 576 scanMngr_unload (pDrvMain->tStadHandles.hScanMngr); 577 } 578 579 if (pDrvMain->tStadHandles.hSiteMgr != NULL) 580 { 581 siteMgr_unLoad (pDrvMain->tStadHandles.hSiteMgr); 582 } 583 584 if (pDrvMain->tStadHandles.hSme != NULL) 585 { 586 sme_Destroy (pDrvMain->tStadHandles.hSme); 587 } 588 589 if (pDrvMain->tStadHandles.hConn != NULL) 590 { 591 conn_unLoad (pDrvMain->tStadHandles.hConn); 592 } 593 594 if (pDrvMain->tStadHandles.hTWD != NULL) 595 { 596 TWD_Destroy (pDrvMain->tStadHandles.hTWD); 597 } 598 599 if (pDrvMain->tStadHandles.hScanCncn != NULL) 600 { 601 scanCncn_Destroy (pDrvMain->tStadHandles.hScanCncn); 602 } 603 604 if (pDrvMain->tStadHandles.hTrafficMon != NULL) 605 { 606 TrafficMonitor_Destroy (pDrvMain->tStadHandles.hTrafficMon); 607 } 608 609 if (pDrvMain->tStadHandles.hCtrlData != NULL) 610 { 611 ctrlData_unLoad (pDrvMain->tStadHandles.hCtrlData); 612 } 613 614 if (pDrvMain->tStadHandles.hTxCtrl != NULL) 615 { 616 txCtrl_Unload (pDrvMain->tStadHandles.hTxCtrl); 617 } 618 619 if (pDrvMain->tStadHandles.hTxDataQ != NULL) 620 { 621 txDataQ_Destroy (pDrvMain->tStadHandles.hTxDataQ); 622 } 623 624 if (pDrvMain->tStadHandles.hTxMgmtQ != NULL) 625 { 626 txMgmtQ_Destroy (pDrvMain->tStadHandles.hTxMgmtQ); 627 } 628 629 if (pDrvMain->tStadHandles.hTxPort != NULL) 630 { 631 txPort_unLoad (pDrvMain->tStadHandles.hTxPort); 632 } 633 634 if (pDrvMain->tStadHandles.hRxData != NULL) 635 { 636 rxData_unLoad (pDrvMain->tStadHandles.hRxData); 637 } 638 639 if (pDrvMain->tStadHandles.hAssoc != NULL) 640 { 641 assoc_unload (pDrvMain->tStadHandles.hAssoc); 642 } 643 644 if (pDrvMain->tStadHandles.hAuth != NULL) 645 { 646 auth_unload (pDrvMain->tStadHandles.hAuth); 647 } 648 649 if (pDrvMain->tStadHandles.hMlmeSm != NULL) 650 { 651 mlme_unload (pDrvMain->tStadHandles.hMlmeSm); 652 } 653 654 if (pDrvMain->tStadHandles.hSCR != NULL) 655 { 656 scr_release (pDrvMain->tStadHandles.hSCR); 657 } 658 659 if (pDrvMain->tStadHandles.hEvHandler != NULL) 660 { 661 EvHandlerUnload (pDrvMain->tStadHandles.hEvHandler); 662 } 663 664 if (pDrvMain->tStadHandles.hRsn != NULL) 665 { 666 rsn_unload (pDrvMain->tStadHandles.hRsn); 667 } 668 669 if (pDrvMain->tStadHandles.hRegulatoryDomain != NULL) 670 { 671 regulatoryDomain_destroy (pDrvMain->tStadHandles.hRegulatoryDomain); 672 } 673 674 if (pDrvMain->tStadHandles.hMeasurementMgr != NULL) 675 { 676 measurementMgr_destroy (pDrvMain->tStadHandles.hMeasurementMgr); 677 } 678 679 if (pDrvMain->tStadHandles.hSoftGemini != NULL) 680 { 681 SoftGemini_destroy (pDrvMain->tStadHandles.hSoftGemini); 682 } 683 684#ifdef XCC_MODULE_INCLUDED 685 if (pDrvMain->tStadHandles.hXCCMngr != NULL) 686 { 687 XCCMngr_unload (pDrvMain->tStadHandles.hXCCMngr); 688 } 689#endif 690 691 if (pDrvMain->tStadHandles.hRoamingMngr != NULL) 692 { 693 roamingMngr_unload (pDrvMain->tStadHandles.hRoamingMngr); 694 } 695 696 if (pDrvMain->tStadHandles.hQosMngr != NULL) 697 { 698 qosMngr_destroy (pDrvMain->tStadHandles.hQosMngr); 699 } 700 701 if (pDrvMain->tStadHandles.hPowerMgr != NULL) 702 { 703 PowerMgr_destroy (pDrvMain->tStadHandles.hPowerMgr); 704 } 705 706 if (pDrvMain->tStadHandles.hAPConnection != NULL) 707 { 708 apConn_unload (pDrvMain->tStadHandles.hAPConnection); 709 } 710 711 if (pDrvMain->tStadHandles.hCurrBss != NULL) 712 { 713 currBSS_unload (pDrvMain->tStadHandles.hCurrBss); 714 } 715 716 if (pDrvMain->tStadHandles.hSwitchChannel != NULL) 717 { 718 switchChannel_unload (pDrvMain->tStadHandles.hSwitchChannel); 719 } 720 721 if (pDrvMain->tStadHandles.hHealthMonitor != NULL) 722 { 723 healthMonitor_unload (pDrvMain->tStadHandles.hHealthMonitor); 724 } 725 726 if (pDrvMain->tStadHandles.hCmdHndlr && pDrvMain->tStadHandles.hEvHandler) 727 { 728 cmdHndlr_Destroy (pDrvMain->tStadHandles.hCmdHndlr, pDrvMain->tStadHandles.hEvHandler); 729 } 730 731 if (pDrvMain->tStadHandles.hCmdDispatch) 732 { 733 cmdDispatch_Destroy (pDrvMain->tStadHandles.hCmdDispatch); 734 } 735 736 if (pDrvMain->tStadHandles.hContext != NULL) 737 { 738 context_Destroy (pDrvMain->tStadHandles.hContext); 739 } 740 741 /* Note: The Timer module must be destroyed last, so all created timers are already destroyed!! */ 742 if (pDrvMain->tStadHandles.hTimer != NULL) 743 { 744 tmr_Destroy (pDrvMain->tStadHandles.hTimer); 745 } 746 747 /* Destroy the SM watchdog timer */ 748 if (pDrvMain->hWatchdogTimer != NULL) 749 { 750 os_timerDestroy (pDrvMain->tStadHandles.hOs, pDrvMain->hWatchdogTimer); 751 } 752 753 if (pDrvMain->tStadHandles.hStaCap != NULL) 754 { 755 StaCap_Destroy (pDrvMain->tStadHandles.hStaCap); 756 } 757 758 if (pDrvMain->tStadHandles.hReport != NULL) 759 { 760 report_Unload (pDrvMain->tStadHandles.hReport); 761 } 762 763 /* Destroy the DrvMain object */ 764 os_memoryFree (pDrvMain->tStadHandles.hOs, hDrvMain, sizeof(TDrvMain)); 765 766 return TI_OK; 767} 768 769void drvMain_SmeStop (TI_HANDLE hDrvMain) 770{ 771 drvMain_SmEvent (hDrvMain, SM_EVENT_DISCONNECTED); 772} 773 774 775/* 776 * \fn drvMain_Init 777 * \brief Init driver modules 778 * 779 * Called from OS context following the driver creation. 780 * Calls all STAD and TWD modules Init functions, which are saving other modules handles, 781 * registering to other modules and initializing their variables. 782 * 783 * \note 784 * \param hDrvMain - The DrvMain object 785 * \return void 786 * \sa drvMain_Create 787 */ 788static void drvMain_Init (TI_HANDLE hDrvMain) 789{ 790 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 791 TStadHandlesList *pModules = &pDrvMain->tStadHandles; /* The STAD modules handles list */ 792 793 /* 794 * Init all modules handles, variables and registries 795 */ 796 context_Init (pModules->hContext, pModules->hOs, pModules->hReport); 797 tmr_Init (pModules->hTimer, pModules->hOs, pModules->hReport, pModules->hContext); 798 txnQ_Init (pModules->hTxnQ, pModules->hOs, pModules->hReport, pModules->hContext); 799 scr_init (pModules); 800 conn_init (pModules); 801 ctrlData_init (pModules, 802 #ifdef XCC_MODULE_INCLUDED 803 XCCMngr_LinkTestRetriesUpdate, pModules->hXCCMngr); 804 #else 805 NULL, NULL); 806 #endif 807 siteMgr_init (pModules); 808 regulatoryDomain_init (pModules); 809 scanCncn_Init (pModules); 810 auth_init (pModules); 811 mlme_init (pModules); 812 assoc_init (pModules); 813 rxData_init (pModules); 814 txCtrl_Init (pModules); 815 txDataQ_Init (pModules); 816 txMgmtQ_Init (pModules); 817 txPort_init (pModules); 818 TrafficMonitor_Init (pModules, 1000 /* pInitTable->trafficMonitorMinIntervalPercentage */); 819 sme_Init (pModules); 820 rsn_init (pModules); 821 measurementMgr_init (pModules); 822#ifdef XCC_MODULE_INCLUDED 823 XCCMngr_init (pModules); 824#endif 825 scanMngr_init (pModules); 826 currBSS_init (pModules); 827 apConn_init (pModules); 828 roamingMngr_init (pModules); 829 qosMngr_init (pModules); 830 switchChannel_init (pModules); 831 healthMonitor_init (pModules); 832 PowerMgr_init (pModules); 833 SoftGemini_init (pModules); 834 cmdDispatch_Init (pModules); 835 StaCap_Init (pModules); 836 cmdHndlr_Init (pModules); 837 838 /* Init TWD component (handles, variables and registries) and provide callbacks for next steps */ 839 TWD_Init (pModules->hTWD, 840 pModules->hReport, 841 pModules->hDrvMain, 842 pModules->hTimer, 843 pModules->hContext, 844 pModules->hTxnQ, 845 (TTwdCallback)drvMain_InitHwCb, 846 (TTwdCallback)drvMain_InitFwCb, 847 (TTwdCallback)drvMain_ConfigFwCb, 848 (TTwdCallback)drvMain_TwdStopCb, 849 (TTwdCallback)drvMain_InitFailCb); 850 851 /* Init DrvMain module local variables */ 852 drvMain_InitLocals (pDrvMain); 853} 854 855 856/* 857 * \fn drvMain_SetDefaults 858 * \brief Set driver default configuration 859 * 860 * Configure all STAD and TWD modules with their default settings from the ini-file. 861 * Timers creation is also done at this stage. 862 * 863 * \note 864 * \param hDrvMain - The DrvMain object 865 * \param pBuf - The ini-file data. 866 * \param uLength - The ini-file length. 867 * \return TI_OK if succeeded, TI_NOK if failed. 868 * \sa drvMain_Init 869 */ 870static TI_STATUS drvMain_SetDefaults (TI_HANDLE hDrvMain, TI_UINT8 *pBuf, TI_UINT32 uLength) 871{ 872 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 873 TInitTable *pInitTable; 874 TI_STATUS eStatus; 875 876 pInitTable = os_memoryAlloc (pDrvMain->tStadHandles.hOs, sizeof(TInitTable)); 877 878 /* Parse defaults */ 879 eStatus = osInitTable_IniFile (pDrvMain->tStadHandles.hOs, pInitTable, (char*)pBuf, (int)uLength); 880 881 /* 882 * Configure modules with their default settings 883 */ 884 report_SetDefaults (pDrvMain->tStadHandles.hReport, &pInitTable->tReport); 885 context_SetDefaults (pDrvMain->tStadHandles.hContext, &pInitTable->tContextInitParams); 886 TWD_SetDefaults (pDrvMain->tStadHandles.hTWD, &pInitTable->twdInitParams); 887 conn_SetDefaults (pDrvMain->tStadHandles.hConn, &pInitTable->connInitParams); 888 ctrlData_SetDefaults (pDrvMain->tStadHandles.hCtrlData, &pInitTable->ctrlDataInitParams); 889 siteMgr_SetDefaults (pDrvMain->tStadHandles.hSiteMgr, &pInitTable->siteMgrInitParams); 890 regulatoryDomain_SetDefaults (pDrvMain->tStadHandles.hRegulatoryDomain, &pInitTable->regulatoryDomainInitParams); 891 scanCncn_SetDefaults (pDrvMain->tStadHandles.hScanCncn, &pInitTable->tScanCncnInitParams); 892 auth_SetDefaults (pDrvMain->tStadHandles.hAuth, &pInitTable->authInitParams); 893 assoc_SetDefaults (pDrvMain->tStadHandles.hAssoc, &pInitTable->assocInitParams); 894 rxData_SetDefaults (pDrvMain->tStadHandles.hRxData, &pInitTable->rxDataInitParams); 895 sme_SetDefaults (pDrvMain->tStadHandles.hSme, &pInitTable->tSmeModifiedInitParams, &pInitTable->tSmeInitParams); 896 rsn_SetDefaults (pDrvMain->tStadHandles.hRsn, &pInitTable->rsnInitParams); 897 measurementMgr_SetDefaults (pDrvMain->tStadHandles.hMeasurementMgr, &pInitTable->measurementInitParams); 898#ifdef XCC_MODULE_INCLUDED 899 XCCMngr_SetDefaults (pDrvMain->tStadHandles.hXCCMngr, &pInitTable->XCCMngrParams); 900#endif /*XCC_MODULE_INCLUDED*/ 901 apConn_SetDefaults (pDrvMain->tStadHandles.hAPConnection, &pInitTable->apConnParams); 902 qosMngr_SetDefaults (pDrvMain->tStadHandles.hQosMngr, &pInitTable->qosMngrInitParams); 903 switchChannel_SetDefaults (pDrvMain->tStadHandles.hSwitchChannel, &pInitTable->SwitchChannelInitParams); 904 healthMonitor_SetDefaults (pDrvMain->tStadHandles.hHealthMonitor, &pInitTable->healthMonitorInitParams); 905 PowerMgr_SetDefaults (pDrvMain->tStadHandles.hPowerMgr, &pInitTable->PowerMgrInitParams); 906 SoftGemini_SetDefaults (pDrvMain->tStadHandles.hSoftGemini, &pInitTable->SoftGeminiInitParams); 907 txDataQ_SetDefaults (pDrvMain->tStadHandles.hTxDataQ, &pInitTable->txDataInitParams); 908 txCtrl_SetDefaults (pDrvMain->tStadHandles.hTxCtrl, &pInitTable->txDataInitParams); 909 currBSS_SetDefaults (pDrvMain->tStadHandles.hCurrBss, &pInitTable->tCurrBssInitParams); 910 mlme_SetDefaults (pDrvMain->tStadHandles.hMlmeSm, &pInitTable->tMlmeInitParams); 911 912 /* Set DrvMain local defaults */ 913 pDrvMain->tBusDrvCfg.tSdioCfg.uBlkSizeShift = pInitTable->tDrvMainParams.uSdioBlkSizeShift; 914 pDrvMain->tBusDrvCfg.tSdioCfg.uBusDrvThreadPriority = pInitTable->tDrvMainParams.uBusDrvThreadPriority; 915 os_SetDrvThreadPriority (pDrvMain->tStadHandles.hOs, pInitTable->tDrvMainParams.uWlanDrvThreadPriority); 916 917 /* Release the init table memory */ 918 os_memoryFree (pDrvMain->tStadHandles.hOs, pInitTable, sizeof(TInitTable)); 919 920 return eStatus; 921} 922 923 924/* 925 * \fn drvMain_xxx...Cb 926 * \brief Callback functions for the init/stop stages completion 927 * 928 * The following callback functions are called from other modules (most from TWD) 929 * when the current init/stop step is completed. 930 * Note that the callbacks are called anyway, either in the original context (if completed), or 931 * in another context if pending. 932 * The first case (same context) may lead to a recursion of the SM, so a special handling is added 933 * to the SM to prevent recursion (see drvMain_Sm). 934 * 935 * drvMain_InitHwCb - HW init completion callback 936 * drvMain_InitFwCb - FW init (mainly download) completion callback 937 * drvMain_ConfigFwCb - FW configuration completion callback 938 * drvMain_TwdStopCb - TWD stopping completion callback 939 * drvMain_InitFailCb - FW init faulty completion callback 940 * drvMain_SmeStopCb - SME stopping completion callback 941 * drvMain_GetFileCb - Getting-file completion callback 942 * 943 * \note 944 * \param hDrvMain - The DrvMain object 945 * \param eStatus - The process result (TI_OK if succeeded, TI_NOK if failed) 946 * \return void 947 * \sa drvMain_Create 948 */ 949static void drvMain_InitHwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus) 950{ 951 HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus); 952 drvMain_SmEvent (hDrvMain, SM_EVENT_HW_INIT_COMPLETE); 953} 954 955static void drvMain_InitFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus) 956{ 957 HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus); 958 drvMain_SmEvent (hDrvMain, SM_EVENT_FW_INIT_COMPLETE); 959} 960 961static void drvMain_ConfigFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus) 962{ 963 HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus); 964 drvMain_SmEvent (hDrvMain, SM_EVENT_FW_CONFIG_COMPLETE); 965} 966 967static void drvMain_TwdStopCb (TI_HANDLE hDrvMain, TI_STATUS eStatus) 968{ 969 HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus); 970 drvMain_SmEvent (hDrvMain, SM_EVENT_STOP_COMPLETE); 971} 972 973static void drvMain_InitFailCb (TI_HANDLE hDrvMain, TI_STATUS eStatus) 974{ 975 drvMain_SmEvent (hDrvMain, SM_EVENT_FAILURE); 976 /* 977 * Note that this call will pass the SM to the FAILED state, since this event 978 * is not handled by any state. 979 */ 980} 981 982static void drvMain_InvokeAction (TI_HANDLE hDrvMain) 983{ 984 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 985 986 switch (pDrvMain->eAction) 987 { 988 case ACTION_TYPE_START: 989 drvMain_SmEvent (hDrvMain, SM_EVENT_START); 990 break; 991 case ACTION_TYPE_STOP: 992 drvMain_SmEvent (hDrvMain, SM_EVENT_STOP); 993 break; 994 default: 995 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_InvokeAction(): Action=%d\n", pDrvMain->eAction); 996 } 997} 998 999static void drvMain_GetFileCb (TI_HANDLE hDrvMain) 1000{ 1001 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 1002 ESmEvent eSmEvent; 1003 1004 switch (pDrvMain->tFileInfo.eFileType) 1005 { 1006 case FILE_TYPE_INI: eSmEvent = SM_EVENT_INI_FILE_READY; break; 1007 case FILE_TYPE_NVS: eSmEvent = SM_EVENT_NVS_FILE_READY; break; 1008 case FILE_TYPE_FW: eSmEvent = SM_EVENT_FW_FILE_READY; break; 1009 case FILE_TYPE_FW_NEXT: eSmEvent = SM_EVENT_FW_FILE_READY; break; 1010 default: 1011 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_GetFileCb(): Unknown eFileType=%d\n", pDrvMain->tFileInfo.eFileType); 1012 return; 1013 } 1014 drvMain_SmEvent (hDrvMain, eSmEvent); 1015} 1016 1017 1018/* 1019 * \fn drvMain_InitLocals 1020 * \brief Init DrvMain module 1021 * 1022 * Init the DrvMain variables, register to other modules and set device power to off. 1023 * 1024 * \note 1025 * \param pDrvMain - The DrvMain object 1026 * \return void 1027 * \sa drvMain_Init 1028 */ 1029static void drvMain_InitLocals (TDrvMain *pDrvMain) 1030{ 1031 /* Initialize the module's local varniables to default values */ 1032 pDrvMain->tFileInfo.eFileType = FILE_TYPE_INI; 1033 pDrvMain->tFileInfo.fCbFunc = drvMain_GetFileCb; 1034 pDrvMain->tFileInfo.hCbHndl = (TI_HANDLE)pDrvMain; 1035 pDrvMain->eSmState = SM_STATE_IDLE; 1036 pDrvMain->uPendingEventsCount = 0; 1037 pDrvMain->bRecovery = TI_FALSE; 1038 pDrvMain->eAction = ACTION_TYPE_NONE; 1039 1040 /* Register the Action callback to the context engine and get the client ID */ 1041 pDrvMain->uContextId = context_RegisterClient (pDrvMain->tStadHandles.hContext, 1042 drvMain_InvokeAction, 1043 (TI_HANDLE)pDrvMain, 1044 TI_TRUE, 1045 "ACTION", 1046 sizeof("ACTION")); 1047 1048 /* Platform specific HW preparations */ 1049 hPlatform_Wlan_Hardware_Init(pDrvMain->tStadHandles.hOs); 1050 1051 /* Insure that device power is off (expected to be) */ 1052 hPlatform_DevicePowerOff(); 1053} 1054 1055 1056/* 1057 * \fn drvMain_InitHw & drvMain_InitFw 1058 * \brief Init HW and Init FW sequences 1059 * 1060 * drvMain_InitHw - HW init sequence which writes and reads some HW registers 1061 * that are needed prior to FW download. 1062 * drvMain_InitFw - FW init sequence which downloads the FW image and waits for 1063 * FW init-complete indication. 1064 * 1065 * \note 1066 * \param hDrvMain - The DrvMain object 1067 * \param pBuf - The file data (NVS for HW-init, FW-Image for FW-init). 1068 * \param uLength - The file length. 1069 * \return TI_OK if succeeded, TI_NOK if failed. 1070 * \sa 1071 */ 1072static TI_STATUS drvMain_InitHw (TI_HANDLE hDrvMain, TI_UINT8 *pbuf, TI_UINT32 uLength) 1073{ 1074 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1075 1076 return TWD_InitHw (pDrvMain->tStadHandles.hTWD, pbuf, uLength); 1077} 1078 1079static TI_STATUS drvMain_InitFw (TI_HANDLE hDrvMain, TFileInfo *pFileInfo) 1080{ 1081 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1082 1083 return TWD_InitFw (pDrvMain->tStadHandles.hTWD, pFileInfo); 1084} 1085 1086 1087/* 1088 * \fn drvMain_ConfigFw 1089 * \brief Configure the FW 1090 * 1091 * The step that follows the FW Init (mainly FW download). 1092 * The Command-Mailbox interface is enabled here and the FW is configured. 1093 * 1094 * \note 1095 * \param pDrvMain - The DrvMain object 1096 * \return TI_OK 1097 * \sa drvMain_Init 1098 */ 1099static TI_STATUS drvMain_ConfigFw (TI_HANDLE hDrvMain) 1100{ 1101 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1102 1103 /* get pointer to FW static info (already in driver memory) */ 1104 TFwInfo *pFwInfo = TWD_GetFWInfo (pDrvMain->tStadHandles.hTWD); 1105 TI_UINT8 *pMacAddr = (TI_UINT8 *)pFwInfo->macAddress; /* STA MAC address */ 1106 1107 /* Update driver's MAC address */ 1108 wlanDrvIf_SetMacAddress (pDrvMain->tStadHandles.hOs, pMacAddr); 1109 1110 /* 1111 * Exit from init mode should be before smeSM starts. this enable us to send 1112 * command to the MboxQueue(that store the command) while the interrupts are masked. 1113 * the interrupt would be enable at the end of the init process. 1114 */ 1115 TWD_ExitFromInitMode (pDrvMain->tStadHandles.hTWD); 1116 1117 /* Configure the FW from the TWD DB */ 1118 TWD_ConfigFw (pDrvMain->tStadHandles.hTWD); 1119 1120 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_INIT , "EXIT FROM INIT\n"); 1121 1122 /* Print the driver and firmware version and the mac address */ 1123 WLAN_OS_REPORT(("\n")); 1124 WLAN_OS_REPORT(("--------------------------------------------------------------------\n")); 1125 WLAN_OS_REPORT(("Driver Version : %s\n", SW_VERSION_STR)); 1126 WLAN_OS_REPORT(("Firmware Version: %s\n", pFwInfo->fwVer)); 1127 WLAN_OS_REPORT(("Station ID : %02X-%02X-%02X-%02X-%02X-%02X\n", 1128 pMacAddr[0], pMacAddr[1], pMacAddr[2], pMacAddr[3], pMacAddr[4], pMacAddr[5])); 1129 WLAN_OS_REPORT(("--------------------------------------------------------------------\n")); 1130 WLAN_OS_REPORT(("\n")); 1131 1132 return TI_OK; 1133} 1134 1135 1136/* 1137 * \fn drvMain_StopActivities 1138 * \brief Freeze driver activities 1139 * 1140 * Freeze all driver activities due to stop command or recovery process. 1141 * 1142 * \note 1143 * \param pDrvMain - The DrvMain object 1144 * \return TI_OK if succeeded, TI_NOK if failed. 1145 * \sa drvMain_EnableActivities 1146 */ 1147static TI_STATUS drvMain_StopActivities (TDrvMain *pDrvMain) 1148{ 1149 txPort_suspendTx (pDrvMain->tStadHandles.hTxPort); 1150 1151 /* Disable External Inputs (IRQs and commands) */ 1152 TWD_DisableInterrupts(pDrvMain->tStadHandles.hTWD); 1153 cmdHndlr_Disable (pDrvMain->tStadHandles.hCmdHndlr); 1154 1155 /* Initiate TWD Restart */ 1156 return TWD_Stop (pDrvMain->tStadHandles.hTWD); 1157} 1158 1159 1160/* 1161 * \fn drvMain_EnableActivities 1162 * \brief Enable driver activities 1163 * 1164 * Enable driver activities after init or recovery process completion. 1165 * 1166 * \note 1167 * \param pDrvMain - The DrvMain object 1168 * \return void 1169 * \sa drvMain_StopActivities 1170 */ 1171static void drvMain_EnableActivities (TDrvMain *pDrvMain) 1172{ 1173 txPort_resumeTx (pDrvMain->tStadHandles.hTxPort); 1174 1175 /* Enable External Inputs (IRQ is enabled elsewhere) */ 1176 cmdHndlr_Enable (pDrvMain->tStadHandles.hCmdHndlr); 1177 1178 /* Enable external events from FW */ 1179 TWD_EnableExternalEvents (pDrvMain->tStadHandles.hTWD); 1180 1181 1182} 1183 1184 1185/* 1186 * \fn drvMain_ClearQueuedEvents 1187 * \brief Enable driver activities 1188 * 1189 * Clear all external events queues (Tx, commands and timers) upon driver stop. 1190 * 1191 * \note 1192 * \param pDrvMain - The DrvMain object 1193 * \return void 1194 * \sa 1195 */ 1196static void drvMain_ClearQueuedEvents (TDrvMain *pDrvMain) 1197{ 1198 txDataQ_ClearQueues (pDrvMain->tStadHandles.hTxDataQ); 1199 txMgmtQ_ClearQueues (pDrvMain->tStadHandles.hTxMgmtQ); 1200 cmdHndlr_ClearQueue (pDrvMain->tStadHandles.hCmdHndlr); 1201 tmr_ClearOperQueue (pDrvMain->tStadHandles.hTimer); 1202} 1203 1204 1205/* 1206 * \fn drvMain_InsertAction 1207 * \brief Get start/stop action and trigger handling 1208 * 1209 * Get start or stop action command from OAL, save it and trigger driver task 1210 * for handling it. 1211 * Wait on a signal object until the requested process is completed. 1212 * 1213 * \note 1214 * \param hDrvMain - The DrvMain object 1215 * \param eAction - The requested action 1216 * \return void 1217 * \sa 1218 */ 1219TI_STATUS drvMain_InsertAction (TI_HANDLE hDrvMain, EActionType eAction) 1220{ 1221 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1222 1223 if (pDrvMain->eAction == eAction) 1224 { 1225 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE, "Action is identical to last action!\n"); 1226 WLAN_OS_REPORT(("Action is identical to last action!\n")); 1227 return TI_NOK; 1228 } 1229 1230 /* Save the requested action */ 1231 pDrvMain->eAction = eAction; 1232 1233 /* Create signal object */ 1234 /* 1235 * Notice that we must create the signal object before asking for ReSchedule, 1236 * because we might receive it immidiatly, and then we will be in a different context 1237 * with null signal object. 1238 */ 1239 pDrvMain->hSignalObj = os_SignalObjectCreate (pDrvMain->tStadHandles.hOs); 1240 if (pDrvMain->hSignalObj == NULL) 1241 { 1242 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_InsertAction(): Couldn't allocate signal object!\n"); 1243 return TI_NOK; 1244 } 1245 1246 /* Request driver task schedule for action handling */ 1247 context_RequestSchedule (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1248 1249 /* Wait for the action processing completion */ 1250 os_SignalObjectWait (pDrvMain->tStadHandles.hOs, pDrvMain->hSignalObj); 1251 1252 /* After "wait" - the action has already been processed in the driver's context */ 1253 1254 /* Free signalling object */ 1255 os_SignalObjectFree (pDrvMain->tStadHandles.hOs, pDrvMain->hSignalObj); 1256 1257 if (pDrvMain->eSmState == SM_STATE_FAILED) 1258 return TI_NOK; 1259 1260 return TI_OK; 1261} 1262 1263 1264/* 1265 * \fn drvMain_Recovery 1266 * \brief Initiate recovery process 1267 * 1268 * Initiate recovery process upon HW/FW error detection (in the Health-Monitor). 1269 * 1270 * \note 1271 * \param hDrvMain - The DrvMain object 1272 * \return TI_OK if started recovery, TI_NOK if recovery is already in progress. 1273 * \sa 1274 */ 1275TI_STATUS drvMain_Recovery (TI_HANDLE hDrvMain) 1276{ 1277 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1278 1279 if (!pDrvMain->bRecovery) 1280 { 1281 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE,".....drvMain_Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs)); 1282 WLAN_OS_REPORT((".....drvMain_Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs))); 1283 pDrvMain->bRecovery = TI_TRUE; 1284 drvMain_SmEvent (hDrvMain, SM_EVENT_RECOVERY); 1285 return TI_OK; 1286 } 1287 else 1288 { 1289 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR, "drvMain_Recovery: **** Recovery already in progress! ****\n"); 1290 return TI_NOK; 1291 } 1292} 1293 1294 1295/* 1296 * \fn drvMain_RecoveryNotify 1297 * \brief Notify STAD modules about recovery 1298 * 1299 * Notify the relevant STAD modules that recovery took place (after completed). 1300 * 1301 * \note 1302 * \param pDrvMain - The DrvMain object 1303 * \return void 1304 * \sa 1305 */ 1306static void drvMain_RecoveryNotify (TDrvMain *pDrvMain) 1307{ 1308 txCtrl_NotifyFwReset (pDrvMain->tStadHandles.hTxCtrl); 1309 scr_notifyFWReset (pDrvMain->tStadHandles.hSCR); 1310 PowerMgr_notifyFWReset (pDrvMain->tStadHandles.hPowerMgr); 1311 1312 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE, ".....drvMain_RecoveryNotify: End Of Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs)); 1313 WLAN_OS_REPORT((".....drvMain_RecoveryNotify: End Of Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs))); 1314} 1315 1316 1317/* 1318 * \fn drvMain_SmWatchdogTimeout 1319 * \brief SM watchdog timer expiry handler 1320 * 1321 * This is the callback function called upon expiartion of the watchdog timer. 1322 * It is called by the OS-API in timer expiry context, and it issues a failure event to the SM. 1323 * Note that we can't switch to the driver task as for other timers, since we are using 1324 * this timer to protect the init processes, and anyway we just need to stop the driver. 1325 * 1326 * \note 1327 * \param hDrvMain - The DrvMain object 1328 * \return void 1329 * \sa 1330 */ 1331 1332#if 0 1333static void drvMain_SmWatchdogTimeout (TI_HANDLE hDrvMain) 1334{ 1335 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 1336 1337 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_SmWatchdogTimeout(): State = %d\n", pDrvMain->eSmState); 1338 1339 /* Send failure event directly to the SM (so the drvMain_SmEvent won't block it). */ 1340 1341 drvMain_Sm ((TI_HANDLE)pDrvMain, SM_EVENT_FAILURE); 1342} 1343#endif 1344 1345/* 1346 * \fn drvMain_SmEvent 1347 * \brief Issue DrvMain SM event 1348 * 1349 * Each event that is handled by the DrvMain state machine, is introduced through this function. 1350 * To prevent SM recursion, the SM is invoeked only if it's not already handling the 1351 * previous event. 1352 * If the SM is busy, the current event is saved until the previous handling is completed. 1353 * 1354 * \note Recursion may happen because some SM activities generate SM events in the same context. 1355 * \param hDrvMain - The DrvMain object 1356 * \param eEvent - The event issued to the SM 1357 * \return void 1358 * \sa 1359 */ 1360static void drvMain_SmEvent (TI_HANDLE hDrvMain, ESmEvent eEvent) 1361{ 1362 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 1363 1364 /* Increment pending events counter and save last event. */ 1365 pDrvMain->uPendingEventsCount++; 1366 pDrvMain->ePendingEvent = eEvent; 1367 1368 /* If the SM is busy, save event and exit (will be handled when current event is finished) */ 1369 if (pDrvMain->uPendingEventsCount > 1) 1370 { 1371 /* Only one pending event is expected (in addition to the handled one, so two together). */ 1372 if (pDrvMain->uPendingEventsCount > 2) 1373 { 1374 TRACE3(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_SmEvent(): Multiple pending events (%d), State = %d, Event = %d\n", pDrvMain->uPendingEventsCount, pDrvMain->eSmState, eEvent); 1375 } 1376 1377 /* Exit. The current event will be handled by the following while loop of the first instance. */ 1378 return; 1379 } 1380 1381 /* Invoke the SM with the current event and further events issued by the last SM invocation. */ 1382 while (pDrvMain->uPendingEventsCount > 0) 1383 { 1384 drvMain_Sm (hDrvMain, pDrvMain->ePendingEvent); 1385 1386 /* 1387 * Note: The SM may issue another event by calling this function and incrementing 1388 * the counter. 1389 * In this case, only the upper part of this function is run, and the pending 1390 * event is hanlded in the next while loo[. 1391 */ 1392 1393 pDrvMain->uPendingEventsCount--; 1394 } 1395} 1396 1397 1398/* 1399 * \fn drvMain_Sm 1400 * \brief The DrvMain state machine 1401 * 1402 * The DrvMain state machine, which handles all driver init, recovery and stop processes. 1403 * 1404 * \note Since the SM may be called back from its own context, recursion is prevented 1405 * by postponing the last event. 1406 * \param hDrvMain - The DrvMain object 1407 * \param eEvent - The event that triggers the SM 1408 * \return void 1409 * \sa 1410 */ 1411static void drvMain_Sm (TI_HANDLE hDrvMain, ESmEvent eEvent) 1412{ 1413 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 1414 TI_STATUS eStatus = TI_NOK; 1415 TI_HANDLE hOs = pDrvMain->tStadHandles.hOs; 1416 1417 TRACE2(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_INFORMATION , "drvMain_Sm(): State = %d, Event = %d\n", pDrvMain->eSmState, eEvent); 1418 1419 /* 1420 * General explenations: 1421 * ===================== 1422 * 1) This SM calls some functions that may complete their processing in another context. 1423 * All of these functions (wlanDrvIf_GetFile, drvMain_InitHw, drvMain_InitFw, drvMain_ConfigFw, 1424 * drvMain_StopActivities, smeSm_start, smeSm_stop) are provided with a callback which 1425 * they always call upon completion, even if they are completed in the original (SM) context. 1426 * Since these callbacks are calling the SM, a simple mechanism is added to prevent 1427 * recursion, by postponing the last event if the SM is still in the previous event's context. 1428 * 2) In any case of unexpected event, the eStatus remains TI_NOK, leading to the FAILED state! 1429 * FAILED state is also reached if any of the functions listed in note 1 returns TI_NOK. 1430 * Note that if these functions detect a failure in another context, they may call their callback 1431 * with the eStatus parameter set to TI_NOK, or call the drvMain_InitFailCb callback. 1432 * All these cases lead to FAILED state which terminates all driver activities and wait for destroy. 1433 * 3) Note that the wlanDrvIf_GetFile is always completed in the original context, and the 1434 * option of completion in a later context is only for future use. 1435 * 4) All processes (Start, Stop, Relcovery) are protected by a watchdog timer to let 1436 * the user free the driver in case of deadlock during the process. 1437 */ 1438 1439 switch (pDrvMain->eSmState) 1440 { 1441 case SM_STATE_IDLE: 1442 /* 1443 * We get a START action after all modules are created and linked. 1444 * Disable further actions, start watchdog timer and request for the ini-file. 1445 */ 1446 if (eEvent == SM_EVENT_START) 1447 { 1448 /* return thr timer later on */ 1449 /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/ 1450 pDrvMain->eSmState = SM_STATE_WAIT_INI_FILE; 1451 context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1452 pDrvMain->tFileInfo.eFileType = FILE_TYPE_INI; 1453 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1454 } 1455 break; 1456 case SM_STATE_WAIT_INI_FILE: 1457 /* 1458 * We've got the ini-file. 1459 * Set STAD and TWD modules defaults according to the ini-file, 1460 * turn on the device and request for the NVS file. 1461 */ 1462 if (eEvent == SM_EVENT_INI_FILE_READY) 1463 { 1464 pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE; 1465 drvMain_SetDefaults (hDrvMain, pDrvMain->tFileInfo.pBuffer, pDrvMain->tFileInfo.uLength); 1466 hPlatform_DevicePowerOn (); 1467 1468 pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS; 1469 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1470 } 1471 break; 1472 1473 case SM_STATE_WAIT_NVS_FILE: 1474 1475 /* : We should split the call to txnQ_ConnectBus to other state in order to support Async bus connection */ 1476 eStatus = txnQ_ConnectBus(pDrvMain->tStadHandles.hTxnQ, &pDrvMain->tBusDrvCfg, NULL, NULL); 1477 1478 if(eStatus != TI_OK) 1479 { 1480 WLAN_OS_REPORT(("SDBus Connect Failed, Set Object Event !!\r\n")); 1481 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "SDBus Connect Failed, Set Object Event !!\r\n"); 1482 os_SignalObjectSet (hOs, pDrvMain->hSignalObj); 1483 break; 1484 } 1485 1486 /* 1487 * We've got the NVS file. 1488 * Start HW-Init process providing the NVS file. 1489 */ 1490 if (eEvent == SM_EVENT_NVS_FILE_READY) 1491 { 1492 pDrvMain->eSmState = SM_STATE_HW_INIT; 1493 eStatus = drvMain_InitHw (hDrvMain, pDrvMain->tFileInfo.pBuffer, pDrvMain->tFileInfo.uLength); 1494 } 1495 break; 1496 case SM_STATE_HW_INIT: 1497 /* 1498 * HW-Init process is completed. 1499 * Request for the FW image file. 1500 */ 1501 if (eEvent == SM_EVENT_HW_INIT_COMPLETE) 1502 { 1503 pDrvMain->tFileInfo.eFileType = FILE_TYPE_FW; 1504 pDrvMain->eSmState = SM_STATE_DOWNLOAD_FW_FILE; 1505 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1506 } 1507 break; 1508 case SM_STATE_DOWNLOAD_FW_FILE: 1509 if (eEvent == SM_EVENT_FW_FILE_READY) 1510 { 1511 pDrvMain->tFileInfo.eFileType = FILE_TYPE_FW_NEXT; 1512 if (pDrvMain->tFileInfo.bLast == TI_TRUE) 1513 { 1514 pDrvMain->eSmState = SM_STATE_FW_INIT; 1515 } 1516 else 1517 { 1518 pDrvMain->eSmState = SM_STATE_WAIT_FW_FILE; 1519 } 1520 /* 1521 * We've got the FW image file. 1522 * Start FW-Init process (mainly FW image download) providing the FW image file. 1523 */ 1524 eStatus = drvMain_InitFw (hDrvMain, &pDrvMain->tFileInfo); 1525 } 1526 break; 1527 case SM_STATE_WAIT_FW_FILE: 1528 if (eEvent == SM_EVENT_FW_INIT_COMPLETE) 1529 { 1530 pDrvMain->eSmState = SM_STATE_DOWNLOAD_FW_FILE; 1531 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1532 } 1533 break; 1534 case SM_STATE_FW_INIT: 1535 /* 1536 * FW-Init process is completed. 1537 * Free the semaphore of the START action to enable the OS interface. 1538 * Enable interrupts (or polling for debug). 1539 * Start FW-Configuration process, and free the semaphore of the START action. 1540 * 1541 * Note that in some OSs, the semaphore must be released in order to enable the 1542 * interrupts, and the interrupts are needed for the configuration process! 1543 */ 1544 if (eEvent == SM_EVENT_FW_INIT_COMPLETE) 1545 { 1546 pDrvMain->eSmState = SM_STATE_FW_CONFIG; 1547 if (!pDrvMain->bRecovery) 1548 { 1549 os_SignalObjectSet (hOs, pDrvMain->hSignalObj); 1550 } 1551 TWD_EnableInterrupts(pDrvMain->tStadHandles.hTWD); 1552 #ifdef PRIODIC_INTERRUPT 1553 /* Start periodic interrupts. It means that every period of time the FwEvent SM will be called */ 1554 os_periodicIntrTimerStart (hOs); 1555 #endif 1556 eStatus = drvMain_ConfigFw (hDrvMain); 1557 } 1558 break; 1559 case SM_STATE_FW_CONFIG: 1560 /* 1561 * FW-configuration process is completed. 1562 * Stop watchdog timer. 1563 * For recovery, notify the relevant STAD modules. 1564 * For regular start, start the SME which handles the connection process. 1565 * Update timer and OAL about entering OPERATIONAL state (OAL ignores recovery) 1566 * Enable driver activities and external events. 1567 * Enable STOP action 1568 * We are now in OPERATIONAL state, i.e. the driver is fully operational! 1569 */ 1570 1571 if (eEvent == SM_EVENT_FW_CONFIG_COMPLETE) 1572 { 1573 pDrvMain->eSmState = SM_STATE_OPERATIONAL; 1574 /* return thr timer later on */ 1575 /*os_timerStop (hOs, pDrvMain->hWatchdogTimer);*/ 1576 if (pDrvMain->bRecovery) 1577 { 1578 drvMain_RecoveryNotify (pDrvMain); 1579 pDrvMain->bRecovery = TI_FALSE; 1580 } 1581 else 1582 { 1583 sme_Start (pDrvMain->tStadHandles.hSme); 1584 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_RUNNING); 1585 } 1586 tmr_UpdateDriverState (pDrvMain->tStadHandles.hTimer, TI_TRUE); 1587 drvMain_EnableActivities (pDrvMain); 1588 context_EnableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1589 eStatus = TI_OK; 1590 1591 } 1592 break; 1593 case SM_STATE_OPERATIONAL: 1594 /* 1595 * Disable start/stop commands and start watchdog timer. 1596 * Update timer and OAL about exiting OPERATIONAL state (OAL ignores recovery). 1597 * For STOP, stop SME (handle disconnection) and move to DISCONNECTING state. 1598 * For recovery, stop driver activities and move to STOPPING state. 1599 * Note that driver-stop process may be Async if we are during Async bus transaction. 1600 */ 1601 1602 context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1603 /* return thr timer later on */ 1604 /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/ 1605 tmr_UpdateDriverState (pDrvMain->tStadHandles.hTimer, TI_FALSE); 1606 if (eEvent == SM_EVENT_STOP) 1607 { 1608 pDrvMain->eSmState = SM_STATE_DISCONNECTING; 1609 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_STOPING); 1610 sme_Stop (pDrvMain->tStadHandles.hSme); 1611 eStatus = TI_OK; 1612 } 1613 else if (eEvent == SM_EVENT_RECOVERY) 1614 { 1615 pDrvMain->eSmState = SM_STATE_STOPPING; 1616 eStatus = drvMain_StopActivities (pDrvMain); 1617 } 1618 1619 break; 1620 case SM_STATE_DISCONNECTING: 1621 /* 1622 * Note that this state is not relevant for recovery. 1623 * SME stop is completed 1624 * Stop driver activities and move to STOPPING state. 1625 * Note that driver stop process may be Async if we are during Async bus transaction. 1626 */ 1627 1628 if (eEvent == SM_EVENT_DISCONNECTED) 1629 { 1630 pDrvMain->eSmState = SM_STATE_STOPPING; 1631 eStatus = drvMain_StopActivities (pDrvMain); 1632 } 1633 break; 1634 case SM_STATE_STOPPING: 1635 /* 1636 * Driver stopping process is done. 1637 * Turn device power off. 1638 * For recovery, turn device power back on, request NVS file and continue with 1639 * the init process (recover back all the way to OPERATIONAL state). 1640 * For STOP process, the driver is now fully stopped (STOPPED state), so stop watchdog timer, 1641 * clear all events queues, free the semaphore of the STOP action and enable START action. 1642 */ 1643 1644 if (eEvent == SM_EVENT_STOP_COMPLETE) 1645 { 1646 txnQ_DisconnectBus (pDrvMain->tStadHandles.hTxnQ); 1647 hPlatform_DevicePowerOff (); 1648 if (pDrvMain->bRecovery) 1649 { 1650 hPlatform_DevicePowerOn (); 1651 pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE; 1652 pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS; 1653 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1654 } 1655 else 1656 { 1657 pDrvMain->eSmState = SM_STATE_STOPPED; 1658 /* return thr timer later on */ 1659 /*os_timerStop (hOs, pDrvMain->hWatchdogTimer);*/ 1660 drvMain_ClearQueuedEvents (pDrvMain); 1661 os_SignalObjectSet (hOs, pDrvMain->hSignalObj); 1662 context_EnableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1663 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_STOPPED); 1664 eStatus = TI_OK; 1665 } 1666 } 1667 1668 break; 1669 case SM_STATE_STOPPED: 1670 /* 1671 * A START action command was inserted, so we go through the init process. 1672 * Disable further actions, start watchdog timer, turn on device and request NVS file. 1673 */ 1674 1675 context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1676 /* return thr timer later on */ 1677 /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/ 1678 if (eEvent == SM_EVENT_START) 1679 { 1680 hPlatform_DevicePowerOn (); 1681 pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE; 1682 pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS; 1683 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1684 } 1685 break; 1686 case SM_STATE_STOPPING_ON_FAIL: 1687 /* 1688 * Driver stopping process upon failure is completed. 1689 * Turn off the device and move to FAILED state. 1690 */ 1691 1692 pDrvMain->eSmState = SM_STATE_FAILED; 1693 txnQ_DisconnectBus (pDrvMain->tStadHandles.hTxnQ); 1694 hPlatform_DevicePowerOff (); 1695 WLAN_OS_REPORT(("[WLAN] Exit application\n")); 1696 os_SignalObjectSet (hOs, pDrvMain->hSignalObj); 1697 break; 1698 case SM_STATE_FAILED: 1699 /* Nothing to do except waiting for Destroy */ 1700 break; 1701 default: 1702 TRACE2(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_Sm: Unknown state, eEvent=%u at state=%u\n", eEvent, pDrvMain->eSmState); 1703 /* Note: Handled below as a failure since the status remains TI_NOK */ 1704 break; 1705 } 1706 1707 /* Handle failures (status = NOK) if not handled yet */ 1708 if ((eStatus == TI_NOK) && 1709 (pDrvMain->eSmState != SM_STATE_FAILED) && 1710 (pDrvMain->eSmState != SM_STATE_STOPPING_ON_FAIL)) 1711 { 1712 TRACE3(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_Sm: eEvent=%u at state=%u, status=%d\n", eEvent, pDrvMain->eSmState, eStatus); 1713 pDrvMain->eSmState = SM_STATE_STOPPING_ON_FAIL; 1714 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_FAILED); 1715 1716 /* 1717 * Stop all activities. This may be completed in a different context if 1718 * we should wait for an Async bus transaction completion. 1719 * The drvMain_TwdStopCb is called from the TWD in any case to pass 1720 * us to the SM_STATE_FAILED state (where we wait for Destroy). 1721 */ 1722 eStatus = drvMain_StopActivities (pDrvMain); 1723 } 1724} 1725 1726 1727 1728