/** 
 * \fn     busDrv_Transact
 * \brief  Process transaction 
 * 
 * Called by the TxnQ module to initiate a new transaction.
 * Prepare the transaction parts (lower layer single transactions),
 *      and send them one by one to the lower layer.
 * 
 * \note   It's assumed that this function is called only when idle (i.e. previous Txn is done).
 * \param  hBusDrv - The module's object
 * \param  pTxn    - The transaction object 
 * \return COMPLETE if Txn completed in this context, PENDING if not, ERROR if failed
 * \sa     busDrv_PrepareTxnParts, busDrv_SendTxnParts
 */ 
ETxnStatus busDrv_Transact (TI_HANDLE hBusDrv, TTxnStruct *pTxn)
{
    TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;
    TI_BOOL     bWithinAggregation;
    CL_TRACE_START_L4();

    pBusDrv->pCurrTxn               = pTxn;
    pBusDrv->uCurrTxnPartsCount     = 0;
    pBusDrv->uCurrTxnPartsCountSync = 0;

    /* Set status OK in Txn struct (changed later to error if transaction fails) */
    TXN_PARAM_SET_STATUS(pTxn, TXN_PARAM_STATUS_OK);

    /* Prepare the transaction parts in a table. */
    bWithinAggregation = busDrv_PrepareTxnParts (pBusDrv, pTxn);

    /* If in the middle of Tx aggregation, return Complete (current Txn was coppied to buffer but not sent) */
    if (bWithinAggregation)
    {
        TRACE1(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_Transact: In aggregation so exit, uTxnLength=%d\n", pBusDrv->uTxnLength);
        CL_TRACE_END_L4("tiwlan_drv.ko", "INHERIT", "TXN", ".Transact");
        return TXN_STATUS_COMPLETE;
    }

    /* Send the prepared transaction parts. */
    busDrv_SendTxnParts (pBusDrv);

    TRACE1(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_Transact: Status = %d\n", pBusDrv->eCurrTxnStatus);

    CL_TRACE_END_L4("tiwlan_drv.ko", "INHERIT", "TXN", ".Transact");

    /* return transaction status - COMPLETE, PENDING or ERROR */
    /* The status is updated in busDrv_SendTxnParts(). It is Async (pending) if not completed in this context */
    return pBusDrv->eCurrTxnStatus;
}
예제 #2
0
/*
 * \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;
} 
예제 #3
0
/*
 * \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;
}