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

📄 htc_events.c

📁 Linux下SDIO设备的驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 2004-2006 Atheros Communications Inc. * *  Wireless Network driver for Atheros AR6001 * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License version 2 as *  published by the Free Software Foundation; * *  Software distributed under the License is distributed on an "AS *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or *  implied. See the License for the specific language governing *  rights and limitations under the License. * * * This file contains the routines handling the different events and callbacks * from the hardware interface layer. */#include "htc_internal.h"/* ------ Global Variable Declarations ------- */extern A_MUTEX_T instanceCS, counterCS, creditCS;extern A_WAITQUEUE_HEAD htcEvent;#ifdef DEBUGextern A_UINT32 debughtc;extern A_UINT32 txcreditsavailable[HTC_MAILBOX_NUM_MAX];extern A_UINT32 txcreditsconsumed[HTC_MAILBOX_NUM_MAX];extern A_UINT32 txcreditintrenable[HTC_MAILBOX_NUM_MAX];extern A_UINT32 txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX];#endifextern A_UINT32 tx_complete[HTC_MAILBOX_NUM_MAX]; /* Num of tx complete *//* ------ Static Variables ------ *//* ------ Functions ------ */#ifdef CFA_STATUS htcInterruptEnabler(HIF_DEVICE *device) {    A_STATUS status;    A_UINT32 address;    HIF_REQUEST request;    HTC_TARGET *target;    target = getTargetInstance(device);    AR_DEBUG_ASSERT(target != NULL);    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,                    ("htcInterruptEnabler Enter target: 0x%p\n", target));    target->table.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) |                                      INT_STATUS_ENABLE_CPU_SET(0x01) |                                      INT_STATUS_ENABLE_COUNTER_SET(0x01) |                                      INT_STATUS_ENABLE_MBOX_DATA_SET(0x0F);    /* Reenable Dragon Interrupts */    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);    address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);    status = HIFReadWrite(target->device, address,                          &target->table.int_status_enable, 1,                          &request, NULL);	AR_DEBUG_ASSERT(status == A_OK);    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("htcInterruptEnabler Exit\n"));        return A_OK;}#endif /* CF */A_STATUShtcRWCompletionHandler(void *context,                       A_STATUS status){    HTC_QUEUE_ELEMENT *element;    element = (HTC_QUEUE_ELEMENT *)context;    AR_DEBUG_ASSERT(element != NULL);    return(element->completionCB(element, status));}A_STATUShtcTxCompletionCB(HTC_DATA_REQUEST_ELEMENT *element,                  A_STATUS status){    HTC_TARGET *target;    HTC_ENDPOINT_ID endPointId;    HTC_ENDPOINT *endPoint;    HTC_EVENT_INFO eventInfo;    HTC_MBOX_BUFFER *mboxBuffer;    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND,                    ("htcTxCompletionCB - Enter\n"));    /* Get the context */    mboxBuffer = GET_MBOX_BUFFER(element);    AR_DEBUG_ASSERT(mboxBuffer != NULL);    endPoint = mboxBuffer->endPoint;    AR_DEBUG_ASSERT(endPoint != NULL);    target = endPoint->target;    AR_DEBUG_ASSERT(target != NULL);    endPointId = GET_ENDPOINT_ID(endPoint);    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_SEND,                    ("mboxBuffer: 0x%p, buffer: 0x%p, endPoint(%d): 0x%p, target: 0x%p\n", mboxBuffer, mboxBuffer->buffer, endPointId, endPoint, target));    /* Return the buffer to the user if the transmission was not successful */    if (status != A_OK) {        AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_SEND,                        ("Frame transmission failed\n"));        AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_SEND,                        ("EndPoint: %d, Tx credits available: %d\n",                         endPointId, GET_TX_CREDITS_AVAILABLE(endPoint)));        /*         * In the failure case it is possible that while queueing of the         * request itself it returned an error status in which case we         * would have dispatched an event and freed the element there         * itself. Ideally if it failed to queue the request then it         * should not generate a callback but we are being a little         * conservative.         */        if (!(IS_ELEMENT_FREE(element))) {            mboxBuffer->buffer += HTC_HEADER_LEN;            FRAME_EVENT(eventInfo, mboxBuffer->buffer,                        mboxBuffer->bufferLength, mboxBuffer->actualLength,                        A_ECANCELED, mboxBuffer->cookie);            RECYCLE_DATA_REQUEST_ELEMENT(element);            dispatchEvent(target, endPointId, HTC_BUFFER_SENT, &eventInfo);            AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND,                            ("htcTxCompletionCB - Exit\n"));        }        return A_OK;    }    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_SEND,                    ("Frame transmission complete\n"));    /*     * The user should see the actual length and buffer length     * to be the same. In case of block mode, we use the actual length     * parameter to reflect the total number of bytes transmitted after     * padding.     */    mboxBuffer->actualLength = mboxBuffer->bufferLength;    mboxBuffer->buffer += HTC_HEADER_LEN;    /*     * Return the transmit buffer to the user through the HTC_BUFFER_SENT     * event indicating that the frame was transmitted successfully.     */    FRAME_EVENT(eventInfo, mboxBuffer->buffer, mboxBuffer->bufferLength,                mboxBuffer->actualLength, A_OK, mboxBuffer->cookie);    RECYCLE_DATA_REQUEST_ELEMENT(element);    tx_complete[endPointId] += 1;    dispatchEvent(target, endPointId, HTC_BUFFER_SENT, &eventInfo);    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND,                    ("htcTxCompletionCB - Exit\n"));    return A_OK;}A_STATUShtcBlkSzNegCompletionCB(HTC_DATA_REQUEST_ELEMENT *element,                        A_STATUS status){    HTC_TARGET *target;    HTC_ENDPOINT *endPoint;    HIF_REQUEST request;    HTC_MBOX_BUFFER *mboxBuffer;    HTC_REG_REQUEST_ELEMENT *regElement;    A_UINT32 address;    /* Get the context */    mboxBuffer = GET_MBOX_BUFFER(element);    AR_DEBUG_ASSERT(mboxBuffer != NULL);    endPoint = mboxBuffer->endPoint;    AR_DEBUG_ASSERT(endPoint != NULL);    target = endPoint->target;    AR_DEBUG_ASSERT(target != NULL);    /* Recycle the request element */    RECYCLE_DATA_REQUEST_ELEMENT(element);    element->completionCB = htcTxCompletionCB;    if (status == A_OK) {        /* Mark the state to be ready */        endPoint->enabled = TRUE;        /* Set the state of the target as ready */        if (target->endPoint[ENDPOINT1].enabled &&            target->endPoint[ENDPOINT2].enabled &&            target->endPoint[ENDPOINT3].enabled &&            target->endPoint[ENDPOINT4].enabled )        {            /* Send the INT_WLAN interrupt to the target */            target->table.int_wlan = 1;            HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO,                              HIF_ASYNCHRONOUS, HIF_BYTE_BASIS,                              HIF_FIXED_ADDRESS);            address = getRegAddr(INT_WLAN_REG, ENDPOINT_UNUSED);            regElement = allocateRegRequestElement(target);            AR_DEBUG_ASSERT(regElement != NULL);            FILL_REG_BUFFER(regElement, &target->table.int_wlan, 1,                            INT_WLAN_REG, ENDPOINT_UNUSED);            status = HIFReadWrite(target->device, address,                                  &target->table.int_wlan,                                  1, &request, regElement);#ifndef HTC_SYNC            AR_DEBUG_ASSERT(status == A_OK);#else			AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);			if(status == A_OK) {				regElement->completionCB(regElement, status);			}#endif        }    }    return A_OK;}A_STATUShtcRxCompletionCB(HTC_DATA_REQUEST_ELEMENT *element,                  A_STATUS status){    HTC_TARGET *target;    HTC_ENDPOINT *endPoint;    HTC_EVENT_INFO eventInfo;    HTC_ENDPOINT_ID endPointId;    HTC_MBOX_BUFFER *mboxBuffer;    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND,                    ("htcRxCompletionCB - Enter\n"));    /* Get the context */    mboxBuffer = GET_MBOX_BUFFER(element);    AR_DEBUG_ASSERT(mboxBuffer != NULL);    endPoint = mboxBuffer->endPoint;    AR_DEBUG_ASSERT(endPoint != NULL);    target = endPoint->target;    AR_DEBUG_ASSERT(target != NULL);    endPointId = GET_ENDPOINT_ID(endPoint);    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_RECV,                    ("mboxBuffer: 0x%p, buffer: 0x%p, endPoint(%d): 0x%p, target: 0x%p\n", mboxBuffer, mboxBuffer->buffer, endPointId, endPoint, target));    /* Return the buffer to the user if the reception was not successful */    if (status != A_OK) {        AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_RECV,                        ("Frame reception failed\n"));        /*         * In the failure case it is possible that while queueing of the         * request itself it returned an error status in which case we         * would have dispatched an event and freed the element there         * itself. Ideally if it failed to queue the request then it         * should not generate a callback but we are being a little         * conservative.         */        if (!(IS_ELEMENT_FREE(element))) {            mboxBuffer->actualLength = 0;            mboxBuffer->buffer += HTC_HEADER_LEN;            FRAME_EVENT(eventInfo, mboxBuffer->buffer,                        mboxBuffer->bufferLength, mboxBuffer->actualLength,                        A_ECANCELED, mboxBuffer->cookie);            RECYCLE_DATA_REQUEST_ELEMENT(element);            dispatchEvent(target, endPointId, HTC_BUFFER_RECEIVED, &eventInfo);            AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,                            ("htcRxCompletionCB - Exit\n"));        }        return A_OK;    }    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_RECV,                    ("Frame reception complete\n"));    AR_DEBUG_PRINTBUF(mboxBuffer->buffer, mboxBuffer->actualLength);    /*     * Advance the pointer by the size of HTC header and pass the payload     * pointer to the upper layer.     */    mboxBuffer->actualLength = ((mboxBuffer->buffer[0] << 0) |                                (mboxBuffer->buffer[1] << 8));    mboxBuffer->buffer += HTC_HEADER_LEN;    /*     * Frame the HTC_BUFFER_RECEIVED to the upper layer indicating that the     * packet has been succesfully received.     */    FRAME_EVENT(eventInfo, mboxBuffer->buffer, mboxBuffer->bufferLength,                mboxBuffer->actualLength, A_OK, mboxBuffer->cookie);    /* Recycle the bufferElement structure */    RECYCLE_DATA_REQUEST_ELEMENT(element);    /* Dispatch the event */    dispatchEvent(target, endPointId, HTC_BUFFER_RECEIVED, &eventInfo);    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,                    ("htcRxCompletion - Exit\n"));    return A_OK;}A_STATUShtcRegCompletionCB(HTC_REG_REQUEST_ELEMENT *element,                   A_STATUS status){    A_STATUS ret;    HTC_TARGET *target;    HTC_ENDPOINT *endPoint;    HTC_REG_BUFFER *regBuffer;    A_UINT8 txCreditsConsumed;    A_UINT8 txCreditsAvailable;    HTC_ENDPOINT_ID endPointId;    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV | ATH_DEBUG_SEND,                    ("htcRegCompletion - Enter\n"));    AR_DEBUG_ASSERT(status == A_OK);    /* Get the context */    AR_DEBUG_ASSERT(element != NULL);    regBuffer = GET_REG_BUFFER(element);    AR_DEBUG_ASSERT(regBuffer != NULL);    target = regBuffer->target;    AR_DEBUG_ASSERT(target != NULL);    /* Identify the register and the operation responsible for the callback */    ret = A_OK;    switch(regBuffer->base) {    case TX_CREDIT_COUNTER_DECREMENT_REG:        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("TX_CREDIT_COUNTER_DECREMENT_REG\n"));        endPointId = regBuffer->offset;        endPoint = &target->endPoint[endPointId];        AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,                        ("Critical Section (credit): LOCK at line %d in file %s\n", __LINE__, __FILE__));        A_MUTEX_LOCK(&creditCS);        /* Calculate the number of credits available */        AR_DEBUG_ASSERT(GET_TX_CREDITS_CONSUMED(endPoint) == regBuffer->length);        AR_DEBUG_ASSERT(regBuffer->buffer[0] >=                        GET_TX_CREDITS_CONSUMED(endPoint));        SET_TX_CREDITS_AVAILABLE(endPoint, regBuffer->buffer[0] -                                 GET_TX_CREDITS_CONSUMED(endPoint));        SET_TX_CREDITS_CONSUMED(endPoint, 0);

⌨️ 快捷键说明

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