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