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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 *****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 */ 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