Example #1
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;
}
Example #2
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;
}
Example #3
0
void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket)
{
    LOCK_AR6K(pDev);
    HTC_PACKET_ENQUEUE(&pDev->RegisterIOList,pPacket);
    UNLOCK_AR6K(pDev);
}
Example #4
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;
                AR_DEBUG_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;
}
Example #5
0
A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev)
{
    A_STATUS                  status;
    AR6K_IRQ_ENABLE_REGISTERS regs;

    LOCK_AR6K(pDev);

        /* Enable all the interrupts except for the internal AR6000 CPU interrupt */
    pDev->IrqEnableRegisters.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) |
                                      INT_STATUS_ENABLE_CPU_SET(0x01) |
                                      INT_STATUS_ENABLE_COUNTER_SET(0x01);

    if (NULL == pDev->GetPendingEventsFunc) {
        pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
    } else {
        /* The HIF layer provided us with a pending events function which means that
         * the detection of pending mbox messages is handled in the HIF layer.
         * This is the case for the SPI2 interface.
         * In the normal case we enable MBOX interrupts, for the case
         * with HIFs that offer this mechanism, we keep these interrupts
         * masked */
        pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
    }


    /* Set up the CPU Interrupt Status Register */
    pDev->IrqEnableRegisters.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00);

    /* Set up the Error Interrupt Status Register */
    pDev->IrqEnableRegisters.error_status_enable =
                                  ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) |
                                  ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01);

    /* Set up the Counter Interrupt Status Register (only for debug interrupt to catch fatal errors) */
    pDev->IrqEnableRegisters.counter_int_status_enable =
        COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK);

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

    UNLOCK_AR6K(pDev);

/* ATHENV */
/* ATHENV */
        /* always synchronous */
    status = HIFReadWrite(pDev->HIFDevice,
                          INT_STATUS_ENABLE_ADDRESS,
                          &regs.int_status_enable,
                          AR6K_IRQ_ENABLE_REGS_SIZE,
                          HIF_WR_SYNC_BYTE_INC,
                          NULL);

    if (status != A_OK) {
        /* Can't write it for some reason */
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                        ("Failed to update interrupt control registers err: %d\n", status));

    }

    return status;
}
Example #6
0
void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket)
{
    LOCK_AR6K(pDev);
    HTC_PACKET_ENQUEUE(&pDev->RegisterIOList,pPacket);
    UNLOCK_AR6K(pDev);
}
Example #7
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;
}