⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htc_events.c

📁 Atheros Communications AR6001 WLAN Driver for SDIO installation Read Me March 26,2007 (based on
💻 C
📖 第 1 页 / 共 3 页
字号:
    } else {
        /* Ack the interrupt */
        HIFAckInterrupt(target->device);

    }

    HTC_DEBUG_PRINTF(ATH_LOG_TRC, "htcDSRHandler: Exit\n");
    return A_OK;
}

void
htcServiceCPUInterrupt(HTC_TARGET *target)
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    A_UINT8 cpu_int_status;

    HTC_DEBUG_PRINTF(ATH_LOG_INF, "CPU Interrupt\n");
    cpu_int_status = target->table.cpu_int_status &
                     target->table.cpu_int_status_enable;
    AR_DEBUG_ASSERT(cpu_int_status);
    HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                    "Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
                    cpu_int_status);

    /* Figure out the interrupt number */
    HTC_DEBUG_PRINTF(ATH_LOG_INF, "Interrupt Number: 0x%x\n", 
                    htcGetBitNumSet(cpu_int_status));

    /* Clear the interrupt */
    target->table.cpu_int_status = cpu_int_status; /* W1C */
    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, 
                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
    address = getRegAddr(CPU_INT_STATUS_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          &target->table.cpu_int_status, 1, &request, NULL);

    AR_DEBUG_ASSERT(status == A_OK);
}


void
htcServiceErrorInterrupt(HTC_TARGET *target)
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    A_UINT8 error_int_status;

    HTC_DEBUG_PRINTF(ATH_LOG_INF, "Error Interrupt\n");
    error_int_status = target->table.error_int_status &
                       target->table.error_status_enable;
    AR_DEBUG_ASSERT(error_int_status);
    HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                    "Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
                    error_int_status);

    if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) {
        /* Wakeup */
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "Wakeup\n");
    }
        
    if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) {
        /* Rx Underflow */
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "Rx Underflow\n");
    }
        
    if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) {
        /* Tx Overflow */
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "Tx Overflow\n");
    }

    /* Clear the interrupt */
    target->table.error_int_status = error_int_status; /* W1C */
    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, 
                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
    address = getRegAddr(ERROR_INT_STATUS_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          &target->table.error_int_status, 1,
                          &request, NULL);

    AR_DEBUG_ASSERT(status == A_OK);
}

void
htcServiceCounterInterrupt(HTC_TARGET *target)
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    HTC_ENDPOINT *endPoint;
    HTC_ENDPOINT_ID endPointId;
    A_UINT8 counter_int_status;
    A_UINT8 reset_credit_int_status;
    A_UINT8 update_credit_int_status;
    HTC_REG_REQUEST_ELEMENT *element;

    HTC_DEBUG_PRINTF(ATH_LOG_INF, "Counter Interrupt\n");

    counter_int_status = target->table.counter_int_status &
                         target->table.counter_int_status_enable;
    AR_DEBUG_ASSERT(counter_int_status);
    HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                    "Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
                    counter_int_status);

    /* Service the reset credit counter interrupt */
    reset_credit_int_status = (counter_int_status & 0x0F);
    while(reset_credit_int_status) {
        endPointId = htcGetBitNumSet(reset_credit_int_status);
        endPoint = &target->endPoint[endPointId];
        AR_DEBUG_ASSERT(endPoint != NULL);

        HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                        "endPoint(%d): %p\n", endPointId, endPoint);

        /* Initialize the number of credits available to zero */
	    HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
                   "Critical Section (credit): LOCK at line %d in file %s\n", __LINE__, __FILE__);
		A_MUTEX_LOCK(&creditCS);
        SET_TX_CREDITS_AVAILABLE(endPoint, 0);
	    HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
                  "Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__);
		A_MUTEX_UNLOCK(&creditCS);

        /* Clear the interrupt */
        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, 
                          HIF_ASYNCHRONOUS, HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
        address = getRegAddr(TX_CREDIT_COUNTER_RESET_REG, endPointId);
        element = allocateRegRequestElement(target);
        AR_DEBUG_ASSERT(element != NULL);
        FILL_REG_BUFFER(element, &endPoint->txCreditsAvailable[1], sizeof(endPoint->txCreditsAvailable[1]),
                        TX_CREDIT_COUNTER_RESET_REG, endPointId);
        status = HIFReadWrite(target->device, address, 
                              (A_UCHAR *)&endPoint->txCreditsAvailable[1],
                              sizeof(endPoint->txCreditsAvailable[1]), &request, element);

#ifndef HTC_SYNC
        AR_DEBUG_ASSERT(status == A_OK);
#else
        AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
		if (status == A_OK) {
        	/* Enable the Tx credit counter interrupt so that we can get the
             * credits posted by the target */
        	htcEnableCreditCounterInterrupt(target, endPointId);
		}
#endif
        reset_credit_int_status &= 
            ~(1 << htcGetBitNumSet(reset_credit_int_status));
    }

    /* Disable the credit counter interrupt */
    htcDisableCreditCounterInterrupt(target, ENDPOINT_UNUSED);

    /* Service the credit counter interrupt */
    update_credit_int_status = counter_int_status & 0xF0;
    while(update_credit_int_status) {
        endPointId = htcGetBitNumSet(update_credit_int_status) - 
                     HTC_MAILBOX_NUM_MAX;
        endPoint = &target->endPoint[endPointId];
        AR_DEBUG_ASSERT(endPoint != NULL);

        /* This is the minimum number of credits that we would have got */
        AR_DEBUG_ASSERT(GET_TX_CREDITS_AVAILABLE(endPoint) == 0);
	    HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
                   "Critical Section (credit): LOCK at line %d in file %s\n", __LINE__, __FILE__);
		A_MUTEX_LOCK(&creditCS);
        SET_TX_CREDITS_AVAILABLE(endPoint, 1);
		HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
                   "Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__);
		A_MUTEX_UNLOCK(&creditCS);


#ifdef DEBUG
        txcreditsavailable[endPointId] = GET_TX_CREDITS_AVAILABLE(endPoint);
        txcreditintrenable[endPointId] -= 1;
#endif /* DEBUG */

        HTC_DEBUG_PRINTF(ATH_LOG_INF, "Tx Credits Available: %d\n", 
                                        GET_TX_CREDITS_AVAILABLE(endPoint));

        if (!target->ready) {
            htcSendBlkSize(endPoint);
        } else {
            htcSendFrame(endPoint);
        }

        update_credit_int_status &= 
            ~(1 << htcGetBitNumSet(update_credit_int_status));
    }
}

void
htcEnableCreditCounterInterrupt(HTC_TARGET *target, 
                                HTC_ENDPOINT_ID endPointId)
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    HTC_ENDPOINT *endPoint;
    HTC_REG_REQUEST_ELEMENT *element;
#ifdef ONLY_16BIT
	A_UINT16 counter_int_enable16;
#endif
	A_UCHAR	counter_int_enable;


    endPoint = &target->endPoint[endPointId];
    AR_DEBUG_ASSERT(endPoint != NULL);

    A_MUTEX_LOCK(&counterCS);

    endPoint->txCreditsIntrEnable = TRUE;
    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, 
                      HIF_ASYNCHRONOUS, HIF_BYTE_BASIS, 
                      HIF_FIXED_ADDRESS);
    element = allocateRegRequestElement(target);
    AR_DEBUG_ASSERT(element != NULL);

    counter_int_enable = ((target->endPoint[0].txCreditsIntrEnable << (4)) |
                         (target->endPoint[1].txCreditsIntrEnable << (5)) |
                         (target->endPoint[2].txCreditsIntrEnable << (6)) |
                         (target->endPoint[3].txCreditsIntrEnable << (7)) |
                         0x0F);
	

#ifdef ONLY_16BIT
    counter_int_enable16 = (counter_int_enable << 8) | target->table.error_status_enable;

    FILL_REG_BUFFER(element, NULL, 2, COUNTER_INT_STATUS_ENABLE_REG, counter_int_enable16);
	address = getRegAddr(ERROR_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
                          2, &request, element);
#else
    FILL_REG_BUFFER(element, NULL, 1, COUNTER_INT_STATUS_ENABLE_REG, counter_int_enable);
    address = getRegAddr(COUNTER_INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
                          1, &request, element);
#endif

#ifndef HTC_SYNC
    AR_DEBUG_ASSERT(status == A_OK);
#else
    AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
    if (status == A_OK) { 
        element->completionCB(element, status);
    }
#endif

    A_MUTEX_UNLOCK(&counterCS);
}

void
htcDisableCreditCounterInterrupt(HTC_TARGET *target, 
                                 HTC_ENDPOINT_ID unused)
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    HTC_ENDPOINT *endPoint;
    HTC_ENDPOINT_ID endPointId;
    A_UINT8 update_credit_int_status;
    HTC_REG_REQUEST_ELEMENT *element;
#ifdef ONLY_16BIT
	A_UINT16 counter_int_enable16;
#endif
	A_UCHAR	counter_int_enable;

    A_MUTEX_LOCK(&counterCS);

    /* The Tx credit counter update bits are reflected in the upper nibble */
    update_credit_int_status = target->table.counter_int_status & 0xF0;

    while(update_credit_int_status) {
        endPointId = htcGetBitNumSet(update_credit_int_status) - 
                     HTC_MAILBOX_NUM_MAX;
        endPoint = &target->endPoint[endPointId];
        AR_DEBUG_ASSERT(endPoint != NULL);

        HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                        "endPoint(%d): %p\n", endPointId, endPoint);

        /* Disable the tx credit interrupt */
        endPoint->txCreditsIntrEnable = FALSE;

        update_credit_int_status &= 
            ~(1 << htcGetBitNumSet(update_credit_int_status));
    }


    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_ASYNCHRONOUS, 
                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);

    element = allocateRegRequestElement(target);
    AR_DEBUG_ASSERT(element != NULL);

    counter_int_enable = ((target->endPoint[0].txCreditsIntrEnable << (4)) |
						 (target->endPoint[1].txCreditsIntrEnable << (5)) |
						 (target->endPoint[2].txCreditsIntrEnable << (6)) |
                         (target->endPoint[3].txCreditsIntrEnable << (7)) | 0x0F);

#ifdef ONLY_16BIT
    counter_int_enable16 = (counter_int_enable << 8) | target->table.error_status_enable;

    FILL_REG_BUFFER(element, NULL, 2, COUNTER_INT_STATUS_DISABLE_REG, 
					counter_int_enable16);
	address = getRegAddr(ERROR_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
                          2, &request, element);
#else
    FILL_REG_BUFFER(element, NULL, 1, COUNTER_INT_STATUS_DISABLE_REG, 
					counter_int_enable);
	address = getRegAddr(COUNTER_INT_STATUS_DISABLE_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
                          1, &request, element);
#endif

#ifndef HTC_SYNC
    AR_DEBUG_ASSERT(status == A_OK);
#else
    AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
	if ( status == A_OK ) {
		element->completionCB(element, status);
	}
#endif

    A_MUTEX_UNLOCK(&counterCS);
}

void
htcServiceMailboxInterrupt(HTC_TARGET *target)
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    HTC_ENDPOINT *endPoint;
    HTC_ENDPOINT_ID endPointId;
    A_UINT8 mailbox_int_status;

    HTC_DEBUG_PRINTF(ATH_LOG_INF, "Mailbox Interrupt\n");

    /* The Rx interrupt bits are reflected in the lower nibble */
    mailbox_int_status = target->table.host_int_status & 
                         HOST_INT_STATUS_MBOX_DATA_MASK;
    HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                    "Valid mailbox interrupt source(s) in INT_STATUS: 0x%x\n",
                    mailbox_int_status);

    /* Disable the receive interrupt for all four mailboxes */
    target->table.int_status_enable &= ~(HOST_INT_STATUS_MBOX_DATA_MASK);

    do {
        while(mailbox_int_status) {
            endPointId = htcGetBitNumSet(mailbox_int_status);
            endPoint = &target->endPoint[endPointId];
            AR_DEBUG_ASSERT(endPoint != NULL);
    
            HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                            "endPoint(%d): %p\n", endPointId, endPoint);

            /* Service the Rx interrupt */
            htcReceiveFrame(endPoint);
            mailbox_int_status &= ~(1 << htcGetBitNumSet(mailbox_int_status));
        }

        /* 
         * Read the register table again. Repeat the process until there are
         * no more valid packets queued up on receive. It is assumed that
         * the following request will be serialized along with the request
         * above and will be completed in the order in which it is received
         * by the bus driver.
         */
        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, 
                          HIF_SYNCHRONOUS, HIF_BYTE_BASIS, 
                          HIF_INCREMENTAL_ADDRESS);
        address = getRegAddr(INT_STATUS_REG, ENDPOINT_UNUSED);
        status = HIFReadWrite(target->device, address, 
                              &target->table.host_int_status, 
                              24, &request, NULL);
        AR_DEBUG_ASSERT(status == A_OK);

	// Hack for CF card surprise removal crash.
	
	if(target->table.host_int_status == 0xff) {
	    target->table.host_int_status = 0;
	    return;
	}
        mailbox_int_status = target->table.host_int_status & 
                             HOST_INT_STATUS_MBOX_DATA_MASK;
    } while (mailbox_int_status);

    target->table.int_status_enable |= HOST_INT_STATUS_MBOX_DATA_MASK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -