/* * \brief Read interrupt info from FW * * \param hFwEvent - FwEvent Driver handle * \return void * * \par Description * * Indicate the TwIf that HW is available and initiate transactions for reading * the Interrupt status and the FW status. * * \sa */ static ETxnStatus fwEvent_SmReadIntrInfo (TfwEvent *pFwEvent) { ETxnStatus eStatus; CL_TRACE_START_L4(); #ifdef HOST_INTR_MODE_EDGE /* Acknowledge the host interrupt for EDGE mode (must be before HINT_STT_CLR register clear on read) */ os_InterruptServiced (pFwEvent->hOs); #endif /* Indicate that the chip is awake (since it interrupted us) */ twIf_HwAvailable(pFwEvent->hTwIf); /* * Read FW-Status structure from HW ==> Special mapping, see note!! * * Note: This structure actually includes two separate areas in the FW: * 1) Interrupt-Status register - a 32 bit register (clear on read). * 2) FW-Status structure - 64 bytes memory area * The two areas are read in a single transaction thanks to a special memory * partition that maps them as contiguous memory. */ TXN_FW_EVENT_SET_FW_STAT_ADDR(pFwEvent) eStatus = twIf_TransactReadFWStatus (pFwEvent->hTwIf, &(pFwEvent->tFwStatusTxn.tTxnStruct)); CL_TRACE_END_L4("tiwlan_drv.ko", "CONTEXT", "FwEvent", ""); /* Return the status of the FwStatus read (complete, pending or error) */ return eStatus; }
/* * \brief Handle the Fw Status information * * \param hFwEvent - FwEvent Driver handle * \return void * * \par Description * This function is called from fwEvent_Handle on a sync read, or from TwIf as a CB on an async read. * It calls fwEvent_CallHandlers to handle the triggered interrupts. * * \sa fwEvent_Handle */ static ETxnStatus fwEvent_SmHandleEvents (TfwEvent *pFwEvent) { ETxnStatus eStatus; CL_TRACE_START_L4(); /* Save delta between driver and FW time (needed for Tx packets lifetime) */ pFwEvent->uFwTimeOffset = (os_timeStampMs (pFwEvent->hOs) * 1000) - ENDIAN_HANDLE_LONG (pFwEvent->tFwStatusTxn.tFwStatus.fwLocalTime); #ifdef HOST_INTR_MODE_LEVEL /* Acknowledge the host interrupt for LEVEL mode (must be after HINT_STT_CLR register clear on read) */ os_InterruptServiced (pFwEvent->hOs); #endif /* Save the interrupts status retreived from the FW */ pFwEvent->uEventVector = pFwEvent->tFwStatusTxn.tFwStatus.intrStatus; /* Mask unwanted interrupts */ pFwEvent->uEventVector &= pFwEvent->uEventMask; /* Call the interrupts handlers */ eStatus = fwEvent_CallHandlers (pFwEvent); TRACE5(pFwEvent->hReport, REPORT_SEVERITY_INFORMATION, "fwEvent_SmHandleEvents: Status=%d, EventVector=0x%x, IntrPending=%d, NumPendHndlrs=%d, FwTimeOfst=%d\n", eStatus, pFwEvent->uEventVector, pFwEvent->bIntrPending, pFwEvent->uNumPendHndlrs, pFwEvent->uFwTimeOffset); CL_TRACE_END_L4("tiwlan_drv.ko", "CONTEXT", "FwEvent", ""); /* Return the status of the handlers processing (complete, pending or error) */ return eStatus; }
/* * \brief Handle the Fw Status information * * \param hFwEvent - FwEvent Driver handle * \return void * * \par Description * This function is called from fwEvent_Handle on a sync read, or from TwIf as a CB on an async read. * It calls fwEvent_CallHandlers to handle the triggered interrupts. * * \sa fwEvent_Handle */ static ETxnStatus fwEvent_SmHandleEvents (TfwEvent *pFwEvent) { ETxnStatus eStatus; /* Save delta between driver and FW time (needed for Tx packets lifetime) */ pFwEvent->uFwTimeOffset = (os_timeStampMs (pFwEvent->hOs) * 1000) - ENDIAN_HANDLE_LONG (pFwEvent->tFwStatusTxn.tFwStatus.fwLocalTime); #ifdef HOST_INTR_MODE_LEVEL /* Acknowledge the host interrupt for LEVEL mode (must be after HINT_STT_CLR register clear on read) */ os_InterruptServiced (pFwEvent->hOs); #endif /* Save the interrupts status retreived from the FW */ pFwEvent->uEventVector = pFwEvent->tFwStatusTxn.tFwStatus.intrStatus; /* Mask unwanted interrupts */ pFwEvent->uEventVector &= pFwEvent->uEventMask; /* Call the interrupts handlers */ eStatus = fwEvent_CallHandlers (pFwEvent); /* Return the status of the handlers processing (complete, pending or error) */ return eStatus; }