Home | History | Annotate | Download | only in FwEvent
      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 ****************************************************************************/
    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 ****************************************************************************/
    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 ****************************************************************************/
    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 ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
    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  ****************************************************************************/
   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  ****************************************************************************/
   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  ****************************************************************************/
   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