DrvMain.c revision b9c472e425a823df929150475a9f340ad4decca3
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 * \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 */ 564TI_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 776void 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 */ 795static 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 */ 877static 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 */ 959static 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 965static 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 971static 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 977static 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 983static 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 992static 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 1009static 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 */ 1039static 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 */ 1082static 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 1089static 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 */ 1109static 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 WLAN_OS_REPORT(("\n")); 1134 WLAN_OS_REPORT(("--------------------------------------------------------------------\n")); 1135 WLAN_OS_REPORT(("Driver Version : %s\n", SW_VERSION_STR)); 1136 WLAN_OS_REPORT(("Firmware Version: %s\n", pFwInfo->fwVer)); 1137 WLAN_OS_REPORT(("Station ID : %02X-%02X-%02X-%02X-%02X-%02X\n", 1138 pMacAddr[0], pMacAddr[1], pMacAddr[2], pMacAddr[3], pMacAddr[4], pMacAddr[5])); 1139 WLAN_OS_REPORT(("--------------------------------------------------------------------\n")); 1140 WLAN_OS_REPORT(("\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 */ 1157static 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 */ 1181static 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 */ 1206static 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 */ 1229TI_STATUS drvMain_InsertAction (TI_HANDLE hDrvMain, EActionType eAction) 1230{ 1231 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1232 1233 if (pDrvMain->eAction == eAction) 1234 { 1235 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE, "Action is identical to last action!\n"); 1236 WLAN_OS_REPORT(("Action %d is identical to last action!\n", eAction)); 1237 return TI_NOK; 1238 } 1239 1240 /* Save the requested action */ 1241 pDrvMain->eAction = eAction; 1242 1243 /* Create signal object */ 1244 /* 1245 * Notice that we must create the signal object before asking for ReSchedule, 1246 * because we might receive it immidiatly, and then we will be in a different context 1247 * with null signal object. 1248 */ 1249 pDrvMain->hSignalObj = os_SignalObjectCreate (pDrvMain->tStadHandles.hOs); 1250 if (pDrvMain->hSignalObj == NULL) 1251 { 1252 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_InsertAction(): Couldn't allocate signal object!\n"); 1253 return TI_NOK; 1254 } 1255 1256 /* Request driver task schedule for action handling */ 1257 context_RequestSchedule (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1258 1259 /* Wait for the action processing completion */ 1260 os_SignalObjectWait (pDrvMain->tStadHandles.hOs, pDrvMain->hSignalObj); 1261 1262 /* After "wait" - the action has already been processed in the driver's context */ 1263 1264 /* Free signalling object */ 1265 os_SignalObjectFree (pDrvMain->tStadHandles.hOs, pDrvMain->hSignalObj); 1266 1267 if (pDrvMain->eSmState == SM_STATE_FAILED) 1268 return TI_NOK; 1269 1270 return TI_OK; 1271} 1272 1273 1274/* 1275 * \fn drvMain_Recovery 1276 * \brief Initiate recovery process 1277 * 1278 * Initiate recovery process upon HW/FW error detection (in the Health-Monitor). 1279 * 1280 * \note 1281 * \param hDrvMain - The DrvMain object 1282 * \return TI_OK if started recovery, TI_NOK if recovery is already in progress. 1283 * \sa 1284 */ 1285TI_STATUS drvMain_Recovery (TI_HANDLE hDrvMain) 1286{ 1287 TDrvMain *pDrvMain = (TDrvMain *) hDrvMain; 1288 1289 if (!pDrvMain->bRecovery) 1290 { 1291 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE,".....drvMain_Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs)); 1292 WLAN_OS_REPORT((".....drvMain_Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs))); 1293 pDrvMain->bRecovery = TI_TRUE; 1294 drvMain_SmEvent (hDrvMain, SM_EVENT_RECOVERY); 1295 return TI_OK; 1296 } 1297 else 1298 { 1299 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR, "drvMain_Recovery: **** Recovery already in progress! ****\n"); 1300 return TI_NOK; 1301 } 1302} 1303 1304 1305/* 1306 * \fn drvMain_RecoveryNotify 1307 * \brief Notify STAD modules about recovery 1308 * 1309 * Notify the relevant STAD modules that recovery took place (after completed). 1310 * 1311 * \note 1312 * \param pDrvMain - The DrvMain object 1313 * \return void 1314 * \sa 1315 */ 1316static void drvMain_RecoveryNotify (TDrvMain *pDrvMain) 1317{ 1318 txCtrl_NotifyFwReset (pDrvMain->tStadHandles.hTxCtrl); 1319 scr_notifyFWReset (pDrvMain->tStadHandles.hSCR); 1320 PowerMgr_notifyFWReset (pDrvMain->tStadHandles.hPowerMgr); 1321 1322 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE, ".....drvMain_RecoveryNotify: End Of Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs)); 1323 WLAN_OS_REPORT((".....drvMain_RecoveryNotify: End Of Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs))); 1324} 1325 1326 1327/* 1328 * \fn drvMain_SmWatchdogTimeout 1329 * \brief SM watchdog timer expiry handler 1330 * 1331 * This is the callback function called upon expiartion of the watchdog timer. 1332 * It is called by the OS-API in timer expiry context, and it issues a failure event to the SM. 1333 * Note that we can't switch to the driver task as for other timers, since we are using 1334 * this timer to protect the init processes, and anyway we just need to stop the driver. 1335 * 1336 * \note 1337 * \param hDrvMain - The DrvMain object 1338 * \return void 1339 * \sa 1340 */ 1341 1342#if 0 1343static void drvMain_SmWatchdogTimeout (TI_HANDLE hDrvMain) 1344{ 1345 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 1346 1347 TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_SmWatchdogTimeout(): State = %d\n", pDrvMain->eSmState); 1348 1349 /* Send failure event directly to the SM (so the drvMain_SmEvent won't block it). */ 1350 1351 drvMain_Sm ((TI_HANDLE)pDrvMain, SM_EVENT_FAILURE); 1352} 1353#endif 1354 1355/* 1356 * \fn drvMain_SmEvent 1357 * \brief Issue DrvMain SM event 1358 * 1359 * Each event that is handled by the DrvMain state machine, is introduced through this function. 1360 * To prevent SM recursion, the SM is invoeked only if it's not already handling the 1361 * previous event. 1362 * If the SM is busy, the current event is saved until the previous handling is completed. 1363 * 1364 * \note Recursion may happen because some SM activities generate SM events in the same context. 1365 * \param hDrvMain - The DrvMain object 1366 * \param eEvent - The event issued to the SM 1367 * \return void 1368 * \sa 1369 */ 1370static void drvMain_SmEvent (TI_HANDLE hDrvMain, ESmEvent eEvent) 1371{ 1372 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 1373 1374 /* Increment pending events counter and save last event. */ 1375 pDrvMain->uPendingEventsCount++; 1376 pDrvMain->ePendingEvent = eEvent; 1377 1378 /* If the SM is busy, save event and exit (will be handled when current event is finished) */ 1379 if (pDrvMain->uPendingEventsCount > 1) 1380 { 1381 /* Only one pending event is expected (in addition to the handled one, so two together). */ 1382 if (pDrvMain->uPendingEventsCount > 2) 1383 { 1384 TRACE3(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_SmEvent(): Multiple pending events (%d), State = %d, Event = %d\n", pDrvMain->uPendingEventsCount, pDrvMain->eSmState, eEvent); 1385 } 1386 1387 /* Exit. The current event will be handled by the following while loop of the first instance. */ 1388 return; 1389 } 1390 1391 /* Invoke the SM with the current event and further events issued by the last SM invocation. */ 1392 while (pDrvMain->uPendingEventsCount > 0) 1393 { 1394 drvMain_Sm (hDrvMain, pDrvMain->ePendingEvent); 1395 1396 /* 1397 * Note: The SM may issue another event by calling this function and incrementing 1398 * the counter. 1399 * In this case, only the upper part of this function is run, and the pending 1400 * event is hanlded in the next while loo[. 1401 */ 1402 1403 pDrvMain->uPendingEventsCount--; 1404 } 1405} 1406 1407 1408/* 1409 * \fn drvMain_Sm 1410 * \brief The DrvMain state machine 1411 * 1412 * The DrvMain state machine, which handles all driver init, recovery and stop processes. 1413 * 1414 * \note Since the SM may be called back from its own context, recursion is prevented 1415 * by postponing the last event. 1416 * \param hDrvMain - The DrvMain object 1417 * \param eEvent - The event that triggers the SM 1418 * \return void 1419 * \sa 1420 */ 1421static void drvMain_Sm (TI_HANDLE hDrvMain, ESmEvent eEvent) 1422{ 1423 TDrvMain *pDrvMain = (TDrvMain *)hDrvMain; 1424 TI_STATUS eStatus = TI_NOK; 1425 TI_HANDLE hOs = pDrvMain->tStadHandles.hOs; 1426 TI_UINT32 uSdioConIndex = 0; 1427 1428 TRACE2(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_INFORMATION , "drvMain_Sm(): State = %d, Event = %d\n", pDrvMain->eSmState, eEvent); 1429 1430 /* 1431 * General explenations: 1432 * ===================== 1433 * 1) This SM calls some functions that may complete their processing in another context. 1434 * All of these functions (wlanDrvIf_GetFile, drvMain_InitHw, drvMain_InitFw, drvMain_ConfigFw, 1435 * drvMain_StopActivities, smeSm_start, smeSm_stop) are provided with a callback which 1436 * they always call upon completion, even if they are completed in the original (SM) context. 1437 * Since these callbacks are calling the SM, a simple mechanism is added to prevent 1438 * recursion, by postponing the last event if the SM is still in the previous event's context. 1439 * 2) In any case of unexpected event, the eStatus remains TI_NOK, leading to the FAILED state! 1440 * FAILED state is also reached if any of the functions listed in note 1 returns TI_NOK. 1441 * Note that if these functions detect a failure in another context, they may call their callback 1442 * with the eStatus parameter set to TI_NOK, or call the drvMain_InitFailCb callback. 1443 * All these cases lead to FAILED state which terminates all driver activities and wait for destroy. 1444 * 3) Note that the wlanDrvIf_GetFile is always completed in the original context, and the 1445 * option of completion in a later context is only for future use. 1446 * 4) All processes (Start, Stop, Relcovery) are protected by a watchdog timer to let 1447 * the user free the driver in case of deadlock during the process. 1448 */ 1449 1450 switch (pDrvMain->eSmState) 1451 { 1452 case SM_STATE_IDLE: 1453 /* 1454 * We get a START action after all modules are created and linked. 1455 * Disable further actions, start watchdog timer and request for the ini-file. 1456 */ 1457 if (eEvent == SM_EVENT_START) 1458 { 1459 /* return thr timer later on */ 1460 /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/ 1461 pDrvMain->eSmState = SM_STATE_WAIT_INI_FILE; 1462 context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1463 pDrvMain->tFileInfo.eFileType = FILE_TYPE_INI; 1464 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1465 } 1466 break; 1467 case SM_STATE_WAIT_INI_FILE: 1468 /* 1469 * We've got the ini-file. 1470 * Set STAD and TWD modules defaults according to the ini-file, 1471 * turn on the device and request for the NVS file. 1472 */ 1473 if (eEvent == SM_EVENT_INI_FILE_READY) 1474 { 1475 pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE; 1476 drvMain_SetDefaults (hDrvMain, pDrvMain->tFileInfo.pBuffer, pDrvMain->tFileInfo.uLength); 1477 hPlatform_DevicePowerOn (); 1478 1479 pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS; 1480 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1481 } 1482 break; 1483 1484 case SM_STATE_WAIT_NVS_FILE: 1485 1486 /* SDBus Connect connection validation */ 1487 for(uSdioConIndex=0; (uSdioConIndex < SDIO_CONNECT_THRESHOLD) && (eStatus != TI_OK); uSdioConIndex++) 1488 { 1489 /* : We should split the call to txnQ_ConnectBus to other state in order to support Async bus connection */ 1490 eStatus = txnQ_ConnectBus(pDrvMain->tStadHandles.hTxnQ, &pDrvMain->tBusDrvCfg, NULL, NULL); 1491 1492 if((eStatus != TI_OK) && 1493 (uSdioConIndex < (SDIO_CONNECT_THRESHOLD - 1))) 1494 { 1495 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_WARNING , "SDBus Connect Failed\n"); 1496 WLAN_OS_REPORT(("Try to SDBus Connect again...\n")); 1497 if (uSdioConIndex > 1) 1498 hPlatform_DevicePowerOffSetLongerDelay(); 1499 else 1500 hPlatform_DevicePowerOff(); 1501 hPlatform_DevicePowerOn(); 1502 } 1503 } 1504 1505 if(eStatus != TI_OK) 1506 { 1507 WLAN_OS_REPORT(("SDBus Connect Failed, Set Object Event !!\r\n")); 1508 TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "SDBus Connect Failed, Set Object Event !!\r\n"); 1509 if (!pDrvMain->bRecovery) 1510 { 1511 os_SignalObjectSet(hOs, pDrvMain->hSignalObj); 1512 } 1513 else 1514 { 1515 /* in case recovery fails, stop the sme which will send disassociation event to os */ 1516 sme_Stop(pDrvMain->tStadHandles.hSme); 1517 } 1518 } 1519 else /* SDBus Connect success */ 1520 { 1521 /* 1522 * We've got the NVS file. 1523 * Start HW-Init process providing the NVS file. 1524 */ 1525 if (eEvent == SM_EVENT_NVS_FILE_READY) 1526 { 1527 pDrvMain->eSmState = SM_STATE_HW_INIT; 1528 eStatus = drvMain_InitHw (hDrvMain, pDrvMain->tFileInfo.pBuffer, pDrvMain->tFileInfo.uLength); 1529 } 1530 } 1531 break; 1532 case SM_STATE_HW_INIT: 1533 /* 1534 * HW-Init process is completed. 1535 * Request for the FW image file. 1536 */ 1537 if (eEvent == SM_EVENT_HW_INIT_COMPLETE) 1538 { 1539 pDrvMain->tFileInfo.eFileType = FILE_TYPE_FW; 1540 pDrvMain->eSmState = SM_STATE_DOWNLOAD_FW_FILE; 1541 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1542 } 1543 break; 1544 case SM_STATE_DOWNLOAD_FW_FILE: 1545 if (eEvent == SM_EVENT_FW_FILE_READY) 1546 { 1547 pDrvMain->tFileInfo.eFileType = FILE_TYPE_FW_NEXT; 1548 if (pDrvMain->tFileInfo.bLast == TI_TRUE) 1549 { 1550 pDrvMain->eSmState = SM_STATE_FW_INIT; 1551 } 1552 else 1553 { 1554 pDrvMain->eSmState = SM_STATE_WAIT_FW_FILE; 1555 } 1556 /* 1557 * We've got the FW image file. 1558 * Start FW-Init process (mainly FW image download) providing the FW image file. 1559 */ 1560 eStatus = drvMain_InitFw (hDrvMain, &pDrvMain->tFileInfo); 1561 } 1562 break; 1563 case SM_STATE_WAIT_FW_FILE: 1564 if (eEvent == SM_EVENT_FW_INIT_COMPLETE) 1565 { 1566 pDrvMain->eSmState = SM_STATE_DOWNLOAD_FW_FILE; 1567 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1568 } 1569 break; 1570 case SM_STATE_FW_INIT: 1571 /* 1572 * FW-Init process is completed. 1573 * Free the semaphore of the START action to enable the OS interface. 1574 * Enable interrupts (or polling for debug). 1575 * Start FW-Configuration process, and free the semaphore of the START action. 1576 * 1577 * Note that in some OSs, the semaphore must be released in order to enable the 1578 * interrupts, and the interrupts are needed for the configuration process! 1579 */ 1580 if (eEvent == SM_EVENT_FW_INIT_COMPLETE) 1581 { 1582 pDrvMain->eSmState = SM_STATE_FW_CONFIG; 1583 if (!pDrvMain->bRecovery) 1584 { 1585 os_SignalObjectSet(hOs, pDrvMain->hSignalObj); 1586 } 1587 TWD_EnableInterrupts(pDrvMain->tStadHandles.hTWD); 1588 #ifdef PRIODIC_INTERRUPT 1589 /* Start periodic interrupts. It means that every period of time the FwEvent SM will be called */ 1590 os_periodicIntrTimerStart (hOs); 1591 #endif 1592 eStatus = drvMain_ConfigFw (hDrvMain); 1593 } 1594 break; 1595 case SM_STATE_FW_CONFIG: 1596 /* 1597 * FW-configuration process is completed. 1598 * Stop watchdog timer. 1599 * For recovery, notify the relevant STAD modules. 1600 * For regular start, start the SME which handles the connection process. 1601 * Update timer and OAL about entering OPERATIONAL state (OAL ignores recovery) 1602 * Enable driver activities and external events. 1603 * Enable STOP action 1604 * We are now in OPERATIONAL state, i.e. the driver is fully operational! 1605 */ 1606 1607 if (eEvent == SM_EVENT_FW_CONFIG_COMPLETE) 1608 { 1609 pDrvMain->eSmState = SM_STATE_OPERATIONAL; 1610 /* return thr timer later on */ 1611 /*os_timerStop (hOs, pDrvMain->hWatchdogTimer);*/ 1612 if (pDrvMain->bRecovery) 1613 { 1614 drvMain_RecoveryNotify (pDrvMain); 1615 pDrvMain->bRecovery = TI_FALSE; 1616 } 1617 else 1618 { 1619 sme_Start (pDrvMain->tStadHandles.hSme); 1620 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_RUNNING); 1621 } 1622 tmr_UpdateDriverState (pDrvMain->tStadHandles.hTimer, TI_TRUE); 1623 drvMain_EnableActivities (pDrvMain); 1624 context_EnableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1625 eStatus = TI_OK; 1626 1627 } 1628 break; 1629 case SM_STATE_OPERATIONAL: 1630 /* 1631 * Disable start/stop commands and start watchdog timer. 1632 * Update timer and OAL about exiting OPERATIONAL state (OAL ignores recovery). 1633 * For STOP, stop SME (handle disconnection) and move to DISCONNECTING state. 1634 * For recovery, stop driver activities and move to STOPPING state. 1635 * Note that driver-stop process may be Async if we are during Async bus transaction. 1636 */ 1637 1638 context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1639 /* return thr timer later on */ 1640 /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/ 1641 tmr_UpdateDriverState (pDrvMain->tStadHandles.hTimer, TI_FALSE); 1642 if (eEvent == SM_EVENT_STOP) 1643 { 1644 pDrvMain->eSmState = SM_STATE_DISCONNECTING; 1645 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_STOPING); 1646 sme_Stop (pDrvMain->tStadHandles.hSme); 1647 eStatus = TI_OK; 1648 } 1649 else if (eEvent == SM_EVENT_RECOVERY) 1650 { 1651 pDrvMain->eSmState = SM_STATE_STOPPING; 1652 eStatus = drvMain_StopActivities (pDrvMain); 1653 } 1654 1655 break; 1656 case SM_STATE_DISCONNECTING: 1657 /* 1658 * Note that this state is not relevant for recovery. 1659 * SME stop is completed 1660 * Stop driver activities and move to STOPPING state. 1661 * Note that driver stop process may be Async if we are during Async bus transaction. 1662 */ 1663 1664 if (eEvent == SM_EVENT_DISCONNECTED) 1665 { 1666 pDrvMain->eSmState = SM_STATE_STOPPING; 1667 eStatus = drvMain_StopActivities (pDrvMain); 1668 } 1669 break; 1670 case SM_STATE_STOPPING: 1671 /* 1672 * Driver stopping process is done. 1673 * Turn device power off. 1674 * For recovery, turn device power back on, request NVS file and continue with 1675 * the init process (recover back all the way to OPERATIONAL state). 1676 * For STOP process, the driver is now fully stopped (STOPPED state), so stop watchdog timer, 1677 * clear all events queues, free the semaphore of the STOP action and enable START action. 1678 */ 1679 1680 if (eEvent == SM_EVENT_STOP_COMPLETE) 1681 { 1682 txnQ_DisconnectBus (pDrvMain->tStadHandles.hTxnQ); 1683 hPlatform_DevicePowerOff (); 1684 if (pDrvMain->bRecovery) 1685 { 1686 hPlatform_DevicePowerOn (); 1687 pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE; 1688 pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS; 1689 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1690 } 1691 else 1692 { 1693 pDrvMain->eSmState = SM_STATE_STOPPED; 1694 /* return thr timer later on */ 1695 /*os_timerStop (hOs, pDrvMain->hWatchdogTimer);*/ 1696 drvMain_ClearQueuedEvents (pDrvMain); 1697 scr_notifyFWReset(pDrvMain->tStadHandles.hSCR); 1698 os_SignalObjectSet (hOs, pDrvMain->hSignalObj); 1699 context_EnableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1700 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_STOPPED); 1701 eStatus = TI_OK; 1702 } 1703 } 1704 1705 break; 1706 case SM_STATE_STOPPED: 1707 /* 1708 * A START action command was inserted, so we go through the init process. 1709 * Disable further actions, start watchdog timer, turn on device and request NVS file. 1710 */ 1711 1712 context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId); 1713 /* return thr timer later on */ 1714 /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/ 1715 if (eEvent == SM_EVENT_START) 1716 { 1717 hPlatform_DevicePowerOn (); 1718 pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE; 1719 pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS; 1720 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo); 1721 } 1722 break; 1723 case SM_STATE_STOPPING_ON_FAIL: 1724 /* 1725 * Driver stopping process upon failure is completed. 1726 * Turn off the device and move to FAILED state. 1727 */ 1728 1729 pDrvMain->eSmState = SM_STATE_FAILED; 1730 txnQ_DisconnectBus (pDrvMain->tStadHandles.hTxnQ); 1731 hPlatform_DevicePowerOff (); 1732 WLAN_OS_REPORT(("[WLAN] Exit application\n")); 1733 if (!pDrvMain->bRecovery) 1734 { 1735 os_SignalObjectSet (hOs, pDrvMain->hSignalObj); 1736 } 1737 break; 1738 case SM_STATE_FAILED: 1739 /* Nothing to do except waiting for Destroy */ 1740 break; 1741 default: 1742 TRACE2(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_Sm: Unknown state, eEvent=%u at state=%u\n", eEvent, pDrvMain->eSmState); 1743 /* Note: Handled below as a failure since the status remains TI_NOK */ 1744 break; 1745 } 1746 1747 /* Handle failures (status = NOK) if not handled yet */ 1748 if ((eStatus == TI_NOK) && 1749 (pDrvMain->eSmState != SM_STATE_FAILED) && 1750 (pDrvMain->eSmState != SM_STATE_STOPPING_ON_FAIL)) 1751 { 1752 TRACE3(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_Sm: eEvent=%u at state=%u, status=%d\n", eEvent, pDrvMain->eSmState, eStatus); 1753 pDrvMain->eSmState = SM_STATE_STOPPING_ON_FAIL; 1754 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_FAILED); 1755 1756 /* 1757 * Stop all activities. This may be completed in a different context if 1758 * we should wait for an Async bus transaction completion. 1759 * The drvMain_TwdStopCb is called from the TWD in any case to pass 1760 * us to the SM_STATE_FAILED state (where we wait for Destroy). 1761 */ 1762 eStatus = drvMain_StopActivities (pDrvMain); 1763 } 1764} 1765