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 */ 91 typedef 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 */ 111 typedef 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 */ 129 typedef 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 146 static void drvMain_Init (TI_HANDLE hDrvMain); 147 static void drvMain_InitHwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus); 148 static void drvMain_InitFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus); 149 static void drvMain_ConfigFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus); 150 static void drvMain_TwdStopCb (TI_HANDLE hDrvMain, TI_STATUS eStatus); 151 static void drvMain_InitFailCb (TI_HANDLE hDrvMain, TI_STATUS eStatus); 152 static void drvMain_InitLocals (TDrvMain *pDrvMain); 153 /* static void drvMain_SmWatchdogTimeout (TI_HANDLE hDrvMain); */ 154 static void drvMain_SmEvent (TI_HANDLE hDrvMain, ESmEvent eEvent); 155 static 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 */ 172 extern 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 */ 184 extern 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 */ 196 extern 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 */ 210 extern 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 */ 234 TI_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 * \fn drvMain_Destroy 555 * \brief Destroy driver 556 * 557 * Destroy all STAD and TWD modules and resources. 558 * 559 * \note 560 * \param hDrvMain - The DrvMain object 561 * \return TI_OK if succeeded, TI_NOK if failed. 562 * \sa drvMain_Create 563 */ 564 TI_STATUS drvMain_Destroy (TI_HANDLE hDrvMain) 565 { 566 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 567 568 hPlatform_Wlan_Hardware_DeInit (); 569 570 if (pDrvMain == NULL) 571 { 572 return TI_NOK; 573 } 574 575 if (pDrvMain->tStadHandles.hScanMngr != NULL) 576 { 577 scanMngr_unload (pDrvMain->tStadHandles.hScanMngr); 578 } 579 580 if (pDrvMain->tStadHandles.hSiteMgr != NULL) 581 { 582 siteMgr_unLoad (pDrvMain->tStadHandles.hSiteMgr); 583 } 584 585 if (pDrvMain->tStadHandles.hSme != NULL) 586 { 587 sme_Destroy (pDrvMain->tStadHandles.hSme); 588 } 589 590 if (pDrvMain->tStadHandles.hConn != NULL) 591 { 592 conn_unLoad (pDrvMain->tStadHandles.hConn); 593 } 594 595 if (pDrvMain->tStadHandles.hTWD != NULL) 596 { 597 TWD_Destroy (pDrvMain->tStadHandles.hTWD); 598 } 599 600 if (pDrvMain->tStadHandles.hScanCncn != NULL) 601 { 602 scanCncn_Destroy (pDrvMain->tStadHandles.hScanCncn); 603 } 604 605 if (pDrvMain->tStadHandles.hTrafficMon != NULL) 606 { 607 TrafficMonitor_Destroy (pDrvMain->tStadHandles.hTrafficMon); 608 } 609 610 if (pDrvMain->tStadHandles.hCtrlData != NULL) 611 { 612 ctrlData_unLoad (pDrvMain->tStadHandles.hCtrlData); 613 } 614 615 if (pDrvMain->tStadHandles.hTxCtrl != NULL) 616 { 617 txCtrl_Unload (pDrvMain->tStadHandles.hTxCtrl); 618 } 619 620 if (pDrvMain->tStadHandles.hTxDataQ != NULL) 621 { 622 txDataQ_Destroy (pDrvMain->tStadHandles.hTxDataQ); 623 } 624 625 if (pDrvMain->tStadHandles.hTxMgmtQ != NULL) 626 { 627 txMgmtQ_Destroy (pDrvMain->tStadHandles.hTxMgmtQ); 628 } 629 630 if (pDrvMain->tStadHandles.hTxPort != NULL) 631 { 632 txPort_unLoad (pDrvMain->tStadHandles.hTxPort); 633 } 634 635 if (pDrvMain->tStadHandles.hRxData != NULL) 636 { 637 rxData_unLoad (pDrvMain->tStadHandles.hRxData); 638 } 639 640 if (pDrvMain->tStadHandles.hAssoc != NULL) 641 { 642 assoc_unload (pDrvMain->tStadHandles.hAssoc); 643 } 644 645 if (pDrvMain->tStadHandles.hAuth != NULL) 646 { 647 auth_unload (pDrvMain->tStadHandles.hAuth); 648 } 649 650 if (pDrvMain->tStadHandles.hMlmeSm != NULL) 651 { 652 mlme_unload (pDrvMain->tStadHandles.hMlmeSm); 653 } 654 655 if (pDrvMain->tStadHandles.hSCR != NULL) 656 { 657 scr_release (pDrvMain->tStadHandles.hSCR); 658 } 659 660 if (pDrvMain->tStadHandles.hTxnQ != NULL) 661 { 662 txnQ_Destroy (pDrvMain->tStadHandles.hTxnQ); 663 } 664 665 if (pDrvMain->tStadHandles.hRsn != NULL) 666 { 667 rsn_unload (pDrvMain->tStadHandles.hRsn); 668 } 669 670 if (pDrvMain->tStadHandles.hRegulatoryDomain != NULL) 671 { 672 regulatoryDomain_destroy (pDrvMain->tStadHandles.hRegulatoryDomain); 673 } 674 675 if (pDrvMain->tStadHandles.hMeasurementMgr != NULL) 676 { 677 measurementMgr_destroy (pDrvMain->tStadHandles.hMeasurementMgr); 678 } 679 680 if (pDrvMain->tStadHandles.hSoftGemini != NULL) 681 { 682 SoftGemini_destroy (pDrvMain->tStadHandles.hSoftGemini); 683 } 684 685 #ifdef XCC_MODULE_INCLUDED 686 if (pDrvMain->tStadHandles.hXCCMngr != NULL) 687 { 688 XCCMngr_unload (pDrvMain->tStadHandles.hXCCMngr); 689 } 690 #endif 691 692 if (pDrvMain->tStadHandles.hRoamingMngr != NULL) 693 { 694 roamingMngr_unload (pDrvMain->tStadHandles.hRoamingMngr); 695 } 696 697 if (pDrvMain->tStadHandles.hQosMngr != NULL) 698 { 699 qosMngr_destroy (pDrvMain->tStadHandles.hQosMngr); 700 } 701 702 if (pDrvMain->tStadHandles.hPowerMgr != NULL) 703 { 704 PowerMgr_destroy (pDrvMain->tStadHandles.hPowerMgr); 705 } 706 707 if (pDrvMain->tStadHandles.hAPConnection != NULL) 708 { 709 apConn_unload (pDrvMain->tStadHandles.hAPConnection); 710 } 711 712 if (pDrvMain->tStadHandles.hCurrBss != NULL) 713 { 714 currBSS_unload (pDrvMain->tStadHandles.hCurrBss); 715 } 716 717 if (pDrvMain->tStadHandles.hSwitchChannel != NULL) 718 { 719 switchChannel_unload (pDrvMain->tStadHandles.hSwitchChannel); 720 } 721 722 if (pDrvMain->tStadHandles.hHealthMonitor != NULL) 723 { 724 healthMonitor_unload (pDrvMain->tStadHandles.hHealthMonitor); 725 } 726 727 if (pDrvMain->tStadHandles.hCmdHndlr && pDrvMain->tStadHandles.hEvHandler) 728 { 729 cmdHndlr_Destroy (pDrvMain->tStadHandles.hCmdHndlr, pDrvMain->tStadHandles.hEvHandler); 730 } 731 732 if (pDrvMain->tStadHandles.hEvHandler != NULL) 733 { 734 EvHandlerUnload (pDrvMain->tStadHandles.hEvHandler); 735 } 736 737 if (pDrvMain->tStadHandles.hCmdDispatch) 738 { 739 cmdDispatch_Destroy (pDrvMain->tStadHandles.hCmdDispatch); 740 } 741 742 /* Note: The Timer module must be destroyed last, so all created timers are already destroyed!! */ 743 if (pDrvMain->tStadHandles.hTimer != NULL) 744 { 745 tmr_Destroy (pDrvMain->tStadHandles.hTimer); 746 } 747 748 /* Destroy the SM watchdog timer */ 749 if (pDrvMain->hWatchdogTimer != NULL) 750 { 751 os_timerDestroy (pDrvMain->tStadHandles.hOs, pDrvMain->hWatchdogTimer); 752 } 753 754 /* Note: Moved after timers for locks */ 755 if (pDrvMain->tStadHandles.hContext != NULL) 756 { 757 context_Destroy (pDrvMain->tStadHandles.hContext); 758 } 759 760 if (pDrvMain->tStadHandles.hStaCap != NULL) 761 { 762 StaCap_Destroy (pDrvMain->tStadHandles.hStaCap); 763 } 764 765 if (pDrvMain->tStadHandles.hReport != NULL) 766 { 767 report_Unload (pDrvMain->tStadHandles.hReport); 768 } 769 770 /* Destroy the DrvMain object */ 771 os_memoryFree (pDrvMain->tStadHandles.hOs, hDrvMain, sizeof(TDrvMain)); 772 773 return TI_OK; 774 } 775 776 void drvMain_SmeStop (TI_HANDLE hDrvMain) 777 { 778 drvMain_SmEvent (hDrvMain, SM_EVENT_DISCONNECTED); 779 } 780 781 782 /* 783 * \fn drvMain_Init 784 * \brief Init driver modules 785 * 786 * Called from OS context following the driver creation. 787 * Calls all STAD and TWD modules Init functions, which are saving other modules handles, 788 * registering to other modules and initializing their variables. 789 * 790 * \note 791 * \param hDrvMain - The DrvMain object 792 * \return void 793 * \sa drvMain_Create 794 */ 795 static void drvMain_Init (TI_HANDLE hDrvMain) 796 { 797 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 798 TStadHandlesList *pModules = &pDrvMain->tStadHandles; /* The STAD modules handles list */ 799 800 /* 801 * Init all modules handles, variables and registries 802 */ 803 context_Init (pModules->hContext, pModules->hOs, pModules->hReport); 804 tmr_Init (pModules->hTimer, pModules->hOs, pModules->hReport, pModules->hContext); 805 txnQ_Init (pModules->hTxnQ, pModules->hOs, pModules->hReport, pModules->hContext); 806 scr_init (pModules); 807 conn_init (pModules); 808 ctrlData_init (pModules, 809 #ifdef XCC_MODULE_INCLUDED 810 XCCMngr_LinkTestRetriesUpdate, pModules->hXCCMngr); 811 #else 812 NULL, NULL); 813 #endif 814 siteMgr_init (pModules); 815 regulatoryDomain_init (pModules); 816 scanCncn_Init (pModules); 817 auth_init (pModules); 818 mlme_init (pModules); 819 assoc_init (pModules); 820 rxData_init (pModules); 821 txCtrl_Init (pModules); 822 txDataQ_Init (pModules); 823 txMgmtQ_Init (pModules); 824 txPort_init (pModules); 825 TrafficMonitor_Init (pModules, 1000 /* pInitTable->trafficMonitorMinIntervalPercentage */); 826 sme_Init (pModules); 827 rsn_init (pModules); 828 measurementMgr_init (pModules); 829 #ifdef XCC_MODULE_INCLUDED 830 XCCMngr_init (pModules); 831 #endif 832 scanMngr_init (pModules); 833 currBSS_init (pModules); 834 apConn_init (pModules); 835 roamingMngr_init (pModules); 836 qosMngr_init (pModules); 837 switchChannel_init (pModules); 838 healthMonitor_init (pModules); 839 PowerMgr_init (pModules); 840 SoftGemini_init (pModules); 841 cmdDispatch_Init (pModules); 842 StaCap_Init (pModules); 843 cmdHndlr_Init (pModules); 844 845 /* Init TWD component (handles, variables and registries) and provide callbacks for next steps */ 846 TWD_Init (pModules->hTWD, 847 pModules->hReport, 848 pModules->hDrvMain, 849 pModules->hTimer, 850 pModules->hContext, 851 pModules->hTxnQ, 852 (TTwdCallback)drvMain_InitHwCb, 853 (TTwdCallback)drvMain_InitFwCb, 854 (TTwdCallback)drvMain_ConfigFwCb, 855 (TTwdCallback)drvMain_TwdStopCb, 856 (TTwdCallback)drvMain_InitFailCb); 857 858 /* Init DrvMain module local variables */ 859 drvMain_InitLocals (pDrvMain); 860 } 861 862 863 /* 864 * \fn drvMain_SetDefaults 865 * \brief Set driver default configuration 866 * 867 * Configure all STAD and TWD modules with their default settings from the ini-file. 868 * Timers creation is also done at this stage. 869 * 870 * \note 871 * \param hDrvMain - The DrvMain object 872 * \param pBuf - The ini-file data. 873 * \param uLength - The ini-file length. 874 * \return TI_OK if succeeded, TI_NOK if failed. 875 * \sa drvMain_Init 876 */ 877 static TI_STATUS drvMain_SetDefaults (TI_HANDLE hDrvMain, TI_UINT8 *pBuf, TI_UINT32 uLength) 878 { 879 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 880 TInitTable *pInitTable; 881 TI_STATUS eStatus; 882 883 pInitTable = os_memoryAlloc (pDrvMain->tStadHandles.hOs, sizeof(TInitTable)); 884 885 /* Parse defaults */ 886 eStatus = osInitTable_IniFile (pDrvMain->tStadHandles.hOs, pInitTable, (char*)pBuf, (int)uLength); 887 888 /* 889 * Configure modules with their default settings 890 */ 891 report_SetDefaults (pDrvMain->tStadHandles.hReport, &pInitTable->tReport); 892 context_SetDefaults (pDrvMain->tStadHandles.hContext, &pInitTable->tContextInitParams); 893 TWD_SetDefaults (pDrvMain->tStadHandles.hTWD, &pInitTable->twdInitParams); 894 conn_SetDefaults (pDrvMain->tStadHandles.hConn, &pInitTable->connInitParams); 895 ctrlData_SetDefaults (pDrvMain->tStadHandles.hCtrlData, &pInitTable->ctrlDataInitParams); 896 siteMgr_SetDefaults (pDrvMain->tStadHandles.hSiteMgr, &pInitTable->siteMgrInitParams); 897 regulatoryDomain_SetDefaults (pDrvMain->tStadHandles.hRegulatoryDomain, &pInitTable->regulatoryDomainInitParams); 898 scanCncn_SetDefaults (pDrvMain->tStadHandles.hScanCncn, &pInitTable->tScanCncnInitParams); 899 auth_SetDefaults (pDrvMain->tStadHandles.hAuth, &pInitTable->authInitParams); 900 assoc_SetDefaults (pDrvMain->tStadHandles.hAssoc, &pInitTable->assocInitParams); 901 rxData_SetDefaults (pDrvMain->tStadHandles.hRxData, &pInitTable->rxDataInitParams); 902 sme_SetDefaults (pDrvMain->tStadHandles.hSme, &pInitTable->tSmeModifiedInitParams, &pInitTable->tSmeInitParams); 903 rsn_SetDefaults (pDrvMain->tStadHandles.hRsn, &pInitTable->rsnInitParams); 904 measurementMgr_SetDefaults (pDrvMain->tStadHandles.hMeasurementMgr, &pInitTable->measurementInitParams); 905 #ifdef XCC_MODULE_INCLUDED 906 XCCMngr_SetDefaults (pDrvMain->tStadHandles.hXCCMngr, &pInitTable->XCCMngrParams); 907 #endif /*XCC_MODULE_INCLUDED*/ 908 apConn_SetDefaults (pDrvMain->tStadHandles.hAPConnection, &pInitTable->apConnParams); 909 qosMngr_SetDefaults (pDrvMain->tStadHandles.hQosMngr, &pInitTable->qosMngrInitParams); 910 switchChannel_SetDefaults (pDrvMain->tStadHandles.hSwitchChannel, &pInitTable->SwitchChannelInitParams); 911 healthMonitor_SetDefaults (pDrvMain->tStadHandles.hHealthMonitor, &pInitTable->healthMonitorInitParams); 912 PowerMgr_SetDefaults (pDrvMain->tStadHandles.hPowerMgr, &pInitTable->PowerMgrInitParams); 913 SoftGemini_SetDefaults (pDrvMain->tStadHandles.hSoftGemini, &pInitTable->SoftGeminiInitParams); 914 txDataQ_SetDefaults (pDrvMain->tStadHandles.hTxDataQ, &pInitTable->txDataInitParams); 915 txCtrl_SetDefaults (pDrvMain->tStadHandles.hTxCtrl, &pInitTable->txDataInitParams); 916 currBSS_SetDefaults (pDrvMain->tStadHandles.hCurrBss, &pInitTable->tCurrBssInitParams); 917 mlme_SetDefaults (pDrvMain->tStadHandles.hMlmeSm, &pInitTable->tMlmeInitParams); 918 919 scanMngr_SetDefaults(pDrvMain->tStadHandles.hScanMngr, &pInitTable->tRoamScanMngrInitParams); 920 roamingMngr_setDefaults(pDrvMain->tStadHandles.hRoamingMngr, &pInitTable->tRoamScanMngrInitParams); 921 922 /* Set DrvMain local defaults */ 923 pDrvMain->tBusDrvCfg.tSdioCfg.uBlkSizeShift = pInitTable->tDrvMainParams.uSdioBlkSizeShift; 924 pDrvMain->tBusDrvCfg.tSdioCfg.uBusDrvThreadPriority = pInitTable->tDrvMainParams.uBusDrvThreadPriority; 925 os_SetDrvThreadPriority (pDrvMain->tStadHandles.hOs, pInitTable->tDrvMainParams.uWlanDrvThreadPriority); 926 927 /* Release the init table memory */ 928 os_memoryFree (pDrvMain->tStadHandles.hOs, pInitTable, sizeof(TInitTable)); 929 930 return eStatus; 931 } 932 933 934 /* 935 * \fn drvMain_xxx...Cb 936 * \brief Callback functions for the init/stop stages completion 937 * 938 * The following callback functions are called from other modules (most from TWD) 939 * when the current init/stop step is completed. 940 * Note that the callbacks are called anyway, either in the original context (if completed), or 941 * in another context if pending. 942 * The first case (same context) may lead to a recursion of the SM, so a special handling is added 943 * to the SM to prevent recursion (see drvMain_Sm). 944 * 945 * drvMain_InitHwCb - HW init completion callback 946 * drvMain_InitFwCb - FW init (mainly download) completion callback 947 * drvMain_ConfigFwCb - FW configuration completion callback 948 * drvMain_TwdStopCb - TWD stopping completion callback 949 * drvMain_InitFailCb - FW init faulty completion callback 950 * drvMain_SmeStopCb - SME stopping completion callback 951 * drvMain_GetFileCb - Getting-file completion callback 952 * 953 * \note 954 * \param hDrvMain - The DrvMain object 955 * \param eStatus - The process result (TI_OK if succeeded, TI_NOK if failed) 956 * \return void 957 * \sa drvMain_Create 958 */ 959 static void drvMain_InitHwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus) 960 { 961 HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus); 962 drvMain_SmEvent (hDrvMain, SM_EVENT_HW_INIT_COMPLETE); 963 } 964 965 static void drvMain_InitFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus) 966 { 967 HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus); 968 drvMain_SmEvent (hDrvMain, SM_EVENT_FW_INIT_COMPLETE); 969 } 970 971 static void drvMain_ConfigFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus) 972 { 973 HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus); 974 drvMain_SmEvent (hDrvMain, SM_EVENT_FW_CONFIG_COMPLETE); 975 } 976 977 static void drvMain_TwdStopCb (TI_HANDLE hDrvMain, TI_STATUS eStatus) 978 { 979 HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus); 980 drvMain_SmEvent (hDrvMain, SM_EVENT_STOP_COMPLETE); 981 } 982 983 static void drvMain_InitFailCb (TI_HANDLE hDrvMain, TI_STATUS eStatus) 984 { 985 drvMain_SmEvent (hDrvMain, SM_EVENT_FAILURE); 986 /* 987 * Note that this call will pass the SM to the FAILED state, since this event 988 * is not handled by any state. 989 */ 990 } 991 992 static void drvMain_InvokeAction (TI_HANDLE hDrvMain) 993 { 994 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 995 996 switch (pDrvMain->eAction) 997 { 998 case ACTION_TYPE_START: 999 drvMain_SmEvent (hDrvMain, SM_EVENT_START); 1000 break; 1001 case ACTION_TYPE_STOP: 1002 drvMain_SmEvent (hDrvMain, SM_EVENT_STOP); 1003 break; 1004 default: 1005 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_InvokeAction(): Action=%d\n", pDrvMain->eAction); 1006 } 1007 } 1008 1009 static void drvMain_GetFileCb (TI_HANDLE hDrvMain) 1010 { 1011 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 1012 ESmEvent eSmEvent; 1013 1014 switch (pDrvMain->tFileInfo.eFileType) 1015 { 1016 case FILE_TYPE_INI: eSmEvent = SM_EVENT_INI_FILE_READY; break; 1017 case FILE_TYPE_NVS: eSmEvent = SM_EVENT_NVS_FILE_READY; break; 1018 case FILE_TYPE_FW: eSmEvent = SM_EVENT_FW_FILE_READY; break; 1019 case FILE_TYPE_FW_NEXT: eSmEvent = SM_EVENT_FW_FILE_READY; break; 1020 default: 1021 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_GetFileCb(): Unknown eFileType=%d\n", pDrvMain->tFileInfo.eFileType); 1022 return; 1023 } 1024 drvMain_SmEvent (hDrvMain, eSmEvent); 1025 } 1026 1027 1028 /* 1029 * \fn drvMain_InitLocals 1030 * \brief Init DrvMain module 1031 * 1032 * Init the DrvMain variables, register to other modules and set device power to off. 1033 * 1034 * \note 1035 * \param pDrvMain - The DrvMain object 1036 * \return void 1037 * \sa drvMain_Init 1038 */ 1039 static void drvMain_InitLocals (TDrvMain *pDrvMain) 1040 { 1041 /* Initialize the module's local varniables to default values */ 1042 pDrvMain->tFileInfo.eFileType = FILE_TYPE_INI; 1043 pDrvMain->tFileInfo.fCbFunc = drvMain_GetFileCb; 1044 pDrvMain->tFileInfo.hCbHndl = (TI_HANDLE)pDrvMain; 1045 pDrvMain->eSmState = SM_STATE_IDLE; 1046 pDrvMain->uPendingEventsCount = 0; 1047 pDrvMain->bRecovery = TI_FALSE; 1048 pDrvMain->eAction = ACTION_TYPE_NONE; 1049 1050 /* Register the Action callback to the context engine and get the client ID */ 1051 pDrvMain->uContextId = context_RegisterClient (pDrvMain->tStadHandles.hContext, 1052 drvMain_InvokeAction, 1053 (TI_HANDLE)pDrvMain, 1054 TI_TRUE, 1055 "ACTION", 1056 sizeof("ACTION")); 1057 1058 /* Platform specific HW preparations */ 1059 hPlatform_Wlan_Hardware_Init(pDrvMain->tStadHandles.hOs); 1060 1061 /* Insure that device power is off (expected to be) */ 1062 hPlatform_DevicePowerOff (); 1063 } 1064 1065 1066 /* 1067 * \fn drvMain_InitHw & drvMain_InitFw 1068 * \brief Init HW and Init FW sequences 1069 * 1070 * drvMain_InitHw - HW init sequence which writes and reads some HW registers 1071 * that are needed prior to FW download. 1072 * drvMain_InitFw - FW init sequence which downloads the FW image and waits for 1073 * FW init-complete indication. 1074 * 1075 * \note 1076 * \param hDrvMain - The DrvMain object 1077 * \param pBuf - The file data (NVS for HW-init, FW-Image for FW-init). 1078 * \param uLength - The file length. 1079 * \return TI_OK if succeeded, TI_NOK if failed. 1080 * \sa 1081 */ 1082 static TI_STATUS drvMain_InitHw (TI_HANDLE hDrvMain, TI_UINT8 *pbuf, TI_UINT32 uLength) 1083 { 1084 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1085 1086 return TWD_InitHw (pDrvMain->tStadHandles.hTWD, pbuf, uLength); 1087 } 1088 1089 static TI_STATUS drvMain_InitFw (TI_HANDLE hDrvMain, TFileInfo *pFileInfo) 1090 { 1091 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1092 1093 return TWD_InitFw (pDrvMain->tStadHandles.hTWD, pFileInfo); 1094 } 1095 1096 1097 /* 1098 * \fn drvMain_ConfigFw 1099 * \brief Configure the FW 1100 * 1101 * The step that follows the FW Init (mainly FW download). 1102 * The Command-Mailbox interface is enabled here and the FW is configured. 1103 * 1104 * \note 1105 * \param pDrvMain - The DrvMain object 1106 * \return TI_OK 1107 * \sa drvMain_Init 1108 */ 1109 static TI_STATUS drvMain_ConfigFw (TI_HANDLE hDrvMain) 1110 { 1111 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1112 1113 /* get pointer to FW static info (already in driver memory) */ 1114 TFwInfo *pFwInfo = TWD_GetFWInfo (pDrvMain->tStadHandles.hTWD); 1115 TI_UINT8 *pMacAddr = (TI_UINT8 *)pFwInfo->macAddress; /* STA MAC address */ 1116 1117 /* Update driver's MAC address */ 1118 wlanDrvIf_SetMacAddress (pDrvMain->tStadHandles.hOs, pMacAddr); 1119 1120 /* 1121 * Exit from init mode should be before smeSM starts. this enable us to send 1122 * command to the MboxQueue(that store the command) while the interrupts are masked. 1123 * the interrupt would be enable at the end of the init process. 1124 */ 1125 TWD_ExitFromInitMode (pDrvMain->tStadHandles.hTWD); 1126 1127 /* Configure the FW from the TWD DB */ 1128 TWD_ConfigFw (pDrvMain->tStadHandles.hTWD); 1129 1130 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_INIT , "EXIT FROM INIT\n"); 1131 1132 /* Print the driver and firmware version and the mac address */ 1133 os_printf("\n"); 1134 os_printf("-----------------------------------------------------\n"); 1135 os_printf("Driver Version : %s\n", SW_VERSION_STR); 1136 os_printf("Firmware Version: %s\n", pFwInfo->fwVer); 1137 os_printf("Station ID : %02X-%02X-%02X-%02X-%02X-%02X\n", 1138 pMacAddr[0], pMacAddr[1], pMacAddr[2], pMacAddr[3], pMacAddr[4], pMacAddr[5]); 1139 os_printf("-----------------------------------------------------\n"); 1140 os_printf("\n"); 1141 1142 return TI_OK; 1143 } 1144 1145 1146 /* 1147 * \fn drvMain_StopActivities 1148 * \brief Freeze driver activities 1149 * 1150 * Freeze all driver activities due to stop command or recovery process. 1151 * 1152 * \note 1153 * \param pDrvMain - The DrvMain object 1154 * \return TI_OK if succeeded, TI_NOK if failed. 1155 * \sa drvMain_EnableActivities 1156 */ 1157 static TI_STATUS drvMain_StopActivities (TDrvMain *pDrvMain) 1158 { 1159 txPort_suspendTx (pDrvMain->tStadHandles.hTxPort); 1160 1161 /* Disable External Inputs (IRQs and commands) */ 1162 TWD_DisableInterrupts(pDrvMain->tStadHandles.hTWD); 1163 cmdHndlr_Disable (pDrvMain->tStadHandles.hCmdHndlr); 1164 1165 /* Initiate TWD Restart */ 1166 return TWD_Stop (pDrvMain->tStadHandles.hTWD); 1167 } 1168 1169 1170 /* 1171 * \fn drvMain_EnableActivities 1172 * \brief Enable driver activities 1173 * 1174 * Enable driver activities after init or recovery process completion. 1175 * 1176 * \note 1177 * \param pDrvMain - The DrvMain object 1178 * \return void 1179 * \sa drvMain_StopActivities 1180 */ 1181 static void drvMain_EnableActivities (TDrvMain *pDrvMain) 1182 { 1183 txPort_resumeTx (pDrvMain->tStadHandles.hTxPort); 1184 1185 /* Enable External Inputs (IRQ is enabled elsewhere) */ 1186 cmdHndlr_Enable (pDrvMain->tStadHandles.hCmdHndlr); 1187 1188 /* Enable external events from FW */ 1189 TWD_EnableExternalEvents (pDrvMain->tStadHandles.hTWD); 1190 1191 1192 } 1193 1194 1195 /* 1196 * \fn drvMain_ClearQueuedEvents 1197 * \brief Enable driver activities 1198 * 1199 * Clear all external events queues (Tx, commands and timers) upon driver stop. 1200 * 1201 * \note 1202 * \param pDrvMain - The DrvMain object 1203 * \return void 1204 * \sa 1205 */ 1206 static void drvMain_ClearQueuedEvents (TDrvMain *pDrvMain) 1207 { 1208 txDataQ_ClearQueues (pDrvMain->tStadHandles.hTxDataQ); 1209 txMgmtQ_ClearQueues (pDrvMain->tStadHandles.hTxMgmtQ); 1210 cmdHndlr_ClearQueue (pDrvMain->tStadHandles.hCmdHndlr); 1211 tmr_ClearOperQueue (pDrvMain->tStadHandles.hTimer); 1212 } 1213 1214 1215 /* 1216 * \fn drvMain_InsertAction 1217 * \brief Get start/stop action and trigger handling 1218 * 1219 * Get start or stop action command from OAL, save it and trigger driver task 1220 * for handling it. 1221 * Wait on a signal object until the requested process is completed. 1222 * 1223 * \note 1224 * \param hDrvMain - The DrvMain object 1225 * \param eAction - The requested action 1226 * \return void 1227 * \sa 1228 */ 1229 TI_STATUS drvMain_InsertAction (TI_HANDLE hDrvMain, EActionType eAction) 1230 { 1231 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1232 1233 context_EnterCriticalSection(pDrvMain->tStadHandles.hContext); 1234 if (pDrvMain->eAction == eAction) 1235 { 1236 context_LeaveCriticalSection(pDrvMain->tStadHandles.hContext); 1237 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE, "Action is identical to last action!\n"); 1238 WLAN_OS_REPORT(("Action %d is identical to last action!\n", eAction)); 1239 return TI_NOK; 1240 } 1241 1242 /* Save the requested action */ 1243 pDrvMain->eAction = eAction; 1244 context_LeaveCriticalSection(pDrvMain->tStadHandles.hContext); 1245 1246 /* Create signal object */ 1247 /* 1248 * Notice that we must create the signal object before asking for ReSchedule, 1249 * because we might receive it immidiatly, and then we will be in a different context 1250 * with null signal object. 1251 */ 1252 pDrvMain->hSignalObj = os_SignalObjectCreate (pDrvMain->tStadHandles.hOs); 1253 if (pDrvMain->hSignalObj == NULL) 1254 { 1255 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_InsertAction(): Couldn't allocate signal object!\n"); 1256 return TI_NOK; 1257 } 1258 1259 /* Request driver task schedule for action handling */ 1260 context_RequestSchedule (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1261 1262 /* Wait for the action processing completion */ 1263 os_SignalObjectWait (pDrvMain->tStadHandles.hOs, pDrvMain->hSignalObj); 1264 1265 /* After "wait" - the action has already been processed in the driver's context */ 1266 1267 /* Free signalling object */ 1268 os_SignalObjectFree (pDrvMain->tStadHandles.hOs, pDrvMain->hSignalObj); 1269 pDrvMain->hSignalObj = NULL; 1270 1271 if (pDrvMain->eSmState == SM_STATE_FAILED) 1272 return TI_NOK; 1273 1274 return TI_OK; 1275 } 1276 1277 1278 /* 1279 * \fn drvMain_Recovery 1280 * \brief Initiate recovery process 1281 * 1282 * Initiate recovery process upon HW/FW error detection (in the Health-Monitor). 1283 * 1284 * \note 1285 * \param hDrvMain - The DrvMain object 1286 * \return TI_OK if started recovery, TI_NOK if recovery is already in progress. 1287 * \sa 1288 */ 1289 TI_STATUS drvMain_Recovery (TI_HANDLE hDrvMain) 1290 { 1291 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1292 1293 if (!pDrvMain->bRecovery) 1294 { 1295 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE,".....drvMain_Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs)); 1296 #ifdef REPORT_LOG 1297 WLAN_OS_REPORT((".....drvMain_Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs))); 1298 #else 1299 printk("%s\n",__func__); 1300 #endif 1301 pDrvMain->bRecovery = TI_TRUE; 1302 drvMain_SmEvent (hDrvMain, SM_EVENT_RECOVERY); 1303 return TI_OK; 1304 } 1305 else 1306 { 1307 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR, "drvMain_Recovery: **** Recovery already in progress! ****\n"); 1308 return TI_NOK; 1309 } 1310 } 1311 1312 1313 /* 1314 * \fn drvMain_RecoveryNotify 1315 * \brief Notify STAD modules about recovery 1316 * 1317 * Notify the relevant STAD modules that recovery took place (after completed). 1318 * 1319 * \note 1320 * \param pDrvMain - The DrvMain object 1321 * \return void 1322 * \sa 1323 */ 1324 static void drvMain_RecoveryNotify (TDrvMain *pDrvMain) 1325 { 1326 txCtrl_NotifyFwReset (pDrvMain->tStadHandles.hTxCtrl); 1327 scr_notifyFWReset (pDrvMain->tStadHandles.hSCR); 1328 PowerMgr_notifyFWReset (pDrvMain->tStadHandles.hPowerMgr); 1329 1330 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE, ".....drvMain_RecoveryNotify: End Of Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs)); 1331 WLAN_OS_REPORT((".....drvMain_RecoveryNotify: End Of Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs))); 1332 } 1333 1334 1335 /* 1336 * \fn drvMain_SmWatchdogTimeout 1337 * \brief SM watchdog timer expiry handler 1338 * 1339 * This is the callback function called upon expiartion of the watchdog timer. 1340 * It is called by the OS-API in timer expiry context, and it issues a failure event to the SM. 1341 * Note that we can't switch to the driver task as for other timers, since we are using 1342 * this timer to protect the init processes, and anyway we just need to stop the driver. 1343 * 1344 * \note 1345 * \param hDrvMain - The DrvMain object 1346 * \return void 1347 * \sa 1348 */ 1349 1350 #if 0 1351 static void drvMain_SmWatchdogTimeout (TI_HANDLE hDrvMain) 1352 { 1353 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 1354 1355 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_SmWatchdogTimeout(): State = %d\n", pDrvMain->eSmState); 1356 1357 /* Send failure event directly to the SM (so the drvMain_SmEvent won't block it). */ 1358 1359 drvMain_Sm ((TI_HANDLE)pDrvMain, SM_EVENT_FAILURE); 1360 } 1361 #endif 1362 1363 /* 1364 * \fn drvMain_SmEvent 1365 * \brief Issue DrvMain SM event 1366 * 1367 * Each event that is handled by the DrvMain state machine, is introduced through this function. 1368 * To prevent SM recursion, the SM is invoeked only if it's not already handling the 1369 * previous event. 1370 * If the SM is busy, the current event is saved until the previous handling is completed. 1371 * 1372 * \note Recursion may happen because some SM activities generate SM events in the same context. 1373 * \param hDrvMain - The DrvMain object 1374 * \param eEvent - The event issued to the SM 1375 * \return void 1376 * \sa 1377 */ 1378 static void drvMain_SmEvent (TI_HANDLE hDrvMain, ESmEvent eEvent) 1379 { 1380 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 1381 1382 /* Increment pending events counter and save last event. */ 1383 pDrvMain->uPendingEventsCount++; 1384 pDrvMain->ePendingEvent = eEvent; 1385 1386 /* If the SM is busy, save event and exit (will be handled when current event is finished) */ 1387 if (pDrvMain->uPendingEventsCount > 1) 1388 { 1389 /* Only one pending event is expected (in addition to the handled one, so two together). */ 1390 if (pDrvMain->uPendingEventsCount > 2) 1391 { 1392 TRACE3(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_SmEvent(): Multiple pending events (%d), State = %d, Event = %d\n", pDrvMain->uPendingEventsCount, pDrvMain->eSmState, eEvent); 1393 } 1394 1395 /* Exit. The current event will be handled by the following while loop of the first instance. */ 1396 return; 1397 } 1398 1399 /* Invoke the SM with the current event and further events issued by the last SM invocation. */ 1400 while (pDrvMain->uPendingEventsCount > 0) 1401 { 1402 drvMain_Sm (hDrvMain, pDrvMain->ePendingEvent); 1403 1404 /* 1405 * Note: The SM may issue another event by calling this function and incrementing 1406 * the counter. 1407 * In this case, only the upper part of this function is run, and the pending 1408 * event is hanlded in the next while loo[. 1409 */ 1410 1411 pDrvMain->uPendingEventsCount--; 1412 } 1413 } 1414 1415 1416 /* 1417 * \fn drvMain_Sm 1418 * \brief The DrvMain state machine 1419 * 1420 * The DrvMain state machine, which handles all driver init, recovery and stop processes. 1421 * 1422 * \note Since the SM may be called back from its own context, recursion is prevented 1423 * by postponing the last event. 1424 * \param hDrvMain - The DrvMain object 1425 * \param eEvent - The event that triggers the SM 1426 * \return void 1427 * \sa 1428 */ 1429 static void drvMain_Sm (TI_HANDLE hDrvMain, ESmEvent eEvent) 1430 { 1431 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 1432 TI_STATUS eStatus = TI_NOK; 1433 TI_HANDLE hOs = pDrvMain->tStadHandles.hOs; 1434 TI_UINT32 uSdioConIndex = 0; 1435 1436 TRACE2(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_INFORMATION , "drvMain_Sm(): State = %d, Event = %d\n", pDrvMain->eSmState, eEvent); 1437 1438 /* 1439 * General explenations: 1440 * ===================== 1441 * 1) This SM calls some functions that may complete their processing in another context. 1442 * All of these functions (wlanDrvIf_GetFile, drvMain_InitHw, drvMain_InitFw, drvMain_ConfigFw, 1443 * drvMain_StopActivities, smeSm_start, smeSm_stop) are provided with a callback which 1444 * they always call upon completion, even if they are completed in the original (SM) context. 1445 * Since these callbacks are calling the SM, a simple mechanism is added to prevent 1446 * recursion, by postponing the last event if the SM is still in the previous event's context. 1447 * 2) In any case of unexpected event, the eStatus remains TI_NOK, leading to the FAILED state! 1448 * FAILED state is also reached if any of the functions listed in note 1 returns TI_NOK. 1449 * Note that if these functions detect a failure in another context, they may call their callback 1450 * with the eStatus parameter set to TI_NOK, or call the drvMain_InitFailCb callback. 1451 * All these cases lead to FAILED state which terminates all driver activities and wait for destroy. 1452 * 3) Note that the wlanDrvIf_GetFile is always completed in the original context, and the 1453 * option of completion in a later context is only for future use. 1454 * 4) All processes (Start, Stop, Relcovery) are protected by a watchdog timer to let 1455 * the user free the driver in case of deadlock during the process. 1456 */ 1457 1458 switch (pDrvMain->eSmState) 1459 { 1460 case SM_STATE_IDLE: 1461 /* 1462 * We get a START action after all modules are created and linked. 1463 * Disable further actions, start watchdog timer and request for the ini-file. 1464 */ 1465 if (eEvent == SM_EVENT_START) 1466 { 1467 /* return thr timer later on */ 1468 /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/ 1469 pDrvMain->eSmState = SM_STATE_WAIT_INI_FILE; 1470 context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1471 pDrvMain->tFileInfo.eFileType = FILE_TYPE_INI; 1472 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1473 } 1474 break; 1475 case SM_STATE_WAIT_INI_FILE: 1476 /* 1477 * We've got the ini-file. 1478 * Set STAD and TWD modules defaults according to the ini-file, 1479 * turn on the device and request for the NVS file. 1480 */ 1481 if (eEvent == SM_EVENT_INI_FILE_READY) 1482 { 1483 pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE; 1484 drvMain_SetDefaults (hDrvMain, pDrvMain->tFileInfo.pBuffer, pDrvMain->tFileInfo.uLength); 1485 hPlatform_DevicePowerOn (); 1486 1487 pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS; 1488 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1489 } 1490 break; 1491 1492 case SM_STATE_WAIT_NVS_FILE: 1493 1494 /* SDBus Connect connection validation */ 1495 for(uSdioConIndex=0; (uSdioConIndex < SDIO_CONNECT_THRESHOLD) && (eStatus != TI_OK); uSdioConIndex++) 1496 { 1497 /* : We should split the call to txnQ_ConnectBus to other state in order to support Async bus connection */ 1498 eStatus = txnQ_ConnectBus(pDrvMain->tStadHandles.hTxnQ, &pDrvMain->tBusDrvCfg, NULL, NULL); 1499 1500 if((eStatus != TI_OK) && 1501 (uSdioConIndex < (SDIO_CONNECT_THRESHOLD - 1))) 1502 { 1503 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_WARNING , "SDBus Connect Failed\n"); 1504 WLAN_OS_REPORT(("Try to SDBus Connect again...\n")); 1505 if (uSdioConIndex > 1) 1506 hPlatform_DevicePowerOffSetLongerDelay(); 1507 else 1508 hPlatform_DevicePowerOff(); 1509 hPlatform_DevicePowerOn(); 1510 } 1511 } 1512 1513 if(eStatus != TI_OK) 1514 { 1515 WLAN_OS_REPORT(("SDBus Connect Failed, Set Object Event !!\r\n")); 1516 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "SDBus Connect Failed, Set Object Event !!\r\n"); 1517 if (!pDrvMain->bRecovery) 1518 { 1519 os_SignalObjectSet(hOs, pDrvMain->hSignalObj); 1520 } 1521 else 1522 { 1523 /* in case recovery fails, stop the sme which will send disassociation event to os */ 1524 sme_Stop(pDrvMain->tStadHandles.hSme); 1525 } 1526 } 1527 else /* SDBus Connect success */ 1528 { 1529 /* 1530 * We've got the NVS file. 1531 * Start HW-Init process providing the NVS file. 1532 */ 1533 if (eEvent == SM_EVENT_NVS_FILE_READY) 1534 { 1535 pDrvMain->eSmState = SM_STATE_HW_INIT; 1536 eStatus = drvMain_InitHw (hDrvMain, pDrvMain->tFileInfo.pBuffer, pDrvMain->tFileInfo.uLength); 1537 } 1538 } 1539 break; 1540 case SM_STATE_HW_INIT: 1541 /* 1542 * HW-Init process is completed. 1543 * Request for the FW image file. 1544 */ 1545 if (eEvent == SM_EVENT_HW_INIT_COMPLETE) 1546 { 1547 pDrvMain->tFileInfo.eFileType = FILE_TYPE_FW; 1548 pDrvMain->eSmState = SM_STATE_DOWNLOAD_FW_FILE; 1549 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1550 } 1551 break; 1552 case SM_STATE_DOWNLOAD_FW_FILE: 1553 if (eEvent == SM_EVENT_FW_FILE_READY) 1554 { 1555 pDrvMain->tFileInfo.eFileType = FILE_TYPE_FW_NEXT; 1556 if (pDrvMain->tFileInfo.bLast == TI_TRUE) 1557 { 1558 pDrvMain->eSmState = SM_STATE_FW_INIT; 1559 } 1560 else 1561 { 1562 pDrvMain->eSmState = SM_STATE_WAIT_FW_FILE; 1563 } 1564 /* 1565 * We've got the FW image file. 1566 * Start FW-Init process (mainly FW image download) providing the FW image file. 1567 */ 1568 eStatus = drvMain_InitFw (hDrvMain, &pDrvMain->tFileInfo); 1569 } 1570 break; 1571 case SM_STATE_WAIT_FW_FILE: 1572 if (eEvent == SM_EVENT_FW_INIT_COMPLETE) 1573 { 1574 pDrvMain->eSmState = SM_STATE_DOWNLOAD_FW_FILE; 1575 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1576 } 1577 break; 1578 case SM_STATE_FW_INIT: 1579 /* 1580 * FW-Init process is completed. 1581 * Free the semaphore of the START action to enable the OS interface. 1582 * Enable interrupts (or polling for debug). 1583 * Start FW-Configuration process, and free the semaphore of the START action. 1584 * 1585 * Note that in some OSs, the semaphore must be released in order to enable the 1586 * interrupts, and the interrupts are needed for the configuration process! 1587 */ 1588 if (eEvent == SM_EVENT_FW_INIT_COMPLETE) 1589 { 1590 pDrvMain->eSmState = SM_STATE_FW_CONFIG; 1591 TWD_EnableInterrupts(pDrvMain->tStadHandles.hTWD); 1592 #ifdef PRIODIC_INTERRUPT 1593 /* Start periodic interrupts. It means that every period of time the FwEvent SM will be called */ 1594 os_periodicIntrTimerStart (hOs); 1595 #endif 1596 eStatus = drvMain_ConfigFw (hDrvMain); 1597 } 1598 break; 1599 case SM_STATE_FW_CONFIG: 1600 /* 1601 * FW-configuration process is completed. 1602 * Stop watchdog timer. 1603 * For recovery, notify the relevant STAD modules. 1604 * For regular start, start the SME which handles the connection process. 1605 * Update timer and OAL about entering OPERATIONAL state (OAL ignores recovery) 1606 * Enable driver activities and external events. 1607 * Enable STOP action 1608 * We are now in OPERATIONAL state, i.e. the driver is fully operational! 1609 */ 1610 1611 if (eEvent == SM_EVENT_FW_CONFIG_COMPLETE) 1612 { 1613 pDrvMain->eSmState = SM_STATE_OPERATIONAL; 1614 /* return thr timer later on */ 1615 /*os_timerStop (hOs, pDrvMain->hWatchdogTimer);*/ 1616 if (pDrvMain->bRecovery) 1617 { 1618 drvMain_RecoveryNotify (pDrvMain); 1619 pDrvMain->bRecovery = TI_FALSE; 1620 } 1621 else 1622 { 1623 sme_Start (pDrvMain->tStadHandles.hSme); 1624 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_RUNNING); 1625 } 1626 tmr_UpdateDriverState (pDrvMain->tStadHandles.hTimer, TI_TRUE); 1627 drvMain_EnableActivities (pDrvMain); 1628 context_EnableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1629 eStatus = TI_OK; 1630 1631 } 1632 if (!pDrvMain->bRecovery) 1633 { 1634 os_SignalObjectSet(hOs, pDrvMain->hSignalObj); 1635 } 1636 break; 1637 case SM_STATE_OPERATIONAL: 1638 /* 1639 * Disable start/stop commands and start watchdog timer. 1640 * Update timer and OAL about exiting OPERATIONAL state (OAL ignores recovery). 1641 * For STOP, stop SME (handle disconnection) and move to DISCONNECTING state. 1642 * For recovery, stop driver activities and move to STOPPING state. 1643 * Note that driver-stop process may be Async if we are during Async bus transaction. 1644 */ 1645 1646 context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1647 /* return thr timer later on */ 1648 /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/ 1649 tmr_UpdateDriverState (pDrvMain->tStadHandles.hTimer, TI_FALSE); 1650 if (eEvent == SM_EVENT_STOP) 1651 { 1652 pDrvMain->eSmState = SM_STATE_DISCONNECTING; 1653 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_STOPING); 1654 sme_Stop (pDrvMain->tStadHandles.hSme); 1655 eStatus = TI_OK; 1656 } 1657 else if (eEvent == SM_EVENT_RECOVERY) 1658 { 1659 pDrvMain->eSmState = SM_STATE_STOPPING; 1660 eStatus = drvMain_StopActivities (pDrvMain); 1661 } 1662 1663 break; 1664 case SM_STATE_DISCONNECTING: 1665 /* 1666 * Note that this state is not relevant for recovery. 1667 * SME stop is completed 1668 * Stop driver activities and move to STOPPING state. 1669 * Note that driver stop process may be Async if we are during Async bus transaction. 1670 */ 1671 1672 if (eEvent == SM_EVENT_DISCONNECTED) 1673 { 1674 pDrvMain->eSmState = SM_STATE_STOPPING; 1675 eStatus = drvMain_StopActivities (pDrvMain); 1676 } 1677 break; 1678 case SM_STATE_STOPPING: 1679 /* 1680 * Driver stopping process is done. 1681 * Turn device power off. 1682 * For recovery, turn device power back on, request NVS file and continue with 1683 * the init process (recover back all the way to OPERATIONAL state). 1684 * For STOP process, the driver is now fully stopped (STOPPED state), so stop watchdog timer, 1685 * clear all events queues, free the semaphore of the STOP action and enable START action. 1686 */ 1687 1688 if (eEvent == SM_EVENT_STOP_COMPLETE) 1689 { 1690 txnQ_DisconnectBus (pDrvMain->tStadHandles.hTxnQ); 1691 hPlatform_DevicePowerOff (); 1692 if (pDrvMain->bRecovery) 1693 { 1694 hPlatform_DevicePowerOn (); 1695 pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE; 1696 pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS; 1697 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1698 } 1699 else 1700 { 1701 pDrvMain->eSmState = SM_STATE_STOPPED; 1702 /* return thr timer later on */ 1703 /*os_timerStop (hOs, pDrvMain->hWatchdogTimer);*/ 1704 drvMain_ClearQueuedEvents (pDrvMain); 1705 scr_notifyFWReset(pDrvMain->tStadHandles.hSCR); 1706 os_SignalObjectSet (hOs, pDrvMain->hSignalObj); 1707 context_EnableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1708 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_STOPPED); 1709 eStatus = TI_OK; 1710 } 1711 } 1712 1713 break; 1714 case SM_STATE_STOPPED: 1715 /* 1716 * A START action command was inserted, so we go through the init process. 1717 * Disable further actions, start watchdog timer, turn on device and request NVS file. 1718 */ 1719 1720 context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1721 /* return thr timer later on */ 1722 /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/ 1723 if (eEvent == SM_EVENT_START) 1724 { 1725 hPlatform_DevicePowerOn (); 1726 pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE; 1727 pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS; 1728 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1729 } 1730 break; 1731 case SM_STATE_STOPPING_ON_FAIL: 1732 /* 1733 * Driver stopping process upon failure is completed. 1734 * Turn off the device and move to FAILED state. 1735 */ 1736 1737 pDrvMain->eSmState = SM_STATE_FAILED; 1738 txnQ_DisconnectBus (pDrvMain->tStadHandles.hTxnQ); 1739 hPlatform_DevicePowerOff (); 1740 WLAN_OS_REPORT(("[WLAN] Exit application\n")); 1741 if (!pDrvMain->bRecovery) 1742 { 1743 os_SignalObjectSet (hOs, pDrvMain->hSignalObj); 1744 } 1745 break; 1746 case SM_STATE_FAILED: 1747 /* Nothing to do except waiting for Destroy */ 1748 break; 1749 default: 1750 TRACE2(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_Sm: Unknown state, eEvent=%u at state=%u\n", eEvent, pDrvMain->eSmState); 1751 /* Note: Handled below as a failure since the status remains TI_NOK */ 1752 break; 1753 } 1754 1755 /* Handle failures (status = NOK) if not handled yet */ 1756 if ((eStatus == TI_NOK) && 1757 (pDrvMain->eSmState != SM_STATE_FAILED) && 1758 (pDrvMain->eSmState != SM_STATE_STOPPING_ON_FAIL)) 1759 { 1760 TRACE3(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_Sm: eEvent=%u at state=%u, status=%d\n", eEvent, pDrvMain->eSmState, eStatus); 1761 pDrvMain->eSmState = SM_STATE_STOPPING_ON_FAIL; 1762 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_FAILED); 1763 1764 /* 1765 * Stop all activities. This may be completed in a different context if 1766 * we should wait for an Async bus transaction completion. 1767 * The drvMain_TwdStopCb is called from the TWD in any case to pass 1768 * us to the SM_STATE_FAILED state (where we wait for Destroy). 1769 */ 1770 eStatus = drvMain_StopActivities (pDrvMain); 1771 } 1772 } 1773