Esempio n. 1
0
/* callback when our fetch to enable/disable completes */
static void DevGMboxIRQActionAsyncHandler(void *Context, struct htc_packet *pPacket)
{
    struct ar6k_device *pDev = (struct ar6k_device *)Context;

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));

    if (pPacket->Status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("IRQAction Operation (%d) failed! status:%d \n", pPacket->PktInfo.AsRx.HTCRxFlags,pPacket->Status));
    }
        /* free this IO packet */
    AR6KFreeIOPacket(pDev,pPacket);
    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n"));
}
Esempio n. 2
0
/* callback when our fetch to enable/disable completes */
static void DevDoEnableDisableRecvAsyncHandler(void *Context, struct htc_packet *pPacket)
{
    struct ar6k_device *pDev = (struct ar6k_device *)Context;

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));

    if (pPacket->Status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                (" Failed to disable receiver, status:%d \n", pPacket->Status));
    }
        /* free this IO packet */
    AR6KFreeIOPacket(pDev,pPacket);
    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDoEnableDisableRecvAsyncHandler \n"));
}
Esempio n. 3
0
/* callback when our fetch to enable/disable completes */
static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket)
{
    AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%X)\n", (A_UINT32)pDev));

    if (A_FAILED(pPacket->Status)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("IRQAction Operation (%d) failed! status:%d \n", pPacket->PktInfo.AsRx.HTCRxFlags,pPacket->Status));
    }
        /* free this IO packet */
    AR6KFreeIOPacket(pDev,pPacket);
    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n"));
}
Esempio n. 4
0
/* callback when our fetch to enable/disable completes */
static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacket)
{
    AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));

    if (A_FAILED(pPacket->Status)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                (" Failed to disable receiver, status:%d \n", pPacket->Status));
    }
        /* free this IO packet */
    AR6KFreeIOPacket(pDev,pPacket);
    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDoEnableDisableRecvAsyncHandler \n"));
}
Esempio n. 5
0
static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket)
{
    AR6K_DEVICE     *pDev = (AR6K_DEVICE *)Context;
    HIF_SCATTER_REQ *pReq = (HIF_SCATTER_REQ *)pPacket->pPktContext;
    
    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevReadWriteScatterAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
    
    pReq->CompletionStatus = pPacket->Status;

    AR6KFreeIOPacket(pDev,pPacket);

    pReq->CompletionRoutine(pReq);

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n"));
}
Esempio n. 6
0
static void DevReadWriteScatterAsyncHandler(void *Context, struct htc_packet *pPacket)
{
    struct ar6k_device     *pDev = (struct ar6k_device *)Context;
    struct hif_scatter_req *pReq = (struct hif_scatter_req *)pPacket->pPktContext;
    
    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevReadWriteScatterAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
    
    pReq->CompletionStatus = pPacket->Status;

    AR6KFreeIOPacket(pDev,pPacket);

    pReq->CompletionRoutine(pReq);

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n"));
}
Esempio n. 7
0
/* disable packet reception (used in case the host runs out of buffers)
 * this is the "override" method when the HIF reports another methods to
 * disable recv events */
static A_STATUS DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode)
{
    A_STATUS                  status = A_OK;
    HTC_PACKET                *pIOPacket = NULL;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n",
            EnableRecv,AsyncMode));

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(FALSE);
                break;
            }

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
            pIOPacket->pContext = pDev;

                /* call the HIF layer override and do this asynchronously */
            status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
                                                 EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
                                                 pIOPacket);
            break;
        }

            /* if we get here we are doing it synchronously */
        status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
                                             EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
                                             NULL);

    } while (FALSE);

    if (A_FAILED(status) && (pIOPacket != NULL)) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }

    return status;
}
Esempio n. 8
0
/* disable packet reception (used in case the host runs out of buffers)
 * this is the "override" method when the HIF reports another methods to
 * disable recv events */
static int DevDoEnableDisableRecvOverride(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode)
{
    int                  status = 0;
    struct htc_packet                *pIOPacket = NULL;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n",
            EnableRecv,AsyncMode));

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(false);
                break;
            }

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
            pIOPacket->pContext = pDev;

                /* call the HIF layer override and do this asynchronously */
            status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
                                                 EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
                                                 pIOPacket);
            break;
        }

            /* if we get here we are doing it synchronously */
        status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
                                             EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
                                             NULL);

    } while (false);

    if (status && (pIOPacket != NULL)) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }

    return status;
}
Esempio n. 9
0
/* callback when our fetch to enable/disable completes */
static void DevGMboxReadCreditsAsyncHandler(void *Context, struct htc_packet *pPacket)
{
    struct ar6k_device *pDev = (struct ar6k_device *)Context;

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));

    if (pPacket->Status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("Read Credit Operation failed! status:%d \n", pPacket->Status));
    } else {
        int credits = 0;
        credits = ProcessCreditCounterReadBuffer(pPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);
        pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext,
                                                credits,
                                                pDev->GMboxInfo.CreditCountIRQEnabled);
        
        
    }
        /* free this IO packet */
    AR6KFreeIOPacket(pDev,pPacket);
    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n"));
}
Esempio n. 10
0
/* callback when our fetch to enable/disable completes */
static void DevGMboxReadCreditsAsyncHandler(void *Context, HTC_PACKET *pPacket)
{
    AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%X)\n", (A_UINT32)pDev));

    if (A_FAILED(pPacket->Status)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("Read Credit Operation failed! status:%d \n", pPacket->Status));
    } else {
        int credits = 0;
        credits = ProcessCreditCounterReadBuffer(pPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);
        pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext,
                                                credits,
                                                pDev->GMboxInfo.CreditCountIRQEnabled);
        
        
    }
        /* free this IO packet */
    AR6KFreeIOPacket(pDev,pPacket);
    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n"));
}
Esempio n. 11
0
A_STATUS DevSetup(AR6K_DEVICE *pDev)
{
    A_UINT32 blocksizes[AR6K_MAILBOXES];
    A_STATUS status = A_OK;
    int      i;
    HTC_CALLBACKS htcCallbacks;

    do {

        DL_LIST_INIT(&pDev->ScatterReqHead);
           /* initialize our free list of IO packets */
        INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList);
        A_MUTEX_INIT(&pDev->Lock);

        A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS));
            /* the device layer handles these */
        htcCallbacks.rwCompletionHandler = DevRWCompletionHandler;
        htcCallbacks.dsrHandler = DevDsrHandler;
        htcCallbacks.context = pDev;

        status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks);

        if (A_FAILED(status)) {
            break;
        }

        pDev->HifAttached = TRUE;

            /* get the addresses for all 4 mailboxes */
        status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR,
                                    &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo));

        if (status != A_OK) {
            A_ASSERT(FALSE);
            break;
        }

            /* carve up register I/O packets (these are for ASYNC register I/O ) */
        for (i = 0; i < AR6K_MAX_REG_IO_BUFFERS; i++) {
            HTC_PACKET *pIOPacket;
            pIOPacket = &pDev->RegIOBuffers[i].HtcPacket;
            SET_HTC_PACKET_INFO_RX_REFILL(pIOPacket,
                                          pDev,
                                          pDev->RegIOBuffers[i].Buffer,
                                          AR6K_REG_IO_BUFFER_SIZE,
                                          0); /* don't care */
            AR6KFreeIOPacket(pDev,pIOPacket);
        }

            /* get the block sizes */
        status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
                                    blocksizes, sizeof(blocksizes));

        if (status != A_OK) {
            A_ASSERT(FALSE);
            break;
        }

            /* note: we actually get the block size of a mailbox other than 0, for SDIO the block
             * size on mailbox 0 is artificially set to 1.  So we use the block size that is set
             * for the other 3 mailboxes */
        pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE];
            /* must be a power of 2 */
        A_ASSERT((pDev->BlockSize & (pDev->BlockSize - 1)) == 0);

            /* assemble mask, used for padding to a block */
        pDev->BlockMask = pDev->BlockSize - 1;

        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("BlockSize: %d, MailboxAddress:0x%X \n",
                    pDev->BlockSize, pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]));

        pDev->GetPendingEventsFunc = NULL;
            /* see if the HIF layer implements the get pending events function  */
        HIFConfigureDevice(pDev->HIFDevice,
                           HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
                           &pDev->GetPendingEventsFunc,
                           sizeof(pDev->GetPendingEventsFunc));

            /* assume we can process HIF interrupt events asynchronously */
        pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC;

            /* see if the HIF layer overrides this assumption */
        HIFConfigureDevice(pDev->HIFDevice,
                           HIF_DEVICE_GET_IRQ_PROC_MODE,
                           &pDev->HifIRQProcessingMode,
                           sizeof(pDev->HifIRQProcessingMode));

        switch (pDev->HifIRQProcessingMode) {
            case HIF_DEVICE_IRQ_SYNC_ONLY:
                AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HIF Interrupt processing is SYNC ONLY\n"));
                    /* see if HIF layer wants HTC to yield */
                HIFConfigureDevice(pDev->HIFDevice,
                                   HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
                                   &pDev->HifIRQYieldParams,
                                   sizeof(pDev->HifIRQYieldParams));

                if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) {
                    AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
                        ("HIF requests that DSR yield per %d RECV packets \n",
                        pDev->HifIRQYieldParams.RecvPacketYieldCount));
                    pDev->DSRCanYield = TRUE;
                }
                break;
            case HIF_DEVICE_IRQ_ASYNC_SYNC:
                AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYNC and SYNC\n"));
                break;
            default:
                A_ASSERT(FALSE);
        }

        pDev->HifMaskUmaskRecvEvent = NULL;

            /* see if the HIF layer implements the mask/unmask recv events function  */
        HIFConfigureDevice(pDev->HIFDevice,
                           HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
                           &pDev->HifMaskUmaskRecvEvent,
                           sizeof(pDev->HifMaskUmaskRecvEvent));

        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%lX , 0x%lX\n",
                 (unsigned long)pDev->GetPendingEventsFunc, (unsigned long)pDev->HifMaskUmaskRecvEvent));

        status = DevDisableInterrupts(pDev);

        if (A_FAILED(status)) {
            break;
        }

        status = DevSetupGMbox(pDev);

    } while (FALSE);

    if (A_FAILED(status)) {
        if (pDev->HifAttached) {
            HIFDetachHTC(pDev->HIFDevice);
            pDev->HifAttached = FALSE;
        }
    }

    return status;

}
Esempio n. 12
0
static A_STATUS DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq)
{
    AR6K_DEVICE     *pDev = (AR6K_DEVICE *)Context;
    A_STATUS        status = A_OK;
    HTC_PACKET      *pIOPacket = NULL;
    A_UINT32        request = pReq->Request;

    do {

        if (pReq->TotalLength > AR6K_MAX_TRANSFER_SIZE_PER_SCATTER) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                            ("Invalid length: %d \n", pReq->TotalLength));
            break;
        }

        if (pReq->TotalLength == 0) {
            A_ASSERT(FALSE);
            break;
        }

        if (request & HIF_ASYNCHRONOUS) {
                /* use an I/O packet to carry this request */
            pIOPacket = AR6KAllocIOPacket(pDev);
            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                break;
            }

                /* save the request */
            pIOPacket->pPktContext = pReq;
                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevReadWriteScatterAsyncHandler;
            pIOPacket->pContext = pDev;
        }

        if (request & HIF_WRITE) {
            /* in virtual DMA, we are issuing the requests through the legacy HIFReadWrite API
             * this API will adjust the address automatically for the last byte to fall on the mailbox
             * EOM. */

            /* if the address is an extended address, we can adjust the address here since the extended
             * address will bypass the normal checks in legacy HIF layers */
            if (pReq->Address == pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress) {
                pReq->Address += pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize - pReq->TotalLength;
            }
        }

            /* use legacy readwrite */
        status = HIFReadWrite(pDev->HIFDevice,
                              pReq->Address,
                              DEV_GET_VIRT_DMA_INFO(pReq)->pVirtDmaBuffer,
                              pReq->TotalLength,
                              request,
                              (request & HIF_ASYNCHRONOUS) ? pIOPacket : NULL);

    } while (FALSE);

    if ((status != A_PENDING) && A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) {
        if (pIOPacket != NULL) {
            AR6KFreeIOPacket(pDev,pIOPacket);
        }
        pReq->CompletionStatus = status;
        pReq->CompletionRoutine(pReq);
        status = A_OK;
    }

    return status;
}
Esempio n. 13
0
/* disable packet reception (used in case the host runs out of buffers)
 * this is the "normal" method using the interrupt enable registers through
 * the host I/F */
static A_STATUS DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode)
{
    A_STATUS                  status = A_OK;
    HTC_PACKET                *pIOPacket = NULL;
    AR6K_IRQ_ENABLE_REGISTERS regs;

        /* take the lock to protect interrupt enable shadows */
    LOCK_AR6K(pDev);

    if (EnableRecv) {
        pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
    } else {
        pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
    }

        /* copy into our temp area */
    A_MEMCPY(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
    UNLOCK_AR6K(pDev);

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(FALSE);
                break;
            }

                /* copy values to write to our async I/O buffer */
            A_MEMCPY(pIOPacket->pBuffer,&regs,AR6K_IRQ_ENABLE_REGS_SIZE);

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
            pIOPacket->pContext = pDev;

                /* write it out asynchronously */
            HIFReadWrite(pDev->HIFDevice,
                         INT_STATUS_ENABLE_ADDRESS,
                         pIOPacket->pBuffer,
                         AR6K_IRQ_ENABLE_REGS_SIZE,
                         HIF_WR_ASYNC_BYTE_INC,
                         pIOPacket);
            break;
        }

        /* if we get here we are doing it synchronously */

        status = HIFReadWrite(pDev->HIFDevice,
                              INT_STATUS_ENABLE_ADDRESS,
                              &regs.int_status_enable,
                              AR6K_IRQ_ENABLE_REGS_SIZE,
                              HIF_WR_SYNC_BYTE_INC,
                              NULL);

    } while (FALSE);

    if (A_FAILED(status) && (pIOPacket != NULL)) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }

    return status;
}
/* callback when our fetch to get interrupt status registers completes */
static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket)
{
    AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
    u32 lookAhead = 0;
    bool      otherInts = false;

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));

    do {

        if (pPacket->Status) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                    (" GetEvents I/O request failed, status:%d \n", pPacket->Status));
            /* bail out, don't unmask HIF interrupt */
            break;
        }

        if (pDev->GetPendingEventsFunc != NULL) {
                /* the HIF layer collected the information for us */
            HIF_PENDING_EVENTS_INFO *pEvents = (HIF_PENDING_EVENTS_INFO *)pPacket->pBuffer;
            if (pEvents->Events & HIF_RECV_MSG_AVAIL) {
                lookAhead = pEvents->LookAhead;
                if (0 == lookAhead) {
                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler1, lookAhead is zero! \n"));
                }
            }
            if (pEvents->Events & HIF_OTHER_EVENTS) {
                otherInts = true;
            }
        } else {
                /* standard interrupt table handling.... */
            AR6K_IRQ_PROC_REGISTERS *pReg = (AR6K_IRQ_PROC_REGISTERS *)pPacket->pBuffer;
            u8 host_int_status;

            host_int_status = pReg->host_int_status & pDev->IrqEnableRegisters.int_status_enable;

            if (host_int_status & (1 << HTC_MAILBOX)) {
                host_int_status &= ~(1 << HTC_MAILBOX);
                if (pReg->rx_lookahead_valid & (1 << HTC_MAILBOX)) {
                        /* mailbox has a message and the look ahead is valid */
                    lookAhead = pReg->rx_lookahead[HTC_MAILBOX];
                    if (0 == lookAhead) {
                        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler2, lookAhead is zero! \n"));
                    }
                }
            }

            if (host_int_status) {
                    /* there are other interrupts to handle */
                otherInts = true;
            }
        }

        if (otherInts || (lookAhead == 0)) {
            /* if there are other interrupts to process, we cannot do this in the async handler so
             * ack the interrupt which will cause our sync handler to run again
             * if however there are no more messages, we can now ack the interrupt  */
            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
                (" Acking interrupt from DevGetEventAsyncHandler (otherints:%d, lookahead:0x%X)\n",
                otherInts, lookAhead));
            HIFAckInterrupt(pDev->HIFDevice);
        } else {
            int      fetched = 0;
            int status;

            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
                    (" DevGetEventAsyncHandler : detected another message, lookahead :0x%X \n",
                    lookAhead));
                /* lookahead is non-zero and there are no other interrupts to service,
                 * go get the next message */
            status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, NULL, &fetched);

            if (!status && !fetched) {
                    /* HTC layer could not pull out messages due to lack of resources, stop IRQ processing */
                AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("MessagePendingCallback did not pull any messages, force-ack \n"));
                DevAsyncIrqProcessComplete(pDev);
            }
        }

    } while (false);

        /* free this IO packet */
    AR6KFreeIOPacket(pDev,pPacket);
    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGetEventAsyncHandler \n"));
}
Esempio n. 15
0
static int DevGMboxCounterEnableDisable(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode)
{
    int                  status = 0;
    struct ar6k_irq_enable_registers regs;
    struct htc_packet                *pIOPacket = NULL;  
    
    LOCK_AR6K(pDev);
    
    if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
        pDev->GMboxInfo.CreditCountIRQEnabled = true;
        pDev->IrqEnableRegisters.counter_int_status_enable |=
            COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER);
        pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_COUNTER_SET(0x01);
    } else {
        pDev->GMboxInfo.CreditCountIRQEnabled = false;
        pDev->IrqEnableRegisters.counter_int_status_enable &=
            ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER));    
    }
        /* copy into our temp area */
    memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);

    UNLOCK_AR6K(pDev);

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(false);
                break;
            }

                /* copy values to write to our async I/O buffer */
            memcpy(pIOPacket->pBuffer,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
            pIOPacket->pContext = pDev;
            pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
                /* write it out asynchronously */
            HIFReadWrite(pDev->HIFDevice,
                         INT_STATUS_ENABLE_ADDRESS,
                         pIOPacket->pBuffer,
                         AR6K_IRQ_ENABLE_REGS_SIZE,
                         HIF_WR_ASYNC_BYTE_INC,
                         pIOPacket);
                         
            pIOPacket = NULL; 
            break;
        } 

            /* if we get here we are doing it synchronously */
        status = HIFReadWrite(pDev->HIFDevice,
                              INT_STATUS_ENABLE_ADDRESS,
                              &regs.int_status_enable,
                              AR6K_IRQ_ENABLE_REGS_SIZE,
                              HIF_WR_SYNC_BYTE_INC,
                              NULL);    
    } while (false);
    
    if (status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));    
    } else {
        if (!AsyncMode) {
            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
                    (" IRQAction Operation (%d) success \n", IrqAction)); 
        }       
    }
    
    if (pIOPacket != NULL) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }
        
    return status;
}
Esempio n. 16
0
int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits)
{
    int    status = 0;
    struct htc_packet  *pIOPacket = NULL;  
    
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC"));
                                            
    do {
        
        pIOPacket = AR6KAllocIOPacket(pDev);

        if (NULL == pIOPacket) {
            status = A_NO_MEMORY;
            A_ASSERT(false);
            break;
        }
        
        A_MEMZERO(pIOPacket->pBuffer,AR6K_REG_IO_BUFFER_SIZE);
      
        if (AsyncMode) {   
                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevGMboxReadCreditsAsyncHandler;
            pIOPacket->pContext = pDev;
                /* read registers asynchronously */
            HIFReadWrite(pDev->HIFDevice,
                         AR6K_GMBOX_CREDIT_DEC_ADDRESS,
                         pIOPacket->pBuffer,
                         AR6K_REG_IO_BUFFER_SIZE,  /* hit the register multiple times */
                         HIF_RD_ASYNC_BYTE_FIX,
                         pIOPacket);
            pIOPacket = NULL;
            break;
        } 

        pIOPacket->Completion = NULL;
            /* if we get here we are doing it synchronously */
        status = HIFReadWrite(pDev->HIFDevice,
                              AR6K_GMBOX_CREDIT_DEC_ADDRESS,
                              pIOPacket->pBuffer,
                              AR6K_REG_IO_BUFFER_SIZE,
                              HIF_RD_SYNC_BYTE_FIX,
                              NULL);    
    } while (false);
    
    if (status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                (" DevGMboxReadCreditCounter failed! status:%d \n", status));          
    }
    
    if (pIOPacket != NULL) {
        if (!status) {
                /* sync mode processing */
            *pCredits = ProcessCreditCounterReadBuffer(pIOPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);     
        }
        AR6KFreeIOPacket(pDev,pIOPacket);
    }
    
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-DevGMboxReadCreditCounter (%s) (%d) \n", 
            AsyncMode ? "ASYNC" : "SYNC", status));
    
    return status;
}
Esempio n. 17
0
int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode)
{
    int      status = 0;
    struct htc_packet    *pIOPacket = NULL;   
    u8 GMboxIntControl[4];

    if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
        return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_ENABLE, AsyncMode);
    } else if(GMBOX_CREDIT_IRQ_DISABLE == IrqAction) {
        return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);
    }
    
    if (GMBOX_DISABLE_ALL == IrqAction) {
            /* disable credit IRQ, those are on a different set of registers */
        DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);    
    }
            
        /* take the lock to protect interrupt enable shadows */
    LOCK_AR6K(pDev);

    switch (IrqAction) {
        
        case GMBOX_DISABLE_ALL:
            pDev->GMboxControlRegisters.int_status_enable = 0;
            break;
        case GMBOX_ERRORS_IRQ_ENABLE:
            pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_TX_OVERFLOW |
                                                             GMBOX_INT_STATUS_RX_OVERFLOW;
            break;
        case GMBOX_RECV_IRQ_ENABLE:
            pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_RX_DATA;
            break;
        case GMBOX_RECV_IRQ_DISABLE:
            pDev->GMboxControlRegisters.int_status_enable &= ~GMBOX_INT_STATUS_RX_DATA;
            break;
        case GMBOX_ACTION_NONE:
        default:
            A_ASSERT(false);
            break;
    }
    
    GMboxIntControl[0] = pDev->GMboxControlRegisters.int_status_enable;
    GMboxIntControl[1] = GMboxIntControl[0];
    GMboxIntControl[2] = GMboxIntControl[0];
    GMboxIntControl[3] = GMboxIntControl[0];
    
    UNLOCK_AR6K(pDev);

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(false);
                break;
            }

                /* copy values to write to our async I/O buffer */
            memcpy(pIOPacket->pBuffer,GMboxIntControl,sizeof(GMboxIntControl));

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
            pIOPacket->pContext = pDev;
            pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
                /* write it out asynchronously */
            HIFReadWrite(pDev->HIFDevice,
                         GMBOX_INT_STATUS_ENABLE_REG,
                         pIOPacket->pBuffer,
                         sizeof(GMboxIntControl),
                         HIF_WR_ASYNC_BYTE_FIX,
                         pIOPacket);
            pIOPacket = NULL;
            break;
        }

        /* if we get here we are doing it synchronously */

        status = HIFReadWrite(pDev->HIFDevice,
                              GMBOX_INT_STATUS_ENABLE_REG,
                              GMboxIntControl,
                              sizeof(GMboxIntControl),
                              HIF_WR_SYNC_BYTE_FIX,
                              NULL);

    } while (false);

    if (status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));    
    } else {
        if (!AsyncMode) {
            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
                    (" IRQAction Operation (%d) success \n", IrqAction)); 
        }      
    }
    
    if (pIOPacket != NULL) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }

    return status;
}
Esempio n. 18
0
/* disable packet reception (used in case the host runs out of buffers)
 * this is the "normal" method using the interrupt enable registers through
 * the host I/F */
static int DevDoEnableDisableRecvNormal(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode)
{
    int                  status = 0;
    struct htc_packet                *pIOPacket = NULL;
    struct ar6k_irq_enable_registers regs;

        /* take the lock to protect interrupt enable shadows */
    LOCK_AR6K(pDev);

    if (EnableRecv) {
        pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
    } else {
        pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
    }

        /* copy into our temp area */
    memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
    UNLOCK_AR6K(pDev);

    do {

        if (AsyncMode) {

            pIOPacket = AR6KAllocIOPacket(pDev);

            if (NULL == pIOPacket) {
                status = A_NO_MEMORY;
                A_ASSERT(false);
                break;
            }

                /* copy values to write to our async I/O buffer */
            memcpy(pIOPacket->pBuffer,&regs,AR6K_IRQ_ENABLE_REGS_SIZE);

                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
            pIOPacket->pContext = pDev;

                /* write it out asynchronously */
            HIFReadWrite(pDev->HIFDevice,
                         INT_STATUS_ENABLE_ADDRESS,
                         pIOPacket->pBuffer,
                         AR6K_IRQ_ENABLE_REGS_SIZE,
                         HIF_WR_ASYNC_BYTE_INC,
                         pIOPacket);
            break;
        }

        /* if we get here we are doing it synchronously */

        status = HIFReadWrite(pDev->HIFDevice,
                              INT_STATUS_ENABLE_ADDRESS,
                              &regs.int_status_enable,
                              AR6K_IRQ_ENABLE_REGS_SIZE,
                              HIF_WR_SYNC_BYTE_INC,
                              NULL);

    } while (false);

    if (status && (pIOPacket != NULL)) {
        AR6KFreeIOPacket(pDev,pIOPacket);
    }

    return status;
}