PageRenderTime 63ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/net/wireless/tiwlan1251/common/src/TNETW_Driver/FW_Transfer/FwEvent/FwEvent.c

http://github.com/CyanogenMod/cm-kernel
C | 1058 lines | 533 code | 143 blank | 382 comment | 56 complexity | 358dd8941680611487902377436fce05 MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0, LGPL-2.0
  1. /****************************************************************************
  2. **+-----------------------------------------------------------------------+**
  3. **| |**
  4. **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
  5. **| All rights reserved. |**
  6. **| |**
  7. **| Redistribution and use in source and binary forms, with or without |**
  8. **| modification, are permitted provided that the following conditions |**
  9. **| are met: |**
  10. **| |**
  11. **| * Redistributions of source code must retain the above copyright |**
  12. **| notice, this list of conditions and the following disclaimer. |**
  13. **| * Redistributions in binary form must reproduce the above copyright |**
  14. **| notice, this list of conditions and the following disclaimer in |**
  15. **| the documentation and/or other materials provided with the |**
  16. **| distribution. |**
  17. **| * Neither the name Texas Instruments nor the names of its |**
  18. **| contributors may be used to endorse or promote products derived |**
  19. **| from this software without specific prior written permission. |**
  20. **| |**
  21. **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
  22. **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
  23. **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
  24. **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
  25. **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
  26. **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
  27. **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
  28. **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
  29. **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
  30. **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
  31. **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
  32. **| |**
  33. **+-----------------------------------------------------------------------+**
  34. ****************************************************************************/
  35. /****************************************************************************
  36. *
  37. * MODULE: FwEvent.c
  38. *
  39. * PURPOSE: Handle firmware events
  40. *
  41. * DESCRIPTION:
  42. * ============
  43. * Call the appropriate event handler.
  44. *
  45. ****************************************************************************/
  46. #include "osTIType.h"
  47. #include "commonTypes.h"
  48. #include "tnetwCommon.h"
  49. #include "TNETWIF.h"
  50. #include "TNETWArb.h"
  51. #include "txResult_api.h"
  52. #include "osApi.h"
  53. #include "whalBus_Api.h"
  54. #include "CmdMBox_api.h"
  55. #include "TNETW_Driver.h"
  56. #include "whalCtrl.h"
  57. #include "shmBus.h"
  58. #include "rxXfer_api.h"
  59. #include "FwEvent.h"
  60. #include "eventMbox_api.h"
  61. #ifdef TI_DBG
  62. #include "DebugTraceXfer_api.h"
  63. #endif /* TI_DBG */
  64. /* for debug only */
  65. #undef DEBUG_INTERRUPTS_PRINT
  66. /********************* static function declerations *************************/
  67. static void FwEvent_ReadRegCB (TI_HANDLE hFwEvent, UINT8 moduleID, TI_STATUS status);
  68. static void FwEvent_WriteMaskCB (TI_HANDLE hFwEvent, UINT8 moduleID, TI_STATUS status);
  69. static void FwEvent_WriteMuxCB (TI_HANDLE hFwEvent, UINT8 moduleID, TI_STATUS status);
  70. static void FwEvent_UpdateRxBits (TI_HANDLE hFwEvent);
  71. /* Client info structure */
  72. typedef struct
  73. {
  74. /* Client event bit in interrupt status register */
  75. UINT32 event;
  76. /* Client handler */
  77. TI_STATUS (*func) (TI_HANDLE hclient);
  78. /* Client corresponding trace message */
  79. char *trace;
  80. } FwClient_t;
  81. /*
  82. * NOTE: Register clients in order of their priorities.
  83. * The command mailbox priority is higher than that of event mailbox.
  84. * This ensures the command complete callback always arrives before event.
  85. */
  86. static const FwClient_t fwClient [MAX_EVENT_NUM] =
  87. {
  88. { ACX_INTR_RX0_DATA, rxXfer_RxEvent, "ACX_INTR_RX0_DATA" },
  89. { ACX_INTR_TX_RESULT, txResult_TxCmpltIntrCB, "ACX_INTR_TX_RESULT" },
  90. { ACX_INTR_RX1_DATA, rxXfer_RxEvent, "ACX_INTR_RX1_DATA" },
  91. { ACX_INTR_CMD_COMPLETE, CmdMBox_CmdCmplt, "ACX_INTR_CMD_COMPLETE" },
  92. { ACX_INTR_EVENT_A, eventMbox_Event, "ACX_INTR_EVENT_A" },
  93. { ACX_INTR_EVENT_B, eventMbox_Event, "ACX_INTR_EVENT_B" },
  94. #ifdef TI_DBG
  95. { ACX_INTR_TRACE_A, debugTrace_Event, "ACX_INTR_TRACE_A" },
  96. { ACX_INTR_TRACE_B, debugTrace_Event, "ACX_INTR_TRACE_B" },
  97. #endif
  98. };
  99. /****************************************************************************
  100. * FwEvent_Create()
  101. ****************************************************************************
  102. * DESCRIPTION: Create the FwEvent module object
  103. *
  104. * INPUTS: None
  105. *
  106. * OUTPUT: None
  107. *
  108. * RETURNS: The Created object
  109. ****************************************************************************/
  110. TI_HANDLE FwEvent_Create (TI_HANDLE hOs)
  111. {
  112. FwEventObj_t *pFwEvent;
  113. pFwEvent = os_memoryAlloc (hOs, sizeof(FwEventObj_t));
  114. if (pFwEvent == NULL)
  115. {
  116. return NULL;
  117. }
  118. os_memoryZero (hOs, pFwEvent, sizeof(FwEventObj_t));
  119. pFwEvent->hOs = hOs;
  120. return (TI_HANDLE)pFwEvent;
  121. } /* FwEvent_Create() */
  122. /****************************************************************************
  123. * FwEvent_Destroy()
  124. ****************************************************************************
  125. * DESCRIPTION: Destroy the FwEvent module object
  126. *
  127. * INPUTS: hFwEvent - The object to free
  128. *
  129. * OUTPUT: None
  130. *
  131. * RETURNS: OK
  132. ****************************************************************************/
  133. TI_STATUS FwEvent_Destroy (TI_HANDLE hFwEvent)
  134. {
  135. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  136. if (pFwEvent)
  137. {
  138. os_memoryFree (pFwEvent->hOs, pFwEvent, sizeof(FwEventObj_t));
  139. }
  140. return TNETWIF_OK;
  141. } /* FwEvent_Destroy() */
  142. /****************************************************************************
  143. * FwEvent_Config()
  144. ****************************************************************************
  145. * DESCRIPTION: Config the FwEvent module object
  146. *
  147. * INPUTS: hTNETW_Driver - TNETW Driver handle
  148. * hhFwEvent - FwEvent handle;
  149. *
  150. * OUTPUT: None
  151. *
  152. * RETURNS: None
  153. ****************************************************************************/
  154. VOID FwEvent_Config (TI_HANDLE hFwEvent, TI_HANDLE hTnetwDrv)
  155. {
  156. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  157. TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
  158. pFwEvent->hOs = pTnetwDrv->hOs;
  159. pFwEvent->hReport = pTnetwDrv->hReport;
  160. pFwEvent->hTNETWIF = pTnetwDrv->hTNETWIF;
  161. /* Register clients in order of their priorities */
  162. pFwEvent->hClient[0] = pTnetwDrv->hRxXfer;
  163. pFwEvent->hClient[1] = pTnetwDrv->hTxResult;
  164. pFwEvent->hClient[2] = pTnetwDrv->hRxXfer;
  165. pFwEvent->hClient[3] = pTnetwDrv->hCmdMBox;
  166. pFwEvent->hClient[4] = pTnetwDrv->hEventMbox;
  167. pFwEvent->hClient[5] = pTnetwDrv->hEventMbox;
  168. #ifdef TI_DBG
  169. pFwEvent->hClient[6] = pTnetwDrv->hDebugTrace;
  170. pFwEvent->hClient[7] = pTnetwDrv->hDebugTrace;
  171. #endif /* TI_DBG */
  172. pFwEvent->FwEventState = FW_EVENT_STATE_IDLE;
  173. pFwEvent->EventMask = 0;
  174. /* Setting the RxControlAddr to 0 indicates that it shouldn't be used */
  175. pFwEvent->RxControlAddr = 0;
  176. pFwEvent->uNumOfRxHandled = 0;
  177. /* Before reading the first Fw Rx counters act like there's no Rx. This is done for the init phase */
  178. pFwEvent->uFwRxCounter = 0;
  179. } /* FwEvent_Config() */
  180. /****************************************************************************
  181. * FwEvent_SetHwInfo()
  182. ****************************************************************************
  183. * DESCRIPTION: Set the rx control address. This is the register to be read
  184. for the Fw Rx counters. Before this function is called we don't
  185. use that variable.
  186. *
  187. * INPUTS: hFwEvent - FwEvent handle;
  188. * pDataPathParams - struct to read the Address from
  189. *
  190. * OUTPUT: None
  191. *
  192. * RETURNS: None
  193. ****************************************************************************/
  194. void FwEvent_SetHwInfo (TI_HANDLE hFwEvent, ACXDataPathParamsResp_t *pDataPathParams)
  195. {
  196. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  197. pFwEvent->RxControlAddr = pDataPathParams->rxControlAddr;
  198. WLAN_REPORT_INFORMATION (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  199. ("%s: RxControlAddr=0x%x\n", __FUNCTION__, pFwEvent->RxControlAddr));
  200. }
  201. /****************************************************************************
  202. * FwEvent_CallHandler()
  203. ****************************************************************************
  204. * DESCRIPTION: Call FwEvent client's event handler
  205. *
  206. * INPUTS: hFwEvent - The object
  207. *
  208. * OUTPUT: None
  209. *
  210. * RETURNS: NOK, TNETWIF_COMPLETE, TNETWIF_PENDING
  211. ****************************************************************************/
  212. static TI_STATUS FwEvent_CallHandler (TI_HANDLE hFwEvent)
  213. {
  214. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  215. TI_STATUS rc;
  216. if (pFwEvent->EventVector == 0)
  217. {
  218. return NOK;
  219. }
  220. while ((pFwEvent->EventNum < MAX_EVENT_NUM) &&
  221. (pFwEvent->EventVector & fwClient[pFwEvent->EventNum].event) == 0)
  222. pFwEvent->EventNum ++;
  223. if (pFwEvent->EventNum < MAX_EVENT_NUM)
  224. {
  225. /* Negate corresponding bit in event vector */
  226. pFwEvent->EventVector &= ~fwClient[pFwEvent->EventNum].event;
  227. /* Call client handler */
  228. rc = fwClient[pFwEvent->EventNum].func (pFwEvent->hClient[pFwEvent->EventNum]);
  229. WLAN_REPORT_INFORMATION (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  230. ("FwEvent_CallHandler: %s, return=%u\n", fwClient[pFwEvent->EventNum].trace, rc));
  231. return rc;
  232. }
  233. return NOK;
  234. } /* FwEvent_CallHandler */
  235. /****************************************************************************
  236. * FwEvent_StateMachine()
  237. ****************************************************************************
  238. * DESCRIPTION: Manage the FwEvent state machine
  239. *
  240. * INPUTS: hFwEvent - The object
  241. * rc - Code passed FwEvent_EventComplete(), either OK or MORE
  242. *
  243. * OUTPUT: None
  244. *
  245. * RETURNS: None
  246. ****************************************************************************/
  247. static void FwEvent_StateMachine (TI_HANDLE hFwEvent, systemStatus_e rc)
  248. {
  249. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  250. while (rc != TNETWIF_PENDING)
  251. {
  252. switch (pFwEvent->FwEventState)
  253. {
  254. case FW_EVENT_STATE_WAIT_BUS_I:
  255. pFwEvent->PendingEvent = FALSE;
  256. pFwEvent->FwEventState = FW_EVENT_STATE_WAIT_MASK;
  257. /*
  258. * We reach this state after TNETWIF_Start CB
  259. * mask the interrupts in the FW
  260. */
  261. rc = TNETWIF_WriteRegOpt (pFwEvent->hTNETWIF,
  262. HINT_MASK,
  263. ACX_INTR_ALL,
  264. FW_EVENT_MODULE_ID,
  265. FwEvent_WriteMaskCB,
  266. hFwEvent);
  267. break;
  268. case FW_EVENT_STATE_WAIT_MASK:
  269. pFwEvent->FwEventState = FW_EVENT_STATE_WAIT_UNMUX;
  270. if (OK == TNETWIF_UnMux (pFwEvent->hTNETWIF))
  271. {
  272. rc = TNETWIF_WriteELPOpt (pFwEvent->hTNETWIF,
  273. 0x1,/*ELPCTRL_WAKE_UP*/
  274. FW_EVENT_MODULE_ID,
  275. FwEvent_WriteMuxCB,
  276. hFwEvent,
  277. TRUE);
  278. }
  279. else
  280. {
  281. rc = TNETWIF_COMPLETE;
  282. }
  283. break;
  284. case FW_EVENT_STATE_WAIT_UNMUX:
  285. case FW_EVENT_STATE_WAIT_BUS_II:
  286. pFwEvent->LoopCounter++;
  287. /* Read the rx counters if the Address was configured */
  288. if (pFwEvent->RxControlAddr)
  289. {
  290. pFwEvent->FwEventState = FW_EVENT_STATE_WAIT_HINT_READ;
  291. }
  292. /* Rx Address was not configured yet. Jump over the read counters state */
  293. else
  294. {
  295. pFwEvent->FwEventState = FW_EVENT_STATE_WAIT_READ_COUNTERS;
  296. }
  297. /*
  298. * We reach this state after TNETWIF_Start CB
  299. * mask the interrupts in the FW
  300. */
  301. rc = TNETWIF_ReadRegOpt (pFwEvent->hTNETWIF,
  302. ACX_REG_INTERRUPT_CLEAR,
  303. &pFwEvent->EventVector,
  304. FW_EVENT_MODULE_ID,
  305. FwEvent_ReadRegCB,
  306. hFwEvent);
  307. break;
  308. case FW_EVENT_STATE_WAIT_HINT_READ:
  309. /*
  310. * Read Fw rx counters. This is needed due to a BUG in the Rx bits which causes to loose bits in the
  311. * EventVector, and therefore we can't relay on the HINT read. The BUG is Fw/Hw related
  312. */
  313. pFwEvent->FwEventState = FW_EVENT_STATE_WAIT_READ_COUNTERS;
  314. rc = TNETWIF_ReadMemOpt (pFwEvent->hTNETWIF,
  315. pFwEvent->RxControlAddr,
  316. PADREAD (&pFwEvent->uFwRxCounter),
  317. sizeof(UINT32),
  318. FW_EVENT_MODULE_ID,
  319. FwEvent_ReadRegCB,
  320. hFwEvent);
  321. break;
  322. case FW_EVENT_STATE_WAIT_READ_COUNTERS:
  323. WLAN_REPORT_INFORMATION(pFwEvent->hReport,FW_EVENT_MODULE_LOG,
  324. ("Reading HostIntRegister = 0x%x, FwRxCounter = 0x%x DriverRxCounter = 0x%x\n",
  325. pFwEvent->EventVector, pFwEvent->uFwRxCounter, pFwEvent->uNumOfRxHandled));
  326. /*
  327. * Mask unwanted interrupts.
  328. */
  329. pFwEvent->EventVector &= pFwEvent->EventMask;
  330. /* Work-around: check if there's a missing Rx bit (or 2 bits) in the Register */
  331. FwEvent_UpdateRxBits (hFwEvent);
  332. if (pFwEvent->EventVector == 0)
  333. {
  334. #ifdef LEVEL_IRQ
  335. /* if working level sensitive mode we must first enable IRQ source */
  336. os_enableIrq(pFwEvent->hOs);
  337. #endif
  338. pFwEvent->FwEventState = FW_EVENT_STATE_WAIT_UNMASK;
  339. /* Unmask the interrupts in the FW */
  340. rc = TNETWIF_WriteRegOpt (pFwEvent->hTNETWIF,
  341. HINT_MASK,
  342. ~pFwEvent->EventMask,
  343. FW_EVENT_MODULE_ID,
  344. FwEvent_WriteMaskCB,
  345. hFwEvent);
  346. }
  347. else
  348. {
  349. pFwEvent->FwEventState = FW_EVENT_STATE_HANDLE_EVENT;
  350. rc = TNETWIF_COMPLETE;
  351. }
  352. break;
  353. case FW_EVENT_STATE_HANDLE_EVENT:
  354. if ((rc = FwEvent_CallHandler (hFwEvent)) == NOK)
  355. {
  356. /* All events have been handled, break the loop */
  357. if (pFwEvent->LoopCounter < NUM_OF_READ_REG_LOOPS)
  358. {
  359. /* Restart */
  360. pFwEvent->FwEventState = FW_EVENT_STATE_WAIT_BUS_II;
  361. rc = TNETWIF_Restart (pFwEvent->hTNETWIF,
  362. FW_EVENT_MODULE_ID,
  363. hFwEvent,
  364. FwEvent_BusReadyCB);
  365. }
  366. else
  367. {
  368. #ifdef LEVEL_IRQ
  369. /* if working level sensitive mode we must first enable IRQ source */
  370. os_enableIrq(pFwEvent->hOs);
  371. #endif
  372. /* Unmask the interrupts in the FW */
  373. pFwEvent->FwEventState = FW_EVENT_STATE_WAIT_UNMASK;
  374. rc = TNETWIF_WriteRegOpt (pFwEvent->hTNETWIF,
  375. HINT_MASK,
  376. ~pFwEvent->EventMask,
  377. FW_EVENT_MODULE_ID,
  378. FwEvent_WriteMaskCB,
  379. hFwEvent);
  380. }
  381. }
  382. break;
  383. case FW_EVENT_STATE_WAIT_UNMASK:
  384. /* We get here after unmask CB */
  385. if (pFwEvent->PendingEvent)
  386. {
  387. pFwEvent->PendingEvent = FALSE;
  388. pFwEvent->FwEventState = FW_EVENT_STATE_WAIT_BUS_I;
  389. TNETWIF_Restart (pFwEvent->hTNETWIF,
  390. FW_EVENT_MODULE_ID,
  391. hFwEvent,
  392. FwEvent_BusReadyCB);
  393. }
  394. else
  395. {
  396. pFwEvent->FwEventState = FW_EVENT_STATE_IDLE;
  397. TNETWIF_Finish (pFwEvent->hTNETWIF, FW_EVENT_MODULE_ID, NULL, NULL);
  398. }
  399. rc = TNETWIF_PENDING;
  400. break;
  401. case FW_EVENT_STATE_IDLE:
  402. default:
  403. WLAN_REPORT_ERROR (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  404. ("FwEvent_StateMachine - invalid state\n"));
  405. rc = TNETWIF_PENDING;
  406. break;
  407. } /* switch */
  408. if (TNETWIF_ERROR == rc)
  409. {
  410. WLAN_REPORT_ERROR (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  411. ("FwEvent_StateMachine rc = TNETWIF_ERROR !!! in state = %d\n",
  412. pFwEvent->FwEventState));
  413. }
  414. } /* while */
  415. } /* FwEvent_StateMachine() */
  416. /****************************************************************************
  417. * FwEvent()
  418. ****************************************************************************
  419. * DESCRIPTION: Start FwEvent
  420. *
  421. * INPUTS: hFwEvent - The object
  422. *
  423. * OUTPUT: None
  424. *
  425. * RETURNS: OK - if in Idle NOK - else
  426. ****************************************************************************/
  427. TI_STATUS FwEvent (TI_HANDLE hFwEvent)
  428. {
  429. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  430. /* NOTE: pFwEvent may be uninitialized at init stage */
  431. if (pFwEvent != NULL)
  432. {
  433. if (pFwEvent->FwEventState == FW_EVENT_STATE_IDLE)
  434. {
  435. pFwEvent->IntrState = STATE_DPC;
  436. pFwEvent->EventVector = 0;
  437. pFwEvent->LoopCounter = 0;
  438. pFwEvent->FwEventState = FW_EVENT_STATE_WAIT_BUS_I;
  439. /* NOTE: hTNETWIF may be uninitialized at init */
  440. if (pFwEvent->hTNETWIF != NULL)
  441. {
  442. TNETWIF_Start (pFwEvent->hTNETWIF, FW_EVENT_MODULE_ID, hFwEvent, FwEvent_BusReadyCB);
  443. }
  444. }
  445. else if (pFwEvent->FwEventState == FW_EVENT_STATE_WAIT_UNMASK)
  446. {
  447. pFwEvent->LoopCounter = 0;
  448. /*
  449. * If an interrupt receiving while unmasking the previous, sign it as pending and exit.
  450. * It will be handled in the next iteration after Restart.
  451. */
  452. pFwEvent->PendingEvent = TRUE;
  453. }
  454. else
  455. {
  456. WLAN_REPORT_WARNING (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  457. ("FwEvent() entering SM not in Idle !!! state: %d\n",
  458. pFwEvent->FwEventState));
  459. return NOK;
  460. }
  461. }
  462. return OK;
  463. } /* FwEvent() */
  464. /****************************************************************************
  465. * FwEvent_BusReadyCB()
  466. ****************************************************************************
  467. * DESCRIPTION: FwEvent_BusReadyCB
  468. *
  469. * INPUTS: hFwEvent - The object
  470. *
  471. * OUTPUT: None
  472. *
  473. * RETURNS: None
  474. ****************************************************************************/
  475. void FwEvent_BusReadyCB (TI_HANDLE hFwEvent, UINT8 module_id, TI_STATUS status)
  476. {
  477. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  478. if (pFwEvent->FwEventState == FW_EVENT_STATE_WAIT_BUS_I ||
  479. pFwEvent->FwEventState == FW_EVENT_STATE_WAIT_BUS_II)
  480. {
  481. /*
  482. * NOTE: init the EventNum here for it take effect both for Start and Restart
  483. */
  484. pFwEvent->EventNum = 0;
  485. FwEvent_StateMachine (hFwEvent, TNETWIF_NONE);
  486. }
  487. else
  488. {
  489. WLAN_REPORT_ERROR (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  490. ("FwEvent_BusReadyCB() state(%d) is not FW_EVENT_STATE_READ_REG\n",
  491. pFwEvent->FwEventState));
  492. }
  493. } /* FwEvent_BusReadyCB() */
  494. /****************************************************************************
  495. * FwEvent_WriteMaskCB()
  496. ****************************************************************************
  497. * DESCRIPTION: Write Mask CB
  498. *
  499. * INPUTS: hFwEvent - The object
  500. *
  501. * OUTPUT: None
  502. *
  503. * RETURNS: None
  504. ****************************************************************************/
  505. void FwEvent_WriteMaskCB (TI_HANDLE hFwEvent, UINT8 moduleID, TI_STATUS status)
  506. {
  507. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  508. if (pFwEvent->FwEventState == FW_EVENT_STATE_WAIT_MASK ||
  509. pFwEvent->FwEventState == FW_EVENT_STATE_WAIT_UNMASK)
  510. {
  511. FwEvent_StateMachine (hFwEvent, TNETWIF_NONE);
  512. }
  513. else
  514. {
  515. WLAN_REPORT_ERROR (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  516. ("FwEvent_WriteMaskCB() shouldn't be called with state(%d)\n",
  517. pFwEvent->FwEventState));
  518. }
  519. } /* FwEvent_WriteMaskCB() */
  520. /****************************************************************************
  521. * FwEvent_WriteMuxCB()
  522. ****************************************************************************
  523. * DESCRIPTION: Write Mask CB
  524. *
  525. * INPUTS: hFwEvent - The object
  526. *
  527. * OUTPUT: None
  528. *
  529. * RETURNS: None
  530. ****************************************************************************/
  531. void FwEvent_WriteMuxCB (TI_HANDLE hFwEvent, UINT8 moduleID, TI_STATUS status)
  532. {
  533. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  534. if (pFwEvent->FwEventState == FW_EVENT_STATE_WAIT_UNMUX)
  535. {
  536. FwEvent_StateMachine (hFwEvent, TNETWIF_NONE);
  537. }
  538. else
  539. {
  540. WLAN_REPORT_ERROR (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  541. ("FwEvent_WriteMaskCB() shouldn't be called with state(%d)\n",
  542. pFwEvent->FwEventState));
  543. }
  544. } /* FwEvent_WriteMaskCB() */
  545. /****************************************************************************
  546. * FwEvent_ReadRegCB()
  547. ****************************************************************************
  548. * DESCRIPTION: FwEvent_ReadRegCB
  549. *
  550. * INPUTS: hFwEvent - The object
  551. *
  552. * OUTPUT: None
  553. *
  554. * RETURNS: None
  555. ****************************************************************************/
  556. void FwEvent_ReadRegCB (TI_HANDLE hFwEvent, UINT8 moduleID, TI_STATUS status)
  557. {
  558. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  559. if ((pFwEvent->FwEventState == FW_EVENT_STATE_WAIT_HINT_READ) ||
  560. (pFwEvent->FwEventState == FW_EVENT_STATE_WAIT_READ_COUNTERS))
  561. {
  562. FwEvent_StateMachine (hFwEvent, TNETWIF_NONE);
  563. }
  564. else
  565. {
  566. WLAN_REPORT_ERROR (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  567. ("FwEvent_ReadRegCB() is in state(%d)\n",
  568. pFwEvent->FwEventState));
  569. }
  570. } /* FwEvent_BusReadyCB() */
  571. /****************************************************************************
  572. * FwEvent_UpdateRxBits()
  573. ****************************************************************************
  574. * DESCRIPTION: Update the EventVector according to the Fw counter of Rx.
  575. * The Rx bits from the EventVector are ignored and instead we are
  576. * using the Fw counters in order to decide how many Rx should we read.
  577. * Using this method is due to a Hw/Fw bug in which we miss some of the
  578. * Rx bits in the EventVector.
  579. *
  580. * INPUTS: pFwEvent - The object
  581. *
  582. * OUTPUT: pFwEvent->EventVector - Add Rx bit if needed
  583. *
  584. * RETURNS: None
  585. ****************************************************************************/
  586. void FwEvent_UpdateRxBits (TI_HANDLE hFwEvent)
  587. {
  588. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  589. UINT32 uFwDriverDiff = pFwEvent->uFwRxCounter - pFwEvent->uNumOfRxHandled;
  590. /* use only the last 4 bits since the Fw is using 4 bits */
  591. uFwDriverDiff &= 0xf;
  592. /* Use the diff to add the number of bits needed for handling */
  593. switch (uFwDriverDiff)
  594. {
  595. case 0:
  596. /* Erase Rx bits */
  597. pFwEvent->EventVector &= ~ACX_INTR_RX0_DATA;
  598. pFwEvent->EventVector &= ~ACX_INTR_RX1_DATA;
  599. break;
  600. case 1:
  601. /* Add only one bit */
  602. pFwEvent->EventVector |= ACX_INTR_RX0_DATA;
  603. pFwEvent->EventVector &= ~ACX_INTR_RX1_DATA;
  604. break;
  605. case 2:
  606. /* Add the 2 bits */
  607. pFwEvent->EventVector |= ACX_INTR_RX0_DATA;
  608. pFwEvent->EventVector |= ACX_INTR_RX1_DATA;
  609. break;
  610. default:
  611. /*
  612. * This is a very bad case were there is no synchronization between Driver & FW. In order to recover from this
  613. * state we will use the the EventVector "as-is" and hope for the best...
  614. */
  615. WLAN_REPORT_ERROR (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  616. ("%s Fw = 0x%x Dr = 0x%x\n", __FUNCTION__, pFwEvent->uFwRxCounter, pFwEvent->uNumOfRxHandled));
  617. break;
  618. }
  619. /* This will make sure that next time we will be synchronized with the Fw */
  620. pFwEvent->uNumOfRxHandled = pFwEvent->uFwRxCounter;
  621. }
  622. /****************************************************************************
  623. * FwEvent_EventComplete()
  624. ****************************************************************************
  625. * DESCRIPTION: FwEvent_EventComplete
  626. *
  627. * INPUTS: hFwEvent - The object
  628. * rc - OK or MORE
  629. *
  630. * OUTPUT: None
  631. *
  632. * RETURNS: None
  633. ****************************************************************************/
  634. void FwEvent_EventComplete (TI_HANDLE hFwEvent, systemStatus_e rc)
  635. {
  636. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  637. if (pFwEvent->FwEventState == FW_EVENT_STATE_HANDLE_EVENT)
  638. {
  639. FwEvent_StateMachine (hFwEvent,rc);
  640. }
  641. else
  642. {
  643. WLAN_REPORT_ERROR (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  644. ("FwEvent_EventComplete() state(%d) is not FW_EVENT_STATE_PENDING\n",
  645. pFwEvent->FwEventState));
  646. }
  647. } /* FwEvent_EventComplete() */
  648. /****************************************************************************
  649. * FwEvent_Enable()
  650. ****************************************************************************
  651. * DESCRIPTION: enable specific interrupt
  652. *
  653. * INPUTS:
  654. *
  655. * OUTPUT:
  656. ****************************************************************************/
  657. void FwEvent_Enable (TI_HANDLE hFwEvent, UINT32 uEventMask)
  658. {
  659. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  660. pFwEvent->EventMask |= uEventMask;
  661. WLAN_REPORT_INFORMATION (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  662. ("%s: EventMask = 0x%x\n", __FUNCTION__, pFwEvent->EventMask));
  663. }
  664. /****************************************************************************
  665. * FwEvent_Disable()
  666. ****************************************************************************
  667. * DESCRIPTION: disables specific interrupt
  668. *
  669. * INPUTS:
  670. *
  671. * OUTPUT:
  672. ****************************************************************************/
  673. void FwEvent_Disable (TI_HANDLE hFwEvent, UINT32 uEventMask)
  674. {
  675. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  676. pFwEvent->EventMask &= ~uEventMask;
  677. WLAN_REPORT_INFORMATION (pFwEvent->hReport, FW_EVENT_MODULE_LOG,
  678. ("%s: EventMask = 0x%x\n", __FUNCTION__, pFwEvent->EventMask));
  679. }
  680. /****************************************************************************
  681. * FwEvent_GetEnabled()
  682. ****************************************************************************
  683. * DESCRIPTION: returns interrupt enabled bit mask
  684. *
  685. * INPUTS:
  686. *
  687. * OUTPUT:
  688. ****************************************************************************/
  689. UINT32 FwEvent_GetEnabled (TI_HANDLE hFwEvent)
  690. {
  691. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  692. return pFwEvent->EventMask;
  693. }
  694. /******************************************************************************************************
  695. *
  696. * Functions originally located at whalHwIntr.c - Not used in the current version and might be removed
  697. *
  698. *******************************************************************************************************/
  699. /****************************************************************************
  700. * FwEvent_EnableInterrupts()
  701. ****************************************************************************
  702. * DESCRIPTION: Enable interrupts
  703. *
  704. * INPUTS:
  705. *
  706. * OUTPUT: None
  707. *
  708. * NOTE: Originally located at whalHwIntr.c .
  709. ****************************************************************************/
  710. void FwEvent_EnableInterrupts (TI_HANDLE hFwEvent)
  711. {
  712. #ifdef USE_SYNC_API
  713. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  714. /* Clearing all the interrupt status register sources */
  715. TNETWIF_WriteRegSync (pFwEvent->hTNETWIF, ACX_REG_INTERRUPT_MASK, ~pFwEvent->EventMask);
  716. /*
  717. * Setting the right operation of the interrupt
  718. * bit 5 - enable interrupt
  719. * bit 7 - active low
  720. */
  721. TNETWIF_WriteRegSync (pFwEvent->hTNETWIF, HI_CFG, HI_CFG_DEF_VAL);
  722. #ifdef DEBUG_INTERRUPTS_PRINT
  723. WLAN_REPORT_INFORMATION (pFwEvent->hReport,
  724. FW_EVENT_MODULE_LOG,
  725. ("FwEvent_EnableInterrupts(0x%08X)",
  726. pFwEvent->EventMask));
  727. #endif /* DEBUG_INTERRUPTS_PRINT */
  728. #if defined(HAL_ON_WIN)
  729. /* (!!!) only in CardBus, add HostIfType parameter */
  730. /* Enable Interrupt on a CardBus */
  731. TNETWIF_WriteRegSync (pFwEvent->hTNETWIF, FEMR, 0x8000);
  732. #endif
  733. #endif /* USE_SYNC_API */
  734. }
  735. /****************************************************************************
  736. * FwEvent_DisableInterrupts()
  737. ****************************************************************************
  738. * DESCRIPTION: Disable interrupts
  739. *
  740. * INPUTS:
  741. *
  742. * OUTPUT: None
  743. *
  744. * RETURNS:
  745. ****************************************************************************/
  746. void FwEvent_DisableInterrupts (TI_HANDLE hFwEvent)
  747. {
  748. #ifdef USE_SYNC_API
  749. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  750. TNETWIF_WriteRegSync (pFwEvent->hTNETWIF, ACX_REG_INTERRUPT_MASK, ACX_INTR_ALL );
  751. #ifdef DEBUG_INTERRUPTS_PRINT
  752. WLAN_REPORT_INFORMATION (pFwEvent->hReport,
  753. FW_EVENT_MODULE_LOG,
  754. ("FwEvent_DisableInterrupts(0x%08X)",
  755. ACX_INTR_ALL));
  756. #endif /* DEBUG_INTERRUPTS_PRINT */
  757. #endif /* USE_SYNC_API */
  758. }
  759. /****************************************************************************
  760. * FwEvent_CheckInterrupts()
  761. ****************************************************************************
  762. * DESCRIPTION: Check if there is interrupts (only unmasked)
  763. *
  764. * INPUTS:
  765. *
  766. * OUTPUT: None
  767. *
  768. * RETURNS: 0 - no interrupts, otherwise - there are interrupts
  769. ****************************************************************************/
  770. UINT32 FwEvent_CheckInterrupts (TI_HANDLE hFwEvent)
  771. {
  772. #ifdef USE_SYNC_API
  773. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  774. register UINT32 CurrentIntr;
  775. UINT32 interruptRegVal;
  776. register UINT32 maskInterruptVal;
  777. #ifdef DEBUG_INTERRUPTS_PRINT
  778. UINT32 endReg;
  779. #endif /* DEBUG_INTERRUPTS_PRINT */
  780. if (pFwEvent->IntrState != STATE_OPERATIONAL)
  781. {
  782. /*
  783. ISR can't be called till the state will be operational again because the ISR
  784. disable the interrupts of the TNET thus if this function is called then it need
  785. to return 0!!!
  786. */
  787. #ifdef DEBUG_INTERRUPTS_PRINT
  788. WLAN_REPORT_WARNING (pFwEvent->hReport,
  789. FW_EVENT_MODULE_LOG,
  790. ("FwEvent_CheckInterrupts() - state isn't STATE_OPERATIONAL (=%d) - ABRTING!\n",
  791. pFwEvent->IntrState));
  792. #endif /* DEBUG_INTERRUPTS_PRINT */
  793. }
  794. #ifdef HW_ACCESS_DEBUG_ACCESS_VIOLATION
  795. whal_hwAccess_setOverrideElpCheck ((TI_HANDLE)pFwEvent->hTNETWIF, TRUE);
  796. #endif /* HW_ACCESS_DEBUG_ACCESS_VIOLATION */
  797. /*read the status register*/
  798. TNETWIF_ReadRegSync (pFwEvent->hTNETWIF, ACX_REG_INTERRUPT_NO_CLEAR, &interruptRegVal);
  799. CurrentIntr = interruptRegVal;
  800. /* 0xFFFF means that the card is disconnected !!! */
  801. if ((CurrentIntr & 0xffff) == 0xffff) /* error */
  802. CurrentIntr = 0;
  803. /* check with the interrupt mask register */
  804. maskInterruptVal = pFwEvent->EventMask;
  805. CurrentIntr &= maskInterruptVal;
  806. if (interruptRegVal != CurrentIntr)
  807. {
  808. #ifdef DEBUG_INTERRUPTS_PRINT
  809. WLAN_REPORT_ERROR(pFwEvent->hReport,
  810. FW_EVENT_MODULE_LOG,
  811. ("%s(%d) - interrupt vector include masked interrupts\n.\
  812. interruptRegVal = 0x%08X\n\
  813. hwMaskInterruptVal= 0x%08X\n\
  814. swMaskInterruptVal= 0x%08X\n\
  815. currrentInt = 0x%08X\n\
  816. diverse = 0x%08X\n\
  817. IntrState = %d\n",
  818. __FILE__,__LINE__,
  819. interruptRegVal,
  820. maskInterruptVal,
  821. pFwEvent->EventMask,
  822. CurrentIntr,
  823. (CurrentIntr ^ interruptRegVal),
  824. pFwEvent->IntrState));
  825. #endif /* DEBUG_INTERRUPTS_PRINT */
  826. }
  827. #ifdef ACK_ON_CHECK_PHASE
  828. /* set ACK to the interrupts on the check phase */
  829. if (CurrentIntr != 0)
  830. {
  831. /* Save the occurring interrupts - to handle interrupt routine */
  832. pFwEvent->SaveIntrValue |= CurrentIntr;
  833. HW_INTR_ACK(pFwEvent->hTNETWIF, CurrentIntr);
  834. /*
  835. state is now wait for DPC
  836. */
  837. pFwEvent->IntrState = STATE_WAIT_FOR_DPC;
  838. }
  839. #endif /* ACK_ON_CHECK_PHASE */
  840. #ifdef DEBUG_INTERRUPTS_PRINT
  841. TNETWIF_ReadRegSync (pFwEvent->hTNETWIF, ACX_REG_INTERRUPT_NO_CLEAR, &endReg);
  842. WLAN_REPORT_INFORMATION(pFwEvent->hReport,
  843. FW_EVENT_MODULE_LOG,
  844. ("%s(%d) - finish ISR ,endReg... \n.\
  845. Intr = 0x%08X\n",
  846. __FILE__,__LINE__,
  847. endReg));
  848. #endif /* DEBUG_INTERRUPTS_PRINT */
  849. #ifdef HW_ACCESS_DEBUG_ACCESS_VIOLATION
  850. whal_hwAccess_setOverrideElpCheck ((TI_HANDLE)pFwEvent->hTNETWIF, FALSE);
  851. #endif /* HW_ACCESS_DEBUG_ACCESS_VIOLATION */
  852. /* (!!!1150) Reset the interrupt line*/
  853. TNETWIF_WriteRegSync (pFwEvent->hTNETWIF, PCI_STATUS_CLR_REG, 0x80000000 /*v2p_intr was asserted*/);
  854. return CurrentIntr;
  855. #else
  856. return 0;
  857. #endif /* USE_SYNC_API */
  858. }
  859. /****************************************************************************
  860. * FwEvent_ChangeState()
  861. ****************************************************************************
  862. * DESCRIPTION: Disable interrupts
  863. *
  864. * INPUTS:
  865. *
  866. * OUTPUT: None
  867. *
  868. * RETURNS:
  869. ****************************************************************************/
  870. void FwEvent_ChangeState (TI_HANDLE hFwEvent, int State)
  871. {
  872. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  873. pFwEvent->IntrState = State;
  874. }
  875. /****************************************************************************
  876. * FwEvent_StateChanged()
  877. ****************************************************************************
  878. * DESCRIPTION:
  879. * StateChanged - change mask notification and
  880. * interrupt acknowledge. Used for SDIO driver
  881. *
  882. * RETURNS: None
  883. ****************************************************************************/
  884. void FwEvent_StateChanged (TI_HANDLE hFwEvent)
  885. {
  886. #ifdef USE_SYNC_API
  887. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  888. TNETWIF_WriteRegSync (pFwEvent->hTNETWIF, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_STATE_CHANGED);
  889. #endif
  890. }
  891. /****************************************************************************
  892. * FwEvent_Stop()
  893. ****************************************************************************
  894. * DESCRIPTION: Stop & reser FwEvent (called by the recovery)
  895. *
  896. * INPUTS:
  897. * hhFwEvent - FwEvent handle;
  898. *
  899. * OUTPUT: None
  900. *
  901. * RETURNS: None
  902. ****************************************************************************/
  903. VOID FwEvent_Stop(TI_HANDLE hFwEvent)
  904. {
  905. FwEventObj_t *pFwEvent = (FwEventObj_t *)hFwEvent;
  906. pFwEvent->FwEventState = FW_EVENT_STATE_IDLE;
  907. /* Setting the RxControlAddr to 0 indicates that it shouldn't be used */
  908. pFwEvent->RxControlAddr = 0;
  909. pFwEvent->uNumOfRxHandled = 0;
  910. /* Before reading the first Fw Rx counters act like there's no Rx. This is done for the init phase */
  911. pFwEvent->uFwRxCounter = 0;
  912. } /* FwEvent_Stop() */