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: EventMbox.c : event Mail Box
39 * PURPOSE: Handle any event interrupt from the FW
40 *
41 ****************************************************************************/
42
43 #include "commonTypes.h"
44 #include "FwEvent_api.h"
45 #include "whalBus_Api.h"
46 #include "eventMbox_api.h"
47 #include "whalCtrl_api.h"
48 #include "TNETWIF.h"
49
50
51 /*******************************************************************************
52 *
53 * Macros
54 *
55 *******************************************************************************/
56 #define IS_EVENT_BIT_ON(EvVector,EvBit) ( (EvBit) == ( (EvVector) & (EvBit) ) )
57 #define IS_EVENT_BIT_OFF(EvVector,EvBit) ( ~(EvBit) == ( (EvVector) | ~(EvBit) ) )
58
59 #define SET_EVENT_BIT(EvVector,EvBit) ( (EvVector) |= (EvBit) )
60 #define CLEAR_EVENT_BIT(EvVector,EvBit) ( (EvVector) &= ~(EvBit) )
61
62 #define EVENT_REPORT_SIZE 80
63
64 #define EVMBX_DBG 1
65
66
67 /*****************************************************************************
68 ** Enumerations **
69 *****************************************************************************/
70
71 typedef enum
72 {
73 EVENT_MBOX_STATE_IDLE,
74 EVENT_MBOX_STATE_READ_BUF,
75 EVENT_MBOX_STATE_ACK_EVENT
76 } EventMboxState_e;
77
78
79 /*****************************************************************************
80 ** Structures **
81 *****************************************************************************/
82
83 /*
84 * Definition for the Event Table
85 */
86 typedef struct
87 {
88 /* Event bit mask */
89 UINT32 bitMask;
90 /* Event trace string */
91 char* str;
92 /* Event data length */
93 UINT8 dataLen;
94 } EventEntry_t;
95
96
97 /*
98 * Event callback structure
99 */
100 typedef struct
101 {
102 /* Event callback function */
103 void* fCb;
104 /* Event callback module handle */
105 TI_HANDLE hCb;
106 /* Event data offset */
107 UINT8* pDataOffs;
108 /* Event callback counter */
109 UINT32 uCount;
110 } EventCB_t;
111
112
113 /*
114 * Event Mailbox object
115 */
116 typedef struct
117 {
118 /* Offset for event A (0) or event B (1) */
119 UINT32 offset[2];
120 /* 0 or 1 according to event A or B */
121 UINT32 currentEvent;
122 /* Event mail box state machine state */
123 EventMboxState_e state;
124 /* Return value */
125 TI_STATUS returnValue;
126 /* Init complete flag */
127 BOOL bInitComplete;
128 /* Indicate if we are in synchronous bus or not */
129 BOOL bSync;
130 /* Callback table */
131 EventCB_t cbTable[MAX_NUM_OF_EVENT];
132 /* Use a struct to read buffers from the bus - used for extra bytes reserving */
133 PADDING (EventMailBox_t CompoundEvent)
134
135 /* Handles */
136 TI_HANDLE hFwEvent;
137 TI_HANDLE hTNETWIF;
138 TI_HANDLE hOs;
139 TI_HANDLE hReport;
140 TI_HANDLE hWhalCtrl;
141 #ifdef TI_DBG
142 /* Count the compound event */
143 UINT32 uCompounEvCount;
144 /* Count the total number of event sending in the compound */
145 UINT32 uTotalEvCount;
146 #endif /* TI_DBG */
147
148 TNETWIF_callback_t fCb;
149 TI_HANDLE hCb;
150 } EventMbox_t;
151
152 /********************************************************************************/
153 /* Internal functions prototypes. */
154 /********************************************************************************/
155
156 static void eventMbox_HandleEvent (TI_HANDLE hEventMbox);
157 static void eventMbox_StateMachine (TI_HANDLE hEventMbox, UINT8 module_id, TI_STATUS status);
158 static void eventMbox_InitCbTable (TI_HANDLE hEventMbox);
159
160
161 static const EventEntry_t eventTable [MAX_NUM_OF_EVENT] =
162 {
163 /*==================================================================================
164 | |
165 | EVENT TABLE |
166 | |
167 ===================================================================================
168 | Id | Event Mask Bit | Event String | Length |
169 ===================================================================================*/
170
171 /*0*/ { MEASUREMENT_START_EVENT_ID, "MEASUREMENT START " , 0},
172 /*1*/ { SCAN_COMPLETE_EVENT_ID , "SCAN CMPLT " , 3},
173 /*2*/ { CALIBRATION_COMPLETE_EVENT_ID, "CALIB CMPLT " , 0},
174 /*3*/ { ROAMING_TRIGGER_LOW_RSSI_EVENT_ID , "RSSI LEVEL " , 1},
175 /*4*/ { PS_REPORT_EVENT_ID, "PS_REPORT " , 1},
176 /*5*/ { SYNCHRONIZATION_TIMEOUT_EVENT_ID, "SYNCHRONIZATION TIMEOUT ", 0},
177 /*6*/ { HEALTH_REPORT_EVENT_ID, "HEALTH REPORT " , 2},
178 /*7*/ { ACI_DETECTION_EVENT_ID , "ACI INDICATION " , 2},
179 /*8*/ { DEBUG_REPORT_EVENT_ID, "DEBUG REPORT " , 8},
180 /*9*/ { MAC_STATUS_EVENT_ID, "MAC STATUS " , 8},
181 /*10*/{ DISCONNECT_EVENT_COMPLETE_ID, "DISCONNECT COMPLETE " , 0},
182 /*11*/{ JOIN_EVENT_COMPLETE_ID, "JOIN CMPLT " , 0},
183 /*12*/{ CHANNEL_SWITCH_COMPLETE_EVENT_ID, "SWITCH CHANNEL CMPLT " , 0},
184 /*13*/{ BSS_LOSE_EVENT_ID, "BSS LOST " , 0},
185 /*14*/{ ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID, "MAX TX RETRY " , 0},
186 /*15*/{ MEASUREMENT_COMPLETE_EVENT_ID, "BSS LOSE " , 0},
187 /*16*/{ AP_DISCOVERY_COMPLETE_EVENT_ID, "MAX TX RETRY " , 0},
188 /*17*/{ SCHEDULED_SCAN_COMPLETE_EVENT_ID, "SPS SCAN CMPLT " , 3},
189 /*18*/{ REGAINED_BSS_EVENT_ID, "REGAINED BSS " , 0},
190 /*19*/{ ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID, "REGAINED RSSI " , 1},
191 /*20*/{ ROAMING_TRIGGER_LOW_SNR_EVENT_ID, "LOW SNR " , 1},
192 /*21*/{ SOFT_GEMINI_SENSE_EVENT_ID, "SOFT GEMINI SENSE " , 1},
193 /*22*/{ SOFT_GEMINI_PREDICTION_EVENT_ID, "SOFT GEMINI PREDICTION " , 1},
194 /*23*/{ SOFT_GEMINI_AVALANCHE_EVENT_ID, "SOFT GEMINI AVALANCHE " , 0},
195 /*24*/{ PLT_RX_CALIBRATION_COMPLETE_EVENT_ID, "PLT RX CALIBR. COMPLETE ", 0},
196 /*25*/{ PSPOLL_DELIVERY_FAILURE_EVENT_ID, "PS-POLL DELIVERY FAILURE", 0},
197 /*26*/{ RESET_BSS_EVENT_ID, "EVENT RESET BSS " , 0},
198 /*27*/{ EVENT_MBOX_ALL_EVENT_ID, "ALL EVENTS " , 0},
199
200 };
201
202 /********************************************************************************/
203 /* functions implementation */
204 /********************************************************************************/
205
206
207 /****************************************************************************
208 * eventMbox_InitCbTable()
209 ****************************************************************************
210 * DESCRIPTION: Initialization of callback table
211 *
212 * INPUTS: hEventMbox eventMbox module handle
213 *
214 * RETURNS: none
215 ****************************************************************************/
eventMbox_InitCbTable(TI_HANDLE hEventMbox)216 void eventMbox_InitCbTable (TI_HANDLE hEventMbox)
217 {
218 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
219 UINT32 EvID;
220
221 for (EvID = 0; EvID < MAX_NUM_OF_EVENT; EvID++)
222 {
223 pEventMbox->cbTable[EvID].pDataOffs = (UINT8*)&pEventMbox->CompoundEvent;
224 }
225
226 pEventMbox->cbTable[ 3].pDataOffs += offsetof (EventMailBox_t, averageRssiLevel);
227 pEventMbox->cbTable[ 4].pDataOffs += offsetof (EventMailBox_t, psStatus);
228 pEventMbox->cbTable[ 6].pDataOffs += offsetof (EventMailBox_t, healthReport);
229 pEventMbox->cbTable[ 7].pDataOffs += offsetof (EventMailBox_t, badFFTCorrelationCounter);
230 pEventMbox->cbTable[ 8].pDataOffs += offsetof (EventMailBox_t, debugReport);
231 pEventMbox->cbTable[ 9].pDataOffs += offsetof (EventMailBox_t, consFcsErrCnt);
232 pEventMbox->cbTable[17].pDataOffs += offsetof (EventMailBox_t, scheduledScanStatus);
233 pEventMbox->cbTable[19].pDataOffs += offsetof (EventMailBox_t, averageRssiLevel);
234 pEventMbox->cbTable[20].pDataOffs += offsetof (EventMailBox_t, averageSNRLevel);
235 pEventMbox->cbTable[21].pDataOffs += offsetof (EventMailBox_t, softGeminiSenseInfo);
236 pEventMbox->cbTable[22].pDataOffs += offsetof (EventMailBox_t, softGeminiProtectiveInfo);
237 }
238
239
240 /****************************************************************************
241 * eventMbox_Create()
242 ****************************************************************************
243 * DESCRIPTION: Create the Bus Access mailbox object
244 *
245 * RETURNS: The Created object
246 ****************************************************************************/
eventMbox_Create(TI_HANDLE hOs)247 TI_HANDLE eventMbox_Create (TI_HANDLE hOs)
248 {
249 EventMbox_t *pEventMbox;
250
251 pEventMbox = os_memoryAlloc (hOs, sizeof(EventMbox_t));
252 if (pEventMbox == NULL)
253 {
254 WLAN_OS_REPORT (("eventMbox_Create: Error creating EventMbox object\n"));
255 return NULL;
256 }
257
258 os_memoryZero (hOs, pEventMbox, sizeof(EventMbox_t));
259
260 pEventMbox->hOs = hOs;
261 pEventMbox->CompoundEvent.eventsMask = EVENT_MBOX_ALL_EVENT_ID;
262
263 return (TI_HANDLE)pEventMbox;
264 }
265
266
267 /****************************************************************************
268 * eventMbox_Destroy()
269 ****************************************************************************
270 * DESCRIPTION: Destroy the object
271 *
272 ****************************************************************************/
eventMbox_Destroy(TI_HANDLE hEventMbox)273 void eventMbox_Destroy (TI_HANDLE hEventMbox)
274 {
275 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
276
277 if (pEventMbox)
278 {
279 os_memoryFree (pEventMbox->hOs, pEventMbox, sizeof(EventMbox_t));
280 }
281 }
282
283
284 /****************************************************************************
285 * eventMbox_Config()
286 ****************************************************************************
287 * DESCRIPTION: Configure the object
288 *
289 * INPUTS: pEventMbox this
290 * pHwIntr Interrupt Object object
291 * hReport Report Object
292 *
293 * RETURNS: OK or NOK
294 ****************************************************************************/
eventMbox_Config(TI_HANDLE hEventMbox,TI_HANDLE hTNETWIF,TI_HANDLE hHwIntr,TI_HANDLE hReport,TI_HANDLE hFwEvent,TI_HANDLE hWhalCtrl)295 void eventMbox_Config (TI_HANDLE hEventMbox, TI_HANDLE hTNETWIF, TI_HANDLE hHwIntr,
296 TI_HANDLE hReport, TI_HANDLE hFwEvent, TI_HANDLE hWhalCtrl)
297 {
298 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
299
300 pEventMbox->hTNETWIF = hTNETWIF;
301 pEventMbox->hReport = hReport;
302 pEventMbox->hFwEvent = hFwEvent;
303 pEventMbox->hWhalCtrl = hWhalCtrl;
304 pEventMbox->hReport = hReport;
305
306 pEventMbox->state = EVENT_MBOX_STATE_IDLE;
307 pEventMbox->bInitComplete = FALSE;
308 pEventMbox->CompoundEvent.eventsVector = 0;
309 pEventMbox->currentEvent = 0;
310
311 /*
312 * NOTE: don't set eventsMask = 0xffffffff;
313 * its value is used after recovery has finished
314 */
315
316 /* Init callback table */
317 eventMbox_InitCbTable (hEventMbox);
318 }
319
320
321 /****************************************************************************
322 * eventMbox_InitComplete()
323 ****************************************************************************
324 * DESCRIPTION: ReConfigure the object, Send the Mask Vector to the FW
325 *
326 * INPUTS: pEventMbox this
327 *
328 * RETURNS:
329 ****************************************************************************/
eventMbox_InitComplete(TI_HANDLE hEventMbox)330 void eventMbox_InitComplete (TI_HANDLE hEventMbox)
331 {
332 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
333
334 WLAN_REPORT_INFORMATION(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
335 ("eventMbox_InitComplete: mask=0x%x\n", pEventMbox->CompoundEvent.eventsMask));
336
337 pEventMbox->bInitComplete = TRUE;
338
339 /* Enable Events Interrupts */
340 FwEvent_Enable (pEventMbox->hFwEvent, ACX_INTR_EVENT_A);
341 FwEvent_Enable (pEventMbox->hFwEvent, ACX_INTR_EVENT_B);
342
343 whalCtrl_SetInfoElemEventMask (pEventMbox->hWhalCtrl, pEventMbox->CompoundEvent.eventsMask);
344 }
345
346 /****************************************************************************
347 * eventMbox_Stop()
348 ****************************************************************************
349 * DESCRIPTION: Stop the object while recovery until Init Complete.
350 *
351 * RETURNS: OK or NOK
352 ****************************************************************************/
eventMbox_Stop(TI_HANDLE hEventMbox)353 int eventMbox_Stop(TI_HANDLE hEventMbox)
354 {
355 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
356
357 pEventMbox->state = EVENT_MBOX_STATE_IDLE;
358 pEventMbox->CompoundEvent.eventsVector = 0;
359 pEventMbox->currentEvent = 0;
360 pEventMbox->bInitComplete = FALSE;
361
362 return OK;
363 }
364
365
366 /****************************************************************************
367 * eventMbox_ConfigCb()
368 ****************************************************************************
369 * DESCRIPTION:Read the SRAM Event mailbox address callback
370 *
371 * RETURNS: None
372 ****************************************************************************/
eventMbox_ConfigCb(TI_HANDLE hEventMbox,UINT8 module_id,TI_STATUS status)373 static void eventMbox_ConfigCb (TI_HANDLE hEventMbox, UINT8 module_id, TI_STATUS status)
374 {
375 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
376
377 pEventMbox->offset[1] = pEventMbox->offset[0] + sizeof(EventMailBox_t);
378
379 WLAN_REPORT_INIT (pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
380 ("eventMbox_ConfigCb: event A offset=0x%x, event B offset=0x%x, sizeof=%d\n",
381 pEventMbox->offset[0], pEventMbox->offset[1], sizeof(EventMailBox_t)));
382
383 /* Call upper layer callback */
384 pEventMbox->fCb (pEventMbox->hCb, module_id, OK);
385 }
386
387
388 /****************************************************************************
389 * eventMbox_ConfigHw()
390 ****************************************************************************
391 * DESCRIPTION:Read the SRAM Event mailbox address
392 *
393 * RETURNS: None
394 ****************************************************************************/
eventMbox_ConfigHw(TI_HANDLE hEventMbox,UINT8 module_id,fnotify_t fCb,TI_HANDLE hCb)395 TI_STATUS eventMbox_ConfigHw (TI_HANDLE hEventMbox, UINT8 module_id, fnotify_t fCb, TI_HANDLE hCb)
396 {
397 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
398 TI_STATUS status;
399
400 pEventMbox->fCb = (TNETWIF_callback_t)fCb;
401 pEventMbox->hCb = hCb;
402
403 /*
404 * Get the event mailbox pointer
405 */
406 status = TNETWIF_ReadRegOpt (pEventMbox->hTNETWIF,
407 REG_EVENT_MAILBOX_PTR,
408 &pEventMbox->offset[0],
409 module_id,
410 eventMbox_ConfigCb,
411 hEventMbox);
412
413 if (status == TNETWIF_COMPLETE)
414 {
415 pEventMbox->offset[1] = pEventMbox->offset[0] + sizeof(EventMailBox_t);
416
417 WLAN_REPORT_INIT (pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
418 ("eventMbox_ConfigHw: event A offset=0x%x, event B offset=0x%x, sizeof=%d\n",
419 pEventMbox->offset[0], pEventMbox->offset[1], sizeof(EventMailBox_t)));
420 }
421
422 return status;
423 }
424
425
426 /****************************************************************************
427 * eventMbox_RegisterEventCB()
428 ****************************************************************************
429 * DESCRIPTION: register callback function for Events
430 *
431 * INPUTS: EvID Event ID
432 * fCb Call Back
433 * hCb Call Back Handle
434 *
435 * RETURNS: OK or NOK
436 ****************************************************************************/
eventMbox_RegisterEventCB(TI_HANDLE hEventMbox,UINT32 EvID,void * fCb,TI_HANDLE hCb)437 int eventMbox_RegisterEventCB (TI_HANDLE hEventMbox, UINT32 EvID, void* fCb, TI_HANDLE hCb)
438 {
439 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
440
441 if (fCb == NULL || hCb == NULL)
442 {
443 WLAN_REPORT_ERROR (pEventMbox->hReport, EVENT_MBOX_MODULE_LOG, ("eventMbox_RegisterEventCB: NULL parameters\n"));
444 return NOK;
445 }
446
447 if (EvID >= HAL_EVENT_ALL)
448 {
449 WLAN_REPORT_ERROR(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG, ("eventMbox_RegisterEventCB: invalid ID\n"));
450 return NOK;
451 }
452
453 pEventMbox->cbTable[EvID].fCb = fCb;
454 pEventMbox->cbTable[EvID].hCb = hCb;
455
456 WLAN_REPORT_INFORMATION(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
457 ("eventMbox_RegisterEventCB: EVENT %s has registered\n", eventTable[EvID].str));
458
459 return OK;
460 }
461
462
463 /****************************************************************************
464 * eventMbox_EvMask()
465 ****************************************************************************
466 * DESCRIPTION: The function Mask the Event in the Local Mask Vector
467 * And in the FW Mask Vector
468 *
469 * INPUTS: Evid: The Event ID
470 *
471 * RETURNS: OK or NOK
472 ****************************************************************************/
eventMbox_EvMask(TI_HANDLE hEventMbox,UINT32 EvID)473 int eventMbox_EvMask (TI_HANDLE hEventMbox, UINT32 EvID)
474 {
475 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
476 UINT32 *pEvMask = (UINT32*)&pEventMbox->CompoundEvent.eventsMask;
477
478 if (EvID >= HAL_EVENT_ALL)
479 {
480 WLAN_REPORT_ERROR(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG, ("eventMbox_EvMask: invalid ID\n"));
481 return NOK;
482 }
483
484 *pEvMask |= eventTable[EvID].bitMask;
485
486 WLAN_REPORT_INFORMATION(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
487 ("eventMbox_EvMask: EVENT %s is masked\n", eventTable[EvID].str));
488
489 if (pEventMbox->bInitComplete == TRUE)
490 {
491 whalCtrl_SetInfoElemEventMask (pEventMbox->hWhalCtrl, *pEvMask);
492 }
493
494 return OK;
495 }
496
497
498 /****************************************************************************
499 * eventMbox_EvUnMask()
500 ****************************************************************************
501 * DESCRIPTION: The function UnMask the Event in the Local Mask Vector
502 * And in the FW Mask Vector
503 *
504 * INPUTS: Evid: The Event ID
505 *
506 * RETURNS: OK or NOK
507 ****************************************************************************/
eventMbox_EvUnMask(TI_HANDLE hEventMbox,UINT32 EvID)508 int eventMbox_EvUnMask (TI_HANDLE hEventMbox, UINT32 EvID)
509 {
510 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
511 UINT32 *pEvMask = (UINT32*)&pEventMbox->CompoundEvent.eventsMask;
512
513 if (EvID >= HAL_EVENT_ALL)
514 {
515 WLAN_REPORT_ERROR(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG, ("eventMbox_EvUnMask: invalid ID\n"));
516 return NOK;
517 }
518
519 *pEvMask &= ~eventTable[EvID].bitMask;
520
521 WLAN_REPORT_INFORMATION (pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
522 ("eventMbox_EvUnMask: EVENT %s is unmasked\n", eventTable[EvID].str));
523
524 if (pEventMbox->bInitComplete == TRUE)
525 {
526 whalCtrl_SetInfoElemEventMask (pEventMbox->hWhalCtrl, *pEvMask);
527 }
528
529 return OK;
530 }
531
532
533 /****************************************************************************
534 * eventMbox_Event()
535 *****************************************************************************
536 * DESCRIPTION: Called when Event A or B interrupt occur
537 *
538 * INPUTS: hEventMbox - The object
539 *
540 * RETURNS: TNETWIF_PENDING in case of Async and TNETWIF_OK on Sync
541 *
542 *****************************************************************************/
eventMbox_Event(TI_HANDLE hEventMbox)543 TI_STATUS eventMbox_Event (TI_HANDLE hEventMbox)
544 {
545 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
546
547 /* Assume the driver is synchronous until opposite is proven */
548 pEventMbox->bSync = TRUE;
549
550 eventMbox_StateMachine (pEventMbox, FW_EVENT_MODULE_ID, OK);
551
552 return pEventMbox->returnValue;
553 }
554
555
556 /********************************************************************************/
557 /* Internal functions implementation. */
558 /********************************************************************************/
559
560 /****************************************************************************
561 * eventMbox_StateMachine()
562 ****************************************************************************
563 * DESCRIPTION: Manage the EventMbox state machine
564 *
565 * The SM is running one event at a time (A or B) .
566 * The order of the states is always the same: IDLE --> READ_BUF --> ACK_EVENT
567 * The difference is whether we are using Synch or Asynch API.
568 * In the Synch case (SDIO) we are looping in the while-loop till we return to IDLE, and we return
569 * to FwEvent module a TNETWIF_OK status.
570 * In the Asynch case we use the SM CB to return to the SM after each Asynch call
571 * (In that case the return status is TNETWIF_PENDING, and we are waiting for the CB).
572 * In the Asynch case the FwEvent module gets TNETWIF_PENDING in return, and waits for
573 * the FwEvent_EventComplete() call in order to move the FwEvent SM.
574 *
575 * INPUTS: hFwEvent - The object
576 * module_id - not used (for CB API only)
577 * status - not used (for CB API only)
578 *
579 * OUTPUT: None
580 *
581 * RETURNS: TNETWIF_PENDING in case of Async and TNETWIF_OK on Sync
582 ****************************************************************************/
eventMbox_StateMachine(TI_HANDLE hEventMbox,UINT8 module_id,TI_STATUS status)583 static void eventMbox_StateMachine (TI_HANDLE hEventMbox, UINT8 module_id, TI_STATUS status)
584 {
585 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
586
587 pEventMbox->returnValue = OK;
588
589 while (pEventMbox->returnValue != TNETWIF_PENDING)
590 {
591 switch (pEventMbox->state)
592 {
593 case EVENT_MBOX_STATE_IDLE:
594
595 pEventMbox->returnValue = TNETWIF_ReadMemOpt (pEventMbox->hTNETWIF,
596 pEventMbox->offset[pEventMbox->currentEvent],
597 PADREAD (&pEventMbox->CompoundEvent),
598 EVENT_REPORT_SIZE,
599 FW_EVENT_MODULE_ID,
600 eventMbox_StateMachine,
601 hEventMbox);
602
603 pEventMbox->state = EVENT_MBOX_STATE_READ_BUF;
604
605 break;
606
607 case EVENT_MBOX_STATE_READ_BUF:
608
609 /* Notify The appropriate layer about the incoming event */
610 eventMbox_HandleEvent (hEventMbox);
611
612 /* Trigger the FW when finishing handle the event */
613 pEventMbox->returnValue = TNETWIF_WriteRegOpt (pEventMbox->hTNETWIF,
614 ACX_REG_INTERRUPT_TRIG,
615 INTR_TRIG_EVENT_ACK,
616 FW_EVENT_MODULE_ID,
617 eventMbox_StateMachine,
618 hEventMbox);
619
620 pEventMbox->state = EVENT_MBOX_STATE_ACK_EVENT;
621
622 break;
623
624 case EVENT_MBOX_STATE_ACK_EVENT:
625
626 /* Handling of the event is done. Switch to the next buffer for the next time */
627 pEventMbox->currentEvent = 1 - pEventMbox->currentEvent;
628
629 if (FALSE == pEventMbox->bSync)
630 {
631 /* Asynchronous bus - call FwEvent for notifying the completion */
632 FwEvent_EventComplete (pEventMbox->hFwEvent, TNETWIF_OK);
633 }
634 else
635 {
636 /* This is the Sync case and we return TNETWIF_OK */
637 pEventMbox->returnValue = TNETWIF_OK;
638 }
639 /* Exit SM */
640 pEventMbox->state = EVENT_MBOX_STATE_IDLE;
641 return;
642
643 default:
644 WLAN_REPORT_ERROR(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
645 ("eventMbox_StateMachine: unknown state !!!\n"));
646 break;
647 }
648 }
649
650 /* If we are here - we got TNETWIF_PENDING, so we are in asynchronous mode */
651 pEventMbox->bSync = FALSE;
652 }
653
654
655 /****************************************************************************
656 * eventMbox_HandleEvent()
657 ****************************************************************************
658 * DESCRIPTION: The functions reads the parameters in the Event mailBox
659 * and activates the appropriate CallBack function.
660 *
661 * INPUTS:
662 *
663 * OUTPUT: None
664 *
665 * RETURNS: OK.
666 ****************************************************************************/
eventMbox_HandleEvent(TI_HANDLE hEventMbox)667 static void eventMbox_HandleEvent (TI_HANDLE hEventMbox)
668 {
669 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
670 EventCB_t *pEventCb;
671 UINT32 EvID;
672 UINT32 EvMask = pEventMbox->CompoundEvent.eventsMask;
673 UINT32 EvVector = pEventMbox->CompoundEvent.eventsVector;
674
675 #ifdef TI_DBG
676 pEventMbox->uCompounEvCount++;
677 #endif /* TI_DBG */
678
679 #if EVMBX_DBG
680 WLAN_REPORT_INFORMATION(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
681 ("eventMbox_HandleEvent: Event Vector = 0x%x\n", EvVector));
682 #endif
683
684 /*
685 Handle Events
686 */
687 for (EvID = 0; EvID < HAL_EVENT_ALL; EvID++)
688 {
689 pEventCb = &pEventMbox->cbTable[EvID];
690 /* Check if the Event Bit in the vector in set */
691 if (IS_EVENT_BIT_ON (EvVector, eventTable[EvID].bitMask))
692 {
693 #ifdef TI_DBG
694 pEventMbox->uTotalEvCount++;
695 #endif /* TI_DBG */
696 pEventCb->uCount++;
697 /* Check if the Mask Bit in the Mask vector in off */
698 if (IS_EVENT_BIT_OFF (EvMask, eventTable[EvID].bitMask))
699 {
700 #if EVMBX_DBG
701 WLAN_REPORT_INFORMATION(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
702 ("eventMbox_HandleEvent: EVENT %s has occurred\n", eventTable[EvID].str));
703 #endif
704 if (pEventCb->fCb != NULL)
705 {
706 if (eventTable[EvID].dataLen)
707 {
708 ((whal_hwMboxDataEvCB)pEventCb->fCb) (pEventCb->hCb,
709 (char *)pEventMbox->cbTable[EvID].pDataOffs,
710 eventTable[EvID].dataLen);
711 }
712 else
713 {
714 ((whal_hwMboxEvCB)pEventCb->fCb) (pEventCb->hCb);
715 }
716 }
717 }
718 }
719 } /*End for*/
720 }
721
722
723 /*
724 * eventMbox_Print: print the Event Mailbox statistic :Number 890
725 */
eventMbox_Print(TI_HANDLE hEventMbox)726 void eventMbox_Print (TI_HANDLE hEventMbox)
727 {
728 #ifdef TI_DBG
729 EventMbox_t *pEventMbox = (EventMbox_t *)hEventMbox;
730 UINT32 i;
731 UINT32 EvMask = pEventMbox->CompoundEvent.eventsMask;
732 UINT32 EvVector = pEventMbox->CompoundEvent.eventsVector;
733
734 WLAN_REPORT_REPLY(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
735 ("------------------------- EventMbox Print ----------------------------\n"));
736
737 WLAN_REPORT_INFORMATION(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
738 (" eventMbox_HandleEvent: Event Vector = 0x%x\n", EvVector));
739 WLAN_REPORT_INFORMATION(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
740 (" eventMbox_HandleEvent: Event Mask = 0x%x\n", EvMask));
741 WLAN_REPORT_REPLY(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
742 (" Total Number Of Compound Event = %d: \n", pEventMbox->uCompounEvCount));
743 WLAN_REPORT_REPLY(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
744 (" Total Number Of Events = %d: \n", pEventMbox->uTotalEvCount));
745 WLAN_REPORT_REPLY(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,("\t\t\t\t *** Event Counters *** :\n"));
746 for (i = 0; i < HAL_EVENT_ALL; i++)
747 {
748 WLAN_REPORT_REPLY(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
749 (" %d) Event Name = EVENT %s, Number of Event = %d\n",
750 i, eventTable[i].str, pEventMbox->cbTable[i].uCount));
751 }
752
753 WLAN_REPORT_REPLY(pEventMbox->hReport, EVENT_MBOX_MODULE_LOG,
754 ("------------------------- EventMbox Print End ----------------------------\n"));
755 #endif /* TI_DBG */
756 }
757
758
759
760