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