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

📄 htc_recv.c

📁 Linux下SDIO设备的驱动程序
💻 C
字号:
/* * 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 receive path. */#include "htc_internal.h"/* ------ Global Variable Declarations ------- */#ifdef DEBUGextern A_UINT32 debughtc;#endif/* ------ Static Variables ------ *//* ------ Functions ------ *//* Makes a buffer available to the HTC module */A_STATUSHTCBufferReceive(HTC_TARGET *target,                 HTC_ENDPOINT_ID endPointId,                 A_UCHAR *buffer,                 A_UINT32 length,                 void *cookie){    A_STATUS status;    HTC_ENDPOINT *endPoint;    HTC_DATA_REQUEST_QUEUE *recvQueue;    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,                    ("HTCBufferReceive: Enter (endPointId: %d, buffer: 0x%p, length: %d, cookie: 0x%p)\n", endPointId, buffer, length, cookie));    AR_DEBUG_ASSERT((endPointId >= ENDPOINT1) && (endPointId <= ENDPOINT4));    /* Extract the end point instance */    endPoint = &target->endPoint[endPointId];    AR_DEBUG_ASSERT(endPoint != NULL);    recvQueue = &endPoint->recvQueue;    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_RECV, ("recvQueue: %p\n",                    recvQueue));    /* Add this posted buffer to the pending receive queue */    status = addToMboxQueue(recvQueue, buffer, length, 0, cookie);    if (status != A_OK) {        AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_RECV,                        ("Mailbox (%d) Send queue full. Unable to add buffer\n",                        GET_ENDPOINT_ID(endPoint)));        return A_ERROR;    }    /*     * If this API was called as a result of a HTC_DATA_AVAILABLE event to     * the upper layer, indicating that HTC is out of buffers, then we should     * receive the frame in the buffer supplied otherwise we simply add the     * buffer to the Pending Receive Queue     */    if (endPoint->rxLengthPending) {        htcReceiveFrame(endPoint);    }    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,                    ("HTCBufferReceive: Exit\n"));    return A_OK;}voidhtcReceiveFrame(HTC_ENDPOINT *endPoint){    A_STATUS status;    A_UINT32 address;    A_UINT32 paddedLength;    A_UINT32 frameLength;    HIF_REQUEST request;    HTC_ENDPOINT_ID endPointId;    HTC_QUEUE_ELEMENT *element;    HTC_MBOX_BUFFER *mboxBuffer;    HTC_DATA_REQUEST_QUEUE *recvQueue;    HTC_TARGET *target;    HTC_EVENT_INFO eventInfo;    HIF_DATAMODE dmode;    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,                    ("htcReceiveFrame - Enter\n"));    /* Get the context */    AR_DEBUG_ASSERT(endPoint != NULL);    endPointId = GET_ENDPOINT_ID(endPoint);    target = endPoint->target;    AR_DEBUG_ASSERT(target != NULL);    recvQueue = &endPoint->recvQueue;    AR_DEBUG_ASSERT(recvQueue != NULL);    /*     * Receive the frame if we have any pending frames and a buffer to     * receive it into.     */     if (IS_DATA_QUEUE_EMPTY(recvQueue)) {         AR_DEBUG_PRINTF(ATH_DEBUG_WARN | ATH_DEBUG_RECV,                         ("Mailbox (%d) recv queue empty. Unable to remove buffer\n", endPointId));         /*          * Communicate this situation to the host via the HTC_DATA_AVAILABLE          * event to request some buffers in the queue.          */         endPoint->rxLengthPending = htcGetFrameLength(endPoint);         AR_DEBUG_ASSERT(endPoint->rxLengthPending);         FRAME_EVENT(eventInfo, NULL, endPoint->rxLengthPending,                     0, A_OK, NULL);         dispatchEvent(target, endPointId, HTC_DATA_AVAILABLE, &eventInfo);         return;     }     /*      * Get the length from the lookahead register if there is nothing      * pending.      */     if (endPoint->rxLengthPending) {         frameLength = endPoint->rxLengthPending;         endPoint->rxLengthPending = 0;     } else {         frameLength = htcGetFrameLength(endPoint);     }     AR_DEBUG_ASSERT((frameLength > 0) &&                     (frameLength <= HTC_MESSAGE_SIZE_MAX));     AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_RECV, ("Frame Length: %d\n",                     frameLength));     /* Adjust the length to be a multiple of block size if appropriate */     paddedLength = (frameLength + (endPoint->blockSize - 1)) &                    (~(endPoint->blockSize - 1));     /*      * Receive the frame(s). Pull an empty buffer from the head of the      * Pending Receive Queue.      */     element = removeFromMboxQueue(recvQueue);     mboxBuffer = GET_MBOX_BUFFER(element);     mboxBuffer->actualLength = paddedLength;     dmode = (endPoint->blockSize > 1) ? HIF_BLOCK_BASIS : HIF_BYTE_BASIS;     HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO,                       HIF_ASYNCHRONOUS, dmode, HIF_INCREMENTAL_ADDRESS);     address = endPoint->address;     status = HIFReadWrite(target->device, address, mboxBuffer->buffer,                           mboxBuffer->actualLength, &request, element);#ifndef HTC_SYNC     if (status != A_OK) {#else     if (status != A_OK && status != A_PENDING) {#endif         AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_RECV,                         ("Frame reception failed\n"));         if (!IS_ELEMENT_FREE(element)) {             mboxBuffer->actualLength = 0;             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,                             ("htcReceiveFrame - Exit\n"));             return;         }     }#ifdef HTC_SYNC	else if (status == A_OK) {		element->completionCB(element, status);	}#endif    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,                    ("htcReceiveFrame - Exit\n"));}A_UINT32htcGetFrameLength(HTC_ENDPOINT *endPoint){    HTC_TARGET *target;    A_UINT32 frameLength;    HTC_ENDPOINT_ID endPointId;    /* Get the context */    AR_DEBUG_ASSERT(endPoint != NULL);    target = endPoint->target;    AR_DEBUG_ASSERT(target != NULL);    endPointId = GET_ENDPOINT_ID(endPoint);    AR_DEBUG_ASSERT(target->table.rx_lookahead_valid & (1 << endPointId));    /* The length is contained in the first two bytes - HTC_HEADER_LEN */    frameLength = (target->table.rx_lookahead[endPointId] & 0xFFFF) +                  HTC_HEADER_LEN;    AR_DEBUG_ASSERT(frameLength);    return frameLength;}

⌨️ 快捷键说明

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