1 /* 2 * eventMbox.c 3 * 4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 35 /** \file eventMbox.c 36 * \brief Handle any event interrupt from the FW 37 * 38 * \see 39 */ 40 41 #define __FILE_ID__ FILE_ID_102 42 #include "eventMbox_api.h" 43 #include "TwIf.h" 44 #include "osApi.h" 45 #include "report.h" 46 #include "CmdBld.h" 47 #include "FwEvent_api.h" 48 #include "TWDriver.h" 49 #include "BusDrv.h" 50 51 52 53 #define EVENT_MBOX_BUFFERS 2 54 55 56 typedef enum 57 { 58 EVENT_MBOX_STATE_IDLE, 59 EVENT_MBOX_STATE_READING 60 } EEventMboxState; 61 62 typedef struct { 63 void* fCb; /* Event Callback function */ 64 TI_HANDLE hCb; /* Evant handle */ 65 TI_UINT8* pDataOffset; /* Event Data Offset */ 66 #ifdef TI_DBG 67 TI_UINT32 uCount; 68 #endif 69 70 }TRegisteredEventCb; 71 72 typedef struct 73 { 74 TI_UINT32 bitMask;/* Event bit mask */ 75 char* str; /* Event trace string */ 76 TI_UINT8 dataLen;/* Event data length */ 77 78 } TEventEntry; 79 80 81 typedef struct 82 { 83 TTxnStruct tTxnReg; 84 TI_UINT32 iRegBuffer; 85 86 } tTxnGenReg; 87 88 89 typedef struct 90 { 91 TTxnStruct tEventMbox; 92 EventMailBox_t iEventMboxBuf; 93 94 } tTxnEventMbox; 95 96 97 98 typedef struct 99 { 100 TI_UINT32 EventMboxAddr[EVENT_MBOX_BUFFERS]; /* the Event Mbox addresses in the device */ 101 TI_UINT8 ActiveMbox; /* The current active Mbox */ 102 EEventMboxState CurrentState; 103 TRegisteredEventCb CbTable[TWD_OWN_EVENT_MAX]; /* Callback table */ 104 105 /* Handles */ 106 TI_HANDLE hTwif; 107 TI_HANDLE hOs; 108 TI_HANDLE hReport; 109 TI_HANDLE hCmdBld; 110 111 /* HW params */ 112 /* use a struct to read or write register (4 byte size) from the bus */ 113 tTxnGenReg iTxnGenRegSize; 114 115 tTxnEventMbox iTxnEventMbox; 116 117 #ifdef TI_DBG 118 TI_UINT32 uCompounEvCount; /* Count the compound event */ 119 TI_UINT32 uTotalEvCount; /* Count total number of event sending in the compound */ 120 #endif /* TI_DBG */ 121 122 fnotify_t fCb; 123 TI_HANDLE hCb; 124 125 }TEventMbox; 126 127 128 /********************************************************************************/ 129 /* Internal functions prototypes. */ 130 /********************************************************************************/ 131 132 static void eventMbox_ConfigCbTable(TI_HANDLE hEventMbox); 133 static void eventMbox_ReadAddrCb(TI_HANDLE hEventMbox, TI_HANDLE hTxn); 134 static void eventMbox_DummyCb(TI_HANDLE hEventMbox); 135 static void eventMbox_ReadCompleteCB(TI_HANDLE hEventMbox, TTxnStruct *pTxnStruct); 136 137 138 static const TEventEntry eventTable [TWD_OWN_EVENT_MAX] = 139 { 140 /*================================================================================== 141 * 142 * EVENT TABLE 143 * 144 * Note that changes here should be reflected also in ETwdOwnEventId in TWDriver.h !!! 145 * 146 =================================================================================== 147 | Id | Event Mask Bit | Event String | Length | 148 ===================================================================================*/ 149 150 /* 0*/{ RSSI_SNR_TRIGGER_0_EVENT_ID, "RSSI SNR TRIGGER 0 " , 1}, 151 /* 1*/{ RSSI_SNR_TRIGGER_1_EVENT_ID, "RSSI SNR TRIGGER 1 " , 1}, 152 /* 2*/{ RSSI_SNR_TRIGGER_2_EVENT_ID, "RSSI SNR TRIGGER 2 " , 1}, 153 /* 3*/{ RSSI_SNR_TRIGGER_3_EVENT_ID, "RSSI SNR TRIGGER 3 " , 1}, 154 /* 4*/{ RSSI_SNR_TRIGGER_4_EVENT_ID, "RSSI SNR TRIGGER 4 " , 1}, 155 /* 5*/{ RSSI_SNR_TRIGGER_5_EVENT_ID, "RSSI SNR TRIGGER 5 " , 1}, 156 /* 6*/{ RSSI_SNR_TRIGGER_6_EVENT_ID, "RSSI SNR TRIGGER 6 " , 1}, 157 /* 7*/{ RSSI_SNR_TRIGGER_7_EVENT_ID, "RSSI SNR TRIGGER 7 " , 1}, 158 /* 8*/{ MEASUREMENT_START_EVENT_ID, "MEASUREMENT START " , 0}, 159 /* 9*/{ MEASUREMENT_COMPLETE_EVENT_ID, "BSS LOSE " , 0}, 160 /*10*/{ SCAN_COMPLETE_EVENT_ID , "SCAN CMPLT " , 8}, 161 /*11*/{ SCHEDULED_SCAN_COMPLETE_EVENT_ID, "SPS SCAN CMPLT " , 3}, 162 /*12*/{ AP_DISCOVERY_COMPLETE_EVENT_ID, "MAX TX RETRY " , 0}, 163 /*13*/{ PS_REPORT_EVENT_ID, "PS_REPORT " , 1}, 164 /*14*/{ PSPOLL_DELIVERY_FAILURE_EVENT_ID, "PS-POLL DELIVERY FAILURE" , 0}, 165 /*15*/{ DISCONNECT_EVENT_COMPLETE_ID, "DISCONNECT COMPLETE " , 0}, 166 /*16*/{ JOIN_EVENT_COMPLETE_ID, "JOIN CMPLT " , 0}, 167 /*17*/{ CHANNEL_SWITCH_COMPLETE_EVENT_ID, "SWITCH CHANNEL CMPLT " , 0}, 168 /*18*/{ BSS_LOSE_EVENT_ID, "BSS LOST " , 0}, 169 /*19*/{ REGAINED_BSS_EVENT_ID, "REGAINED BSS " , 0}, 170 /*20*/{ ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID, "MAX TX RETRY " , 0}, 171 /*21*/{ BIT_21, "RESERVED" , 0}, 172 /*22*/{ SOFT_GEMINI_SENSE_EVENT_ID, "SOFT GEMINI SENSE " , 1}, 173 /*23*/{ SOFT_GEMINI_PREDICTION_EVENT_ID, "SOFT GEMINI PREDICTION " , 1}, 174 /*24*/{ SOFT_GEMINI_AVALANCHE_EVENT_ID, "SOFT GEMINI AVALANCHE " , 0}, 175 /*25*/{ PLT_RX_CALIBRATION_COMPLETE_EVENT_ID, "PLT RX CALIBR. COMPLETE " , 0}, 176 /*26*/{ DBG_EVENT_ID, "DBG_EVENT_ID " , 16}, 177 /*27*/{ HEALTH_CHECK_REPLY_EVENT_ID, "HEALTH_CHECK_REPLY_EVENT_ID" , 0}, 178 /*28*/{ PERIODIC_SCAN_COMPLETE_EVENT_ID, "PERIODIC SCAN COMPLETE " , 8}, 179 /*29*/{ PERIODIC_SCAN_REPORT_EVENT_ID, "PERIODIC SCAN REPORT " , 8}, 180 /*30*/{ BA_SESSION_TEAR_DOWN_EVENT_ID, "BA_SESSION_TEAR_DOWN_EVENT_ID" , 0}, 181 /*31*/{ EVENT_MBOX_ALL_EVENT_ID, "ALL EVENTS " , 0} 182 }; 183 184 185 /* 186 * \brief Create the Bus Access mailbox object 187 * 188 * \param hOs - OS Handle 189 * \returnThe Created object 190 * 191 * \sa 192 */ 193 194 TI_HANDLE eventMbox_Create(TI_HANDLE hOs) 195 { 196 TEventMbox *pEventMbox; 197 pEventMbox = (TEventMbox*)os_memoryAlloc(hOs,sizeof(TEventMbox)); 198 if (pEventMbox == NULL) 199 { 200 WLAN_OS_REPORT (("eventMbox_Create: Error creating EventMbox object\n")); 201 return NULL; 202 } 203 os_memoryZero (hOs, pEventMbox, sizeof(TEventMbox)); 204 pEventMbox->hOs = hOs; 205 pEventMbox->iTxnEventMbox.iEventMboxBuf.eventsMask = EVENT_MBOX_ALL_EVENT_ID; 206 return (TI_HANDLE)pEventMbox; 207 } 208 209 210 /* 211 * \brief Release all memory resource of EventMbox 212 * 213 * \param hEventMbox - Handle to EventMbox 214 * \return none 215 * 216 * \par Description 217 * This function should called after all interrupts was disabled. 218 * 219 * \sa 220 */ 221 void eventMbox_Destroy(TI_HANDLE hEventMbox) 222 { 223 TEventMbox *pEventMbox = (TEventMbox *)hEventMbox; 224 225 if (pEventMbox) 226 { 227 os_memoryFree (pEventMbox->hOs, pEventMbox, sizeof(TEventMbox)); 228 } 229 } 230 231 232 233 /* 234 * \brief Stop the EventMbox clear state and event vector 235 * 236 * \param hEventMbox - Handle to EventMbox 237 * \return none 238 * 239 * \par Description 240 * This function should called to stop the EventMb. 241 * Do Not clear the mask Event could use us again when restart/recovery!!!! 242 * \sa 243 */ 244 void eventMbox_Stop(TI_HANDLE hEventMbox) 245 { 246 TEventMbox* pEventMbox = (TEventMbox*)hEventMbox; 247 pEventMbox->ActiveMbox = 0; 248 pEventMbox->CurrentState = EVENT_MBOX_STATE_IDLE; 249 pEventMbox->iTxnEventMbox.iEventMboxBuf.eventsVector = 0; 250 } 251 252 253 254 /* 255 * \brief Configure the object 256 * 257 * \param hEventMbox - Handle to EventMbox 258 * \param hTwif - Handle to TWIF 259 * \param hReport - Handle to Report module 260 * \param hFwEvent - Handle to FW Event module 261 * \param hCmdBld - Handle to Command Build module 262 * \return none 263 * 264 * \par Description 265 * This function should called to configure the module. 266 * \sa 267 */ 268 269 void eventMbox_Config(TI_HANDLE hEventMbox, 270 TI_HANDLE hTwif, 271 TI_HANDLE hReport, 272 TI_HANDLE hFwEvent, 273 TI_HANDLE hCmdBld) 274 { 275 TEventMbox *pEventMbox = (TEventMbox *)hEventMbox; 276 pEventMbox->hTwif = hTwif; 277 pEventMbox->hReport = hReport; 278 pEventMbox->hCmdBld = hCmdBld; 279 pEventMbox->ActiveMbox = 0; 280 pEventMbox->CurrentState = EVENT_MBOX_STATE_IDLE; 281 #ifdef TI_DBG 282 pEventMbox->uCompounEvCount = 0; 283 pEventMbox->uTotalEvCount = 0; 284 #endif 285 eventMbox_ConfigCbTable(pEventMbox); 286 } 287 288 289 290 /* 291 * \brief Initialization of callback table 292 * 293 * \param hEventMbox - Handle to EventMbox 294 * \return none 295 * 296 * \par Description 297 * This function is called to configure the CB table initialize the 298 * CB functions and handle and set the Data offset. 299 * 300 * \sa 301 */ 302 static void eventMbox_ConfigCbTable(TI_HANDLE hEventMbox) 303 { 304 TEventMbox* pEventMbox; 305 TI_UINT8 EvID; 306 307 pEventMbox = (TEventMbox*)hEventMbox; 308 309 /* for all events set a dummy func and data offset */ 310 for (EvID = 0; EvID < TWD_OWN_EVENT_MAX;EvID++) 311 { 312 pEventMbox->CbTable[EvID].pDataOffset = (TI_UINT8*)&pEventMbox->iTxnEventMbox.iEventMboxBuf; 313 pEventMbox->CbTable[EvID].fCb = (void*)eventMbox_DummyCb; 314 pEventMbox->CbTable[EvID].hCb = pEventMbox; 315 } 316 /* set the data offset for Events with data only */ 317 for (EvID = 0;EvID < NUM_OF_RSSI_SNR_TRIGGERS;EvID++) 318 { 319 pEventMbox->CbTable[EvID].pDataOffset += TI_FIELD_OFFSET (EventMailBox_t, RSSISNRTriggerMetric[EvID]); 320 } 321 pEventMbox->CbTable[TWD_DBG_EVENT ].pDataOffset += TI_FIELD_OFFSET (EventMailBox_t, dbgEventRep); 322 pEventMbox->CbTable[TWD_OWN_EVENT_SCAN_CMPLT ].pDataOffset += TI_FIELD_OFFSET (EventMailBox_t,scanCompleteResults); 323 pEventMbox->CbTable[TWD_OWN_EVENT_SPS_SCAN_CMPLT ].pDataOffset += TI_FIELD_OFFSET (EventMailBox_t,scheduledScanAttendedChannels); 324 pEventMbox->CbTable[TWD_OWN_EVENT_PERIODIC_SCAN_COMPLETE].pDataOffset += TI_FIELD_OFFSET (EventMailBox_t, scanCompleteResults); 325 pEventMbox->CbTable[TWD_OWN_EVENT_PERIODIC_SCAN_REPORT ].pDataOffset += TI_FIELD_OFFSET (EventMailBox_t, scanCompleteResults); 326 pEventMbox->CbTable[TWD_OWN_EVENT_SOFT_GEMINI_SENSE ].pDataOffset += TI_FIELD_OFFSET (EventMailBox_t,softGeminiSenseInfo); 327 pEventMbox->CbTable[TWD_OWN_EVENT_SOFT_GEMINI_PREDIC ].pDataOffset += TI_FIELD_OFFSET (EventMailBox_t,softGeminiProtectiveInfo); 328 pEventMbox->CbTable[TWD_OWN_EVENT_SWITCH_CHANNEL_CMPLT ].pDataOffset += TI_FIELD_OFFSET (EventMailBox_t,channelSwitchStatus); 329 pEventMbox->CbTable[TWD_OWN_EVENT_PS_REPORT ].pDataOffset += TI_FIELD_OFFSET (EventMailBox_t,psStatus); 330 } 331 332 333 334 static void eventMbox_DummyCb(TI_HANDLE hEventMbox) 335 { 336 TEventMbox* pEventMbox = (TEventMbox*)hEventMbox; 337 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_ERROR, "eventMbox_DummyCb : Called for unregistered event"); 338 } 339 340 341 /* 342 * \brief Read mailbox address 343 * 344 * \param hEventMbox - Handle to EventMbox 345 * \param fCb - CB function to return in Async mode 346 * \param hCb - CB Habdle 347 * \return TXN_STATUS_COMPLETE, TXN_STATUS_PENDING, TXN_STATUS_ERROR 348 * 349 * \par Description 350 * This function is called for initialize the Event MBOX addresses. 351 * It issues a read transaction from the Twif with a CB. 352 * 353 * \sa 354 */ 355 TI_STATUS eventMbox_InitMboxAddr(TI_HANDLE hEventMbox, fnotify_t fCb, TI_HANDLE hCb) 356 { 357 TTxnStruct *pTxn; 358 TEventMbox* pEventMbox; 359 ETxnStatus rc; 360 pEventMbox = (TEventMbox*)hEventMbox; 361 pTxn = &pEventMbox->iTxnGenRegSize.tTxnReg; 362 363 /* Store the Callabck address of the modules that called us in case of Asynchronuous transaction that will complete later */ 364 pEventMbox->fCb = fCb; 365 pEventMbox->hCb = hCb; 366 367 /* Build the command TxnStruct */ 368 TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_READ, TXN_INC_ADDR) 369 /* Applying a CB in case of an async read */ 370 BUILD_TTxnStruct(pTxn, REG_EVENT_MAILBOX_PTR, &pEventMbox->iTxnGenRegSize.iRegBuffer, REGISTER_SIZE, eventMbox_ReadAddrCb, hEventMbox) 371 rc = twIf_Transact(pEventMbox->hTwif,pTxn); 372 if (rc == TXN_STATUS_COMPLETE) 373 { 374 pEventMbox->EventMboxAddr[0] = pEventMbox->iTxnGenRegSize.iRegBuffer; 375 pEventMbox->EventMboxAddr[1] = pEventMbox->EventMboxAddr[0] + sizeof(EventMailBox_t); 376 TRACE3(pEventMbox->hReport, REPORT_SEVERITY_INIT , "eventMbox_ConfigHw: event A Address=0x%x, event B Address=0x%x, sizeof=%d\n", pEventMbox->EventMboxAddr[0], pEventMbox->EventMboxAddr[1], sizeof(EventMailBox_t)); 377 378 } 379 return rc; 380 } 381 382 383 /* 384 * \brief Save the Event MBOX addresses 385 * 386 * \param hEventMbox - Handle to EventMbox 387 * \param hTxn - Handle to TTxnStruct 388 * \return none 389 * 390 * \par Description 391 * This function is called upon completion of thr read Event MBOX address register. 392 * It save the addresses in EventMbox. 393 * 394 * \sa 395 */ 396 static void eventMbox_ReadAddrCb(TI_HANDLE hEventMbox, TI_HANDLE hTxn) 397 { 398 TEventMbox* pEventMbox; 399 400 pEventMbox = (TEventMbox*)hEventMbox; 401 402 pEventMbox->EventMboxAddr[0] = pEventMbox->iTxnGenRegSize.iRegBuffer; 403 pEventMbox->EventMboxAddr[1] = pEventMbox->EventMboxAddr[0] + sizeof(EventMailBox_t); 404 405 TRACE3(pEventMbox->hReport, REPORT_SEVERITY_INIT , "eventMbox_ConfigHw: event A Address=0x%x, event B Address=0x%x, sizeof=%d\n", pEventMbox->EventMboxAddr[0], pEventMbox->EventMboxAddr[1], sizeof(EventMailBox_t)); 406 407 /* call back the module that called us before to read our self-address */ 408 pEventMbox->fCb(pEventMbox->hCb,TI_OK); 409 } 410 411 412 /* 413 * \brief confige the Mask vector in FW 414 * 415 * \param hEventMbox - Handle to EventMbox 416 * \return none 417 * 418 * \par Description 419 * This function is called upon exit from init it will set the mask vector. 420 * this function is mostly use for recovery 421 * Note that at Init stage the FW is already configured to have all events masked but at Recovery stage 422 * The driver whishes to just set back previous event mask configuration 423 * 424 * \sa 425 */ 426 void eventMbox_InitComplete(TI_HANDLE hEventMbox) 427 { 428 429 TEventMbox* pEventMbox; 430 pEventMbox = (TEventMbox*)hEventMbox; 431 432 TRACE1(pEventMbox->hReport, REPORT_SEVERITY_INFORMATION, "eventMbox_InitComplete: mask = 0x%x\n", pEventMbox->iTxnEventMbox.iEventMboxBuf.eventsMask); 433 434 cmdBld_CfgEventMask(pEventMbox->hCmdBld,pEventMbox->iTxnEventMbox.iEventMboxBuf.eventsMask,NULL,NULL); 435 } 436 437 438 439 /* 440 * \brief Register an event 441 * 442 * \param hEventMbox - Handle to EventMbox 443 * \param EvID - the event ID to register 444 * \param fCb - CB function of the registered event 445 * \param hCb - CB handle of the registered event 446 * \return TI_OK,TI_NOK 447 * 448 * \par Description 449 * This function is called from the user upon request to register for event. 450 * an Event can only be register to one user. 451 * This function doesn't change the mask vector in FW!!! 452 * 453 * \sa 454 */ 455 TI_STATUS eventMbox_RegisterEvent(TI_HANDLE hEventMbox,TI_UINT32 EvID,void* fCb,TI_HANDLE hCb) 456 { 457 TEventMbox *pEventMbox = (TEventMbox *)hEventMbox; 458 if (fCb == NULL || hCb == NULL) 459 { 460 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_ERROR, "eventMbox_RegisterEvent : NULL parameters\n"); 461 return TI_NOK; 462 } 463 if (EvID >= TWD_OWN_EVENT_ALL) 464 { 465 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_ERROR, "eventMbox_RegisterEvent : Event ID invalid\n"); 466 return TI_NOK; 467 } 468 pEventMbox->CbTable[EvID].fCb = fCb; 469 pEventMbox->CbTable[EvID].hCb = hCb; 470 return TI_OK; 471 } 472 473 474 475 476 /* 477 * \brief Replace event callback 478 * 479 * \param hEventMbox - Handle to EventMbox 480 * \param EvID - the event ID to register 481 * \param fNewCb - the new CB function of the registered event 482 * \param hNewCb - the new CB handle of the registered event 483 * \param pPrevCb - the old CB to save 484 * \param pPrevHndl - the old handle to save 485 * \return TI_OK,TI_NOK 486 * 487 * \par Description 488 * Replace event callback function by another one. 489 * Provide the previous CB to the caller. 490 * 491 * \sa 492 */ 493 TI_STATUS eventMbox_ReplaceEvent (TI_HANDLE hEventMbox, 494 TI_UINT32 EvID, 495 void *fNewCb, 496 TI_HANDLE hNewCb, 497 void **pPrevCb, 498 TI_HANDLE *pPrevHndl) 499 { 500 TEventMbox *pEventMbox = (TEventMbox *)hEventMbox; 501 if (fNewCb == NULL || hNewCb == NULL) 502 { 503 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_ERROR , "eventMbox_ReplaceEvent: NULL parameters\n"); 504 return TI_NOK; 505 } 506 if (EvID >= TWD_OWN_EVENT_ALL) 507 { 508 TRACE1(pEventMbox->hReport, REPORT_SEVERITY_ERROR, "eventMbox_ReplaceEvent: invalid ID. ID is %d\n", EvID); 509 return TI_NOK; 510 } 511 512 /* Save the old CBs */ 513 *pPrevCb = pEventMbox->CbTable[EvID].fCb; 514 *pPrevHndl = pEventMbox->CbTable[EvID].hCb; 515 516 /* store the new CBs */ 517 pEventMbox->CbTable[EvID].fCb = fNewCb; 518 pEventMbox->CbTable[EvID].hCb = hNewCb; 519 520 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_INFORMATION, "eventMbox_ReplaceEvent: EVENT has registered\n"); 521 return TI_OK; 522 } 523 524 525 /* 526 * \brief Un mask an event 527 * 528 * \param hEventMbox - Handle to EventMbox 529 * \param EvID - the event ID to un mask 530 * \param fCb - CB function 531 * \param hCb - CB handle 532 * \return TI_COMPLETE,TI_PENDING,TI_ERROR 533 * 534 * \par Description 535 * This function is called from the user upon request to un mask an event. 536 * This function change the mask vector in FW but doesn't register for it in the driver and 537 * doesn't set Cb function and Cb Handle in case of un mask event without registered for it an 538 * error will be handling!!! 539 * 540 * \sa 541 */ 542 TI_STATUS eventMbox_UnMaskEvent(TI_HANDLE hEventMbox,TI_UINT32 EvID,void* fCb,TI_HANDLE hCb) 543 { 544 TI_UINT32* pEventMask; 545 TI_STATUS aStatus; 546 TEventMbox *pEventMbox = (TEventMbox *)hEventMbox; 547 pEventMask = (TI_UINT32*)&pEventMbox->iTxnEventMbox.iEventMboxBuf.eventsMask; 548 549 if (EvID >= TWD_OWN_EVENT_ALL) 550 { 551 TRACE1(pEventMbox->hReport, REPORT_SEVERITY_ERROR, "eventMbox_UnMaskEvent : Un mask an Invalid event = 0x%x\n",EvID); 552 return TXN_STATUS_ERROR; 553 } 554 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_INFORMATION, "eventMbox_UnMaskEvent : EVENT is unmasked\n"); 555 556 *pEventMask &= ~eventTable[EvID].bitMask; 557 558 aStatus = cmdBld_CfgEventMask (pEventMbox->hCmdBld, *pEventMask, fCb, hCb); 559 return aStatus; 560 } 561 562 563 /* 564 * \brief mask an event 565 * 566 * \param hEventMbox - Handle to EventMbox 567 * \param EvID - the event ID to un mask 568 * \param fCb - CB function 569 * \param hCb - CB handle 570 * \return TI_COMPLETE,TI_PENDING,TI_ERROR 571 * 572 * \par Description 573 * This function is called from the user upon request to mask an event. 574 * This function change the mask vector in FW but doesn't unregister it in the driver. 575 * \sa 576 */ 577 TI_STATUS eventMbox_MaskEvent(TI_HANDLE hEventMbox,TI_UINT32 EvID,void* fCb,TI_HANDLE hCb) 578 { 579 TI_UINT32* pEventMask; 580 TI_STATUS aStatus; 581 TEventMbox *pEventMbox = (TEventMbox *)hEventMbox; 582 pEventMask = (TI_UINT32*)&pEventMbox->iTxnEventMbox.iEventMboxBuf.eventsMask; 583 584 if (EvID >= TWD_OWN_EVENT_ALL) 585 { 586 TRACE1(pEventMbox->hReport, REPORT_SEVERITY_ERROR, "eventMbox_MaskEvent : Mask an Invalid event = 0x%x\n",EvID); 587 return TXN_STATUS_ERROR; 588 } 589 590 *pEventMask |= eventTable[EvID].bitMask; 591 592 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_INFORMATION , "eventMbox_MaskEvent : EVENT is masked\n"); 593 594 aStatus = cmdBld_CfgEventMask(pEventMbox->hCmdBld,*pEventMask,fCb,hCb); 595 return aStatus; 596 } 597 598 599 600 /* 601 * \brief Handle the incoming event read the Mbox data 602 * 603 * \param hEventMbox - Handle to EventMbox 604 * \param TFwStatus - FW status 605 * \return none 606 * 607 * \par Description 608 * This function is called from the FW Event upon receiving MBOX event. 609 * \sa 610 */ 611 ETxnStatus eventMbox_Handle(TI_HANDLE hEventMbox,FwStatus_t* pFwStatus) 612 { 613 ETxnStatus rc; 614 TTxnStruct *pTxn; 615 TEventMbox *pEventMbox = (TEventMbox *)hEventMbox; 616 617 pTxn = &pEventMbox->iTxnEventMbox.tEventMbox; 618 619 TRACE1(pEventMbox->hReport, REPORT_SEVERITY_INFORMATION, "eventMbox_Handle : Reading from MBOX -- %d",pEventMbox->ActiveMbox); 620 621 #ifdef TI_DBG 622 /* Check if missmatch MBOX */ 623 if (pEventMbox->ActiveMbox == 0) 624 { 625 if (pFwStatus->intrStatus & ACX_INTR_EVENT_B) 626 { 627 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_ERROR, "eventMbox_Handle : incorrect MBOX SW MBOX -- A FW MBOX -- B"); 628 } 629 } 630 else if (pEventMbox->ActiveMbox == 1) 631 { 632 if (pFwStatus->intrStatus & ACX_INTR_EVENT_A) 633 { 634 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_ERROR, "eventMbox_Handle : incorrect MBOX SW MBOX -- B FW MBOX -- A"); 635 } 636 } 637 #endif /* TI_DBG */ 638 639 if (pEventMbox->CurrentState != EVENT_MBOX_STATE_IDLE) 640 { 641 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_ERROR, "eventMbox_Handle : Receiving event not in Idle state"); 642 } 643 pEventMbox->CurrentState = EVENT_MBOX_STATE_READING; 644 645 /* Build the command TxnStruct */ 646 TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_READ, TXN_INC_ADDR) 647 /* Applying a CB in case of an async read */ 648 BUILD_TTxnStruct(pTxn, pEventMbox->EventMboxAddr[pEventMbox->ActiveMbox], &pEventMbox->iTxnEventMbox.iEventMboxBuf, sizeof(EventMailBox_t),(TTxnDoneCb)eventMbox_ReadCompleteCB, pEventMbox) 649 rc = twIf_Transact(pEventMbox->hTwif,pTxn); 650 651 pEventMbox->ActiveMbox = 1 - pEventMbox->ActiveMbox; 652 if (rc == TXN_STATUS_COMPLETE) 653 { 654 eventMbox_ReadCompleteCB(pEventMbox,pTxn); 655 } 656 657 return TXN_STATUS_COMPLETE; 658 } 659 660 661 /* 662 * \brief Process the event 663 * 664 * \param hEventMbox - Handle to EventMbox 665 * \param pTxnStruct - the Txn data 666 * \return none 667 * 668 * \par Description 669 * This function is called from the upon reading completion of the event MBOX 670 * it will call all registered event according to the pending bits in event MBOX vector. 671 * \sa 672 */ 673 static void eventMbox_ReadCompleteCB(TI_HANDLE hEventMbox, TTxnStruct *pTxnStruct) 674 { 675 TI_UINT32 EvID; 676 TTxnStruct* pTxn; 677 TEventMbox *pEventMbox = (TEventMbox *)hEventMbox; 678 pTxn = &pEventMbox->iTxnGenRegSize.tTxnReg; 679 680 TRACE1(pEventMbox->hReport, REPORT_SEVERITY_INFORMATION, "eventMbox_ReadCompleteCB : event vector -- 0x%x\n",pEventMbox->iTxnEventMbox.iEventMboxBuf.eventsVector); 681 682 pEventMbox->iTxnGenRegSize.iRegBuffer = INTR_TRIG_EVENT_ACK; 683 684 for (EvID = 0; EvID < TWD_OWN_EVENT_ALL; EvID++) 685 { 686 if (pEventMbox->iTxnEventMbox.iEventMboxBuf.eventsVector & eventTable[EvID].bitMask) 687 { 688 if (eventTable[EvID].dataLen) 689 { 690 ((TEventMboxDataCb)pEventMbox->CbTable[EvID].fCb)(pEventMbox->CbTable[EvID].hCb,(TI_CHAR*)pEventMbox->CbTable[EvID].pDataOffset,eventTable[EvID].dataLen); 691 } 692 else 693 { 694 ((TEventMboxEvCb)pEventMbox->CbTable[EvID].fCb)(pEventMbox->CbTable[EvID].hCb); 695 } 696 } 697 } 698 699 /* Check if the state is changed in the context of the event callbacks */ 700 if (pEventMbox->CurrentState == EVENT_MBOX_STATE_IDLE) 701 { 702 /* 703 * When eventMbox_stop is called state is changed to IDLE 704 * This is done in the context of the above events callbacks 705 * Don't send the EVENT ACK transaction because the driver stop process includes power off 706 */ 707 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_WARNING, "eventMbox_ReadCompleteCB : State is IDLE ! don't send the EVENT ACK"); 708 return; 709 } 710 711 pEventMbox->CurrentState = EVENT_MBOX_STATE_IDLE; 712 713 /* Build the command TxnStruct */ 714 TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR) 715 /* Applying a CB in case of an async read */ 716 BUILD_TTxnStruct(pTxn, ACX_REG_INTERRUPT_TRIG, &pEventMbox->iTxnGenRegSize.iRegBuffer, sizeof(pEventMbox->iTxnGenRegSize.iRegBuffer), NULL, NULL) 717 twIf_Transact(pEventMbox->hTwif,pTxn); 718 } 719 720 721 #ifdef TI_DBG 722 723 /* 724 * eventMbox_Print: print the Event Mailbox statistic :Number 890 725 */ 726 TI_STATUS eventMbox_Print (TI_HANDLE hEventMbox) 727 { 728 TEventMbox *pEventMbox = (TEventMbox *)hEventMbox; 729 TI_UINT32 i; 730 TI_UINT32 EvMask = pEventMbox->iTxnEventMbox.iEventMboxBuf.eventsMask; 731 TI_UINT32 EvVector = pEventMbox->iTxnEventMbox.iEventMboxBuf.eventsVector; 732 733 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_CONSOLE, "------------------------- EventMbox Print ----------------------------\n"); 734 735 TRACE1(pEventMbox->hReport, REPORT_SEVERITY_INFORMATION, " eventMbox_HandleEvent: Event Vector = 0x%x\n", EvVector); 736 TRACE1(pEventMbox->hReport, REPORT_SEVERITY_INFORMATION, " eventMbox_HandleEvent: Event Mask = 0x%x\n", EvMask); 737 TRACE1(pEventMbox->hReport, REPORT_SEVERITY_CONSOLE, " Total Number Of Compound Event = %d: \n", pEventMbox->uCompounEvCount); 738 TRACE1(pEventMbox->hReport, REPORT_SEVERITY_CONSOLE, " Total Number Of Events = %d: \n", pEventMbox->uTotalEvCount); 739 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_CONSOLE, "\t\t\t\t *** Event Counters *** :\n"); 740 for (i = 0; i < TWD_OWN_EVENT_ALL; i++) 741 { 742 TRACE2(pEventMbox->hReport, REPORT_SEVERITY_CONSOLE, " %d) Event Name = EVENT , Number of Event = %d\n", i, pEventMbox->CbTable[i].uCount); 743 } 744 745 TRACE0(pEventMbox->hReport, REPORT_SEVERITY_CONSOLE, "------------------------- EventMbox Print End ----------------------------\n"); 746 747 return TI_OK; 748 } 749 750 751 #endif /* TI_DBG */ 752 753 754 755