?? htc.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 HTC APIs that are exposed to higher layers. */#include "htc_internal.h"/* ------ Global Variable Declarations ------- */HTC_TARGET *AtherosTargetList[HIF_MAX_DEVICES];HTC_GLOBAL_EVENT_TABLE AtherosEventTable;A_MUTEX_T creditCS, counterCS, instanceCS;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 int tx_attempt[HTC_MAILBOX_NUM_MAX]; /* Num of attempts to add */extern int tx_post[HTC_MAILBOX_NUM_MAX]; /* Num of attemps succeded */extern int tx_complete[HTC_MAILBOX_NUM_MAX]; /* Num of tx complete *//* Initializes the HTC module */A_STATUSHTCInit(void){ HTC_CALLBACKS htcCallbacks; static A_BOOL HTCInitialized = FALSE; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Enter\n")); if (HTCInitialized) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Exit\n")); return A_OK; } A_MEMZERO(&AtherosEventTable, sizeof(HTC_GLOBAL_EVENT_TABLE)); A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS)); A_INIT_WAITQUEUE_HEAD(&htcEvent); htcCallbacks.deviceInsertedHandler = htcTargetInsertedHandler; htcCallbacks.deviceRemovedHandler = htcTargetRemovedHandler; htcCallbacks.rwCompletionHandler = htcRWCompletionHandler;#ifdef CF htcCallbacks.deviceInterruptEnabler = htcInterruptEnabler; htcCallbacks.deviceInterruptDisabler = htcInterruptDisabler;#endif /* CF */ htcCallbacks.dsrHandler = htcDSRHandler; HIFRegisterCallbacks(&htcCallbacks); HTCInitialized = TRUE; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Exit\n")); return A_OK;}/* Enables Dragon interrupts */A_STATUSHTCStart(HTC_TARGET *target){ A_STATUS status; A_UINT32 address; HIF_REQUEST request; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n")); /* Unmask the host controller interrupts */ HIFUnMaskInterrupt(target->device); /* Enable all the interrupts except for the dragon interrupt */ 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); /* Set up the CPU Interrupt Status Register */ target->table.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00); /* Set up the Error Interrupt Status Register */ target->table.error_status_enable = ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) | ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01); /* Set up the Counter Interrupt Status Register */ target->table.counter_int_status_enable = COUNTER_INT_STATUS_ENABLE_BIT_SET(0xFF); /* Write to the register */ HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS); address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED); status = HIFReadWrite(target->device, address, &target->table.int_status_enable, 4, &request, NULL); if (status != A_OK) { /* Can't write it for some reason */ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to enable INT_STATUS_ENABLE | CPU_INT_STATUS_ENABLE | ERROR_STATUS_ENABLE | COUNTER_INT_STATUS_ENABLE, err: %d\n", status)); HTCStop(target); return status; }#ifdef DEBUG txcreditintrenable[ENDPOINT1] += 1; txcreditintrenable[ENDPOINT2] += 1; txcreditintrenable[ENDPOINT3] += 1; txcreditintrenable[ENDPOINT4] += 1; txcreditintrenableaggregate[ENDPOINT1] += 1; txcreditintrenableaggregate[ENDPOINT2] += 1; txcreditintrenableaggregate[ENDPOINT3] += 1; txcreditintrenableaggregate[ENDPOINT4] += 1;#endif /* DEBUG */ /* Wait on a timed semaphore that will get signalled once the block size negotiation with the target has completed. Furthermore, we have to do it only once during the lifetime of the target detection */ if (!target->ready) { AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Waiting for the block size negotiation to finish\n")); A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(htcEvent, (target->ready == TRUE), HTC_TARGET_RESPONSE_TIMEOUT); if (target->ready) { status = A_OK; } else { status = A_ERROR; AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to negotiate the block sizes\n")); HTCStop(target); } } AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n")); return status;}/* * Provides an interface for the higher layer module to register for * different events supported by the HTC module */A_STATUSHTCEventReg(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId, HTC_EVENT_ID eventId, HTC_EVENT_HANDLER eventHandler, void *param){ /* * Add the event handler against the specified event and store it in * the event table */ A_STATUS status; HTC_ENDPOINT *endPoint; HTC_EVENT_INFO eventInfo; HTC_DATA_REQUEST_QUEUE *sendQueue, *recvQueue; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCEventReg: Enter (eventId: 0x%x, endPointId: %d)\n", eventId, endPointId)); if (eventHandler) { if ((status = addToEventTable(target, endPointId, eventId, eventHandler, param)) != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Could not add the event 0x%x to the event table\n", eventId)); return status; } } switch(eventId) { case HTC_TARGET_AVAILABLE: if (eventHandler != NULL) { /* * Dispatch a Target Available event for all the targets * present. Iterate through the global list of targets but * currently we shall simply look for the first instance */ target = AtherosTargetList[0]; if (target != NULL) { FRAME_EVENT(eventInfo, (A_UCHAR *)target->device, sizeof(HIF_DEVICE *), sizeof(HIF_DEVICE *), A_OK, NULL); dispatchEvent(target, ENDPOINT_UNUSED, eventId, &eventInfo); } } else { /* Initiate a shut down procedure */ } break; case HTC_TARGET_UNAVAILABLE: break; case HTC_BUFFER_RECEIVED: if (eventHandler == NULL) { /* Flush the queue before unregistering the event handler */ endPoint = &target->endPoint[endPointId]; recvQueue = &endPoint->recvQueue; flushMboxQueue(endPoint, recvQueue, HTC_BUFFER_RECEIVED); } break; case HTC_SKB_RECEIVED: AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("skb not handled currently\n")); break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -