?? htc_utils.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 utility routines used across the entire HTC module. */#include "htc_internal.h"/* ------ Global Variable Declarations ------- */extern HTC_TARGET *AtherosTargetList[HIF_MAX_DEVICES];extern HTC_GLOBAL_EVENT_TABLE AtherosEventTable;extern A_MUTEX_T instanceCS;#ifdef DEBUGextern A_UINT32 debughtc;#endif/* ------ Static Variables ------ *//* ------ Functions ------ */voiddispatchEvent(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId, HTC_EVENT_ID eventId, HTC_EVENT_INFO *eventInfo){ EVENT_TABLE_ELEMENT *eventElement; if (eventId == HTC_TARGET_AVAILABLE) { eventElement = &AtherosEventTable.element[0]; } else if (eventId == HTC_TARGET_UNAVAILABLE) { eventElement = &AtherosEventTable.element[1]; } else { eventElement = &target->endPoint[endPointId].eventTable.element[eventId]; } AR_DEBUG_ASSERT(eventElement != NULL); AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("dispatchEvent(endpoint: %d, eventId: 0x%d, handler: 0x%p)\n", endPointId, eventElement->id, eventElement->handler)); if (eventElement->handler) { eventElement->handler(target, endPointId, eventId, eventInfo, eventElement->param); }}A_STATUSaddToEventTable(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId, HTC_EVENT_ID eventId, HTC_EVENT_HANDLER handler, void *param){ EVENT_TABLE_ELEMENT *new; if (eventId == HTC_TARGET_AVAILABLE) { new = &AtherosEventTable.element[0]; } else if (eventId == HTC_TARGET_UNAVAILABLE) { new = &AtherosEventTable.element[1]; } else { new = &target->endPoint[endPointId].eventTable.element[eventId]; } /* Store the event id, the corresponding handler and the param passed */ new->id = eventId; new->handler = handler; new->param = param; AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("addToEventTable(endpoint: %d, eventId: 0x%d, handler: 0x%p)\n", endPointId, new->id, new->handler)); return A_OK;}A_STATUSremoveFromEventTable(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId, HTC_EVENT_ID eventId){ EVENT_TABLE_ELEMENT *remove; if (eventId == HTC_TARGET_AVAILABLE) { remove = &AtherosEventTable.element[0]; } else if (eventId == HTC_TARGET_UNAVAILABLE) { remove = &AtherosEventTable.element[1]; } else { remove = &target->endPoint[endPointId].eventTable.element[eventId]; } /* Remove the event handler */ A_MEMZERO(remove, sizeof(EVENT_TABLE_ELEMENT)); return A_OK;}A_STATUSaddToMboxQueue(HTC_DATA_REQUEST_QUEUE *queue, A_UCHAR *buffer, A_UINT32 bufferLength, A_UINT32 actualLength, void *cookie){ A_STATUS status; HTC_DATA_REQUEST_ELEMENT *element; AR_DEBUG_ASSERT(queue != NULL); AR_DEBUG_ASSERT(bufferLength); AR_DEBUG_PRINTF(ATH_DEBUG_SYNC, ("Critical Section (queue): LOCK at line %d in file %s\n", __LINE__, __FILE__)); A_MUTEX_LOCK(&instanceCS); element = GET_QUEUE_TAIL(queue); if (!(IS_DATA_QUEUE_FULL(queue)) && IS_ELEMENT_FREE(element)) { element->buffer.free = FALSE; FILL_MBOX_BUFFER(element, buffer, bufferLength, actualLength, cookie); queue->size += 1; AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("addToMboxQueue (index: %d, size: %d, bufferElement: 0x%p, bufferElement->buffer: 0x%p, bufferElement->cookie: 0x%p)\n", (queue->head + queue->size - 1) % HTC_DATA_REQUEST_RING_BUFFER_SIZE, queue->size, element, (GET_MBOX_BUFFER(element))->buffer, (GET_MBOX_BUFFER(element))->cookie)); status = A_OK; } else { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Queue size: %d\n", queue->size)); status = A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_SYNC, ("Critical Section (queue): UNLOCK at line %d in file %s\n", __LINE__, __FILE__)); A_MUTEX_UNLOCK(&instanceCS); return status;}HTC_DATA_REQUEST_ELEMENT *removeFromMboxQueue(HTC_DATA_REQUEST_QUEUE *queue) { HTC_DATA_REQUEST_ELEMENT *element; AR_DEBUG_ASSERT(queue != NULL); AR_DEBUG_PRINTF(ATH_DEBUG_SYNC, ("Critical Section (queue): LOCK at line %d in file %s\n", __LINE__, __FILE__)); A_MUTEX_LOCK(&instanceCS); if (!(IS_DATA_QUEUE_EMPTY(queue))) { element = GET_QUEUE_HEAD(queue); queue->head = (queue->head + 1) % HTC_DATA_REQUEST_RING_BUFFER_SIZE; queue->size -= 1; AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("removeFromMboxQueue (index: %d, size: %d, bufferElement: 0x%p, bufferElement->buffer: 0x%p, bufferElement->cookie: 0x%p)\n", queue->head, queue->size, element, (GET_MBOX_BUFFER(element))->buffer, (GET_MBOX_BUFFER(element))->cookie)); } else { element = NULL; } AR_DEBUG_PRINTF(ATH_DEBUG_SYNC, ("Critical Section (queue): UNLOCK at line %d in file %s\n", __LINE__, __FILE__)); A_MUTEX_UNLOCK(&instanceCS); return element;}voidflushMboxQueue(HTC_ENDPOINT *endPoint, HTC_DATA_REQUEST_QUEUE *queue, HTC_EVENT_ID eventId){ HTC_DATA_REQUEST_ELEMENT *curr; HTC_EVENT_INFO eventInfo; HTC_ENDPOINT_EVENT_TABLE *eventTable; HTC_ENDPOINT_ID endPointId; EVENT_TABLE_ELEMENT *eventElement; HTC_MBOX_BUFFER *mboxBuffer; eventTable = &endPoint->eventTable; endPointId = GET_ENDPOINT_ID(endPoint); /* * Release the buffer to WMI using the registered event handler. If WMI * has not registered any callbacks for a particular endpoint then it * means that its queues will not have any buffers so we skip that * endpoint. */ if ((eventElement = &eventTable->element[eventId]) != NULL) { while ((curr = removeFromMboxQueue(queue)) != NULL) { /* Frame the event and dispatch it */ mboxBuffer = GET_MBOX_BUFFER(curr); FRAME_EVENT(eventInfo, mboxBuffer->buffer, mboxBuffer->bufferLength, mboxBuffer->actualLength, A_ECANCELED, mboxBuffer->cookie); if (eventElement->handler) { eventElement->handler(endPoint->target, endPointId, eventId, &eventInfo, eventElement->param); } RECYCLE_DATA_REQUEST_ELEMENT(curr); } } /* Initialize the head and tail pointer */ queue->head = 0; queue->size = 0;}HTC_REG_REQUEST_ELEMENT *allocateRegRequestElement(HTC_TARGET *target) { A_UINT32 count; HTC_REG_REQUEST_ELEMENT *element; A_MUTEX_LOCK(&instanceCS); element = NULL; for (count = 0; count < HTC_REG_REQUEST_LIST_SIZE; count ++) { element = &target->regList.element[count]; if (IS_ELEMENT_FREE(element)) { element->buffer.free = FALSE; break; } } A_MUTEX_UNLOCK(&instanceCS); return element;}voidfreeRegRequestElement(HTC_REG_REQUEST_ELEMENT *element) { A_MUTEX_LOCK(&instanceCS); FILL_REG_BUFFER(element, NULL, 0, 0, 0); element->buffer.free = TRUE; A_MUTEX_UNLOCK(&instanceCS);}HTC_TARGET *getTargetInstance(void *device){ return AtherosTargetList[0];}voidaddTargetInstance(HTC_TARGET *target){ AtherosTargetList[0] = target;}voiddelTargetInstance(HTC_TARGET *target){ AtherosTargetList[0] = NULL;}A_UINT32getRegAddr(TARGET_REGISTERS base, HTC_ENDPOINT_ID endPointId){ A_UINT32 address; switch(base) { case TX_CREDIT_COUNTER_RESET_REG: address = COUNT_DEC_ADDRESS + endPointId * 4; break; case TX_CREDIT_COUNTER_DECREMENT_REG: address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + endPointId) * 4; break; case TX_CREDIT_COUNTER_REG: address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + endPointId) * 4; break; case INT_STATUS_ENABLE_REG: address = INT_STATUS_ENABLE_ADDRESS; break; case COUNTER_INT_STATUS_ENABLE_REG: case COUNTER_INT_STATUS_DISABLE_REG: address = COUNTER_INT_STATUS_ENABLE_ADDRESS; break; case INT_STATUS_REG: address = HOST_INT_STATUS_ADDRESS; break; case CPU_INT_STATUS_REG: address = CPU_INT_STATUS_ADDRESS; break; case ERROR_INT_STATUS_REG: address = ERROR_INT_STATUS_ADDRESS; break; case INT_WLAN_REG: address = INT_WLAN_ADDRESS; break; case WINDOW_DATA_REG: address = WINDOW_DATA_ADDRESS; break; case WINDOW_WRITE_ADDR_REG: address = WINDOW_WRITE_ADDR_ADDRESS; break; case WINDOW_READ_ADDR_REG: address = WINDOW_READ_ADDR_ADDRESS; break; default: AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid register: %d\n", base)); AR_DEBUG_ASSERT(0); address = 0; break; } return address;}voiddumpBytes(A_UCHAR *buffer, A_UINT16 length){ A_CHAR stream[60]; A_UINT32 i; A_UINT16 offset, count; AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("Dumping %d Bytes : ------>\n", length)); count = 0; offset = 0; for(i = 0; i < length; i++) { sprintf(stream + offset, "%2x ", buffer[i]); count ++; offset += 3; if(count == 16) { count = 0; offset = 0; AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("[H]: %s\n", stream)); A_MEMZERO(stream, 60); } } if(offset != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("[H]: %s\n", stream)); }}voiddumpRegisters(HTC_TARGET *target){ HTC_REGISTER_TABLE *reg; reg = &target->table; AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("\n<------- Register Table -------->\nInt Status: 0x%x\nCPU Int Status: 0x%x\nError Int Status: 0x%x\nCounter Int Status: 0x%x\nMbox Frame: 0x%x\nRx Lookahead Valid: 0x%x\nRx Lookahead 0: 0x%x\nRx Lookahead 1: 0x%x\nRx Lookahead 2: 0x%x\nRx Lookahead 3: 0x%x\nInt Status Enable: 0x%x\nCounter Int Status Enable: 0x%x\n<------------------------------->\n", reg->host_int_status, reg->cpu_int_status, reg->error_int_status, reg->counter_int_status, reg->mbox_frame, reg->rx_lookahead_valid, reg->rx_lookahead[ENDPOINT1], reg->rx_lookahead[ENDPOINT2], reg->rx_lookahead[ENDPOINT3], reg->rx_lookahead[ENDPOINT4], reg->int_status_enable, reg->counter_int_status_enable));}A_UINT8htcGetBitNumSet(A_UINT32 data){ A_UINT8 count; count = 0; while(!(data & 0x1)) { count += 1; data >>= 1; } return count;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -