diff options
Diffstat (limited to 'target/linux/s3c24xx/files-2.6.31/drivers/ar6000/htc/htc_send.c')
-rw-r--r-- | target/linux/s3c24xx/files-2.6.31/drivers/ar6000/htc/htc_send.c | 538 |
1 files changed, 0 insertions, 538 deletions
diff --git a/target/linux/s3c24xx/files-2.6.31/drivers/ar6000/htc/htc_send.c b/target/linux/s3c24xx/files-2.6.31/drivers/ar6000/htc/htc_send.c deleted file mode 100644 index cf0dabef47..0000000000 --- a/target/linux/s3c24xx/files-2.6.31/drivers/ar6000/htc/htc_send.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * - * Copyright (c) 2007 Atheros Communications Inc. - * All rights reserved. - * - * - * 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. - * - * - * - */ - -#include "htc_internal.h" - -#define DO_EP_TX_COMPLETION(ep,p) \ -{ \ - (p)->Completion = NULL; \ - (ep)->EpCallBacks.EpTxComplete((ep)->EpCallBacks.pContext,(p)); \ -} - - -/* call the distribute credits callback with the distribution */ -#define DO_DISTRIBUTION(t,reason,description,pList) \ -{ \ - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, \ - (" calling distribute function (%s) (dfn:0x%X, ctxt:0x%X, dist:0x%X) \n", \ - (description), \ - (A_UINT32)(t)->DistributeCredits, \ - (A_UINT32)(t)->pCredDistContext, \ - (A_UINT32)pList)); \ - (t)->DistributeCredits((t)->pCredDistContext, \ - (pList), \ - (reason)); \ -} - -/* our internal send packet completion handler when packets are submited to the AR6K device - * layer */ -static void HTCSendPktCompletionHandler(void *Context, HTC_PACKET *pPacket) -{ - HTC_TARGET *target = (HTC_TARGET *)Context; - HTC_ENDPOINT *pEndpoint = &target->EndPoint[pPacket->Endpoint]; - - - if (A_FAILED(pPacket->Status)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("HTCSendPktCompletionHandler: request failed (status:%d, ep:%d) \n", - pPacket->Status, pPacket->Endpoint)); - } - /* first, fixup the head room we allocated */ - pPacket->pBuffer += HTC_HDR_LENGTH; - /* do completion */ - DO_EP_TX_COMPLETION(pEndpoint,pPacket); -} - -A_STATUS HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket, A_UINT8 SendFlags) -{ - A_STATUS status; - A_UINT8 *pHdrBuf; - A_BOOL sync = FALSE; - - /* caller always provides headrooom */ - pPacket->pBuffer -= HTC_HDR_LENGTH; - pHdrBuf = pPacket->pBuffer; - /* setup frame header */ - A_SET_UINT16_FIELD(pHdrBuf,HTC_FRAME_HDR,PayloadLen,(A_UINT16)pPacket->ActualLength); - A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,Flags,SendFlags); - A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,EndpointID, (A_UINT8)pPacket->Endpoint); - - if (pPacket->Completion == NULL) { - /* mark that this request was synchronously issued */ - sync = TRUE; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, - ("+-HTCIssueSend: transmit length : %d (%s) \n", - pPacket->ActualLength + HTC_HDR_LENGTH, - sync ? "SYNC" : "ASYNC" )); - - /* send message to device */ - status = DevSendPacket(&target->Device, - pPacket, - pPacket->ActualLength + HTC_HDR_LENGTH); - - if (sync) { - /* use local sync variable. If this was issued asynchronously, pPacket is no longer - * safe to access. */ - pPacket->pBuffer += HTC_HDR_LENGTH; - } - - /* if this request was asynchronous, the packet completion routine will be invoked by - * the device layer when the HIF layer completes the request */ - - return status; -} - -/* try to send the current packet or a packet at the head of the TX queue, - * if there are no credits, the packet remains in the queue. */ -static void HTCTrySend(HTC_TARGET *target, - HTC_PACKET *pPacketToSend, - HTC_ENDPOINT_ID ep) -{ - HTC_PACKET *pPacket; - HTC_ENDPOINT *pEndpoint; - int creditsRequired; - A_UINT8 sendFlags; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCTrySend (pPkt:0x%X)\n",(A_UINT32)pPacketToSend)); - - pEndpoint = &target->EndPoint[ep]; - - LOCK_HTC_TX(target); - - if (pPacketToSend != NULL) { - /* caller supplied us a packet to queue to the tail of the HTC TX queue before - * we check the tx queue */ - HTC_PACKET_ENQUEUE(&pEndpoint->TxQueue,pPacketToSend); - pEndpoint->CurrentTxQueueDepth++; - } - - /* now drain the TX queue for transmission as long as we have enough - * credits */ - - while (1) { - - if (HTC_QUEUE_EMPTY(&pEndpoint->TxQueue)) { - /* nothing in the queue */ - break; - } - - sendFlags = 0; - - /* get packet at head, but don't remove it */ - pPacket = HTC_GET_PKT_AT_HEAD(&pEndpoint->TxQueue); - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Got head packet:0x%X , Queue Depth: %d\n", - (A_UINT32)pPacket, pEndpoint->CurrentTxQueueDepth)); - - /* figure out how many credits this message requires */ - creditsRequired = pPacket->ActualLength + HTC_HDR_LENGTH; - creditsRequired += target->TargetCreditSize - 1; - creditsRequired /= target->TargetCreditSize; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Creds Required:%d Got:%d\n", - creditsRequired, pEndpoint->CreditDist.TxCredits)); - - if (pEndpoint->CreditDist.TxCredits < creditsRequired) { - - /* not enough credits */ - - if (pPacket->Endpoint == ENDPOINT_0) { - /* leave it in the queue */ - break; - } - /* invoke the registered distribution function only if this is not - * endpoint 0, we let the driver layer provide more credits if it can. - * We pass the credit distribution list starting at the endpoint in question - * */ - - /* set how many credits we need */ - pEndpoint->CreditDist.TxCreditsSeek = - creditsRequired - pEndpoint->CreditDist.TxCredits; - DO_DISTRIBUTION(target, - HTC_CREDIT_DIST_SEEK_CREDITS, - "Seek Credits", - &pEndpoint->CreditDist); - - pEndpoint->CreditDist.TxCreditsSeek = 0; - - if (pEndpoint->CreditDist.TxCredits < creditsRequired) { - /* still not enough credits to send, leave packet in the queue */ - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, - (" Not enough credits for ep %d leaving packet in queue..\n", - pPacket->Endpoint)); - break; - } - - } - - pEndpoint->CreditDist.TxCredits -= creditsRequired; - INC_HTC_EP_STAT(pEndpoint, TxCreditsConsummed, creditsRequired); - - /* check if we need credits */ - if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) { - sendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE; - INC_HTC_EP_STAT(pEndpoint, TxCreditLowIndications, 1); - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Host Needs Credits \n")); - } - - /* now we can fully dequeue */ - pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxQueue); - pEndpoint->CurrentTxQueueDepth--; - - INC_HTC_EP_STAT(pEndpoint, TxIssued, 1); - - UNLOCK_HTC_TX(target); - - HTCIssueSend(target, pPacket, sendFlags); - - LOCK_HTC_TX(target); - - /* go back and check for more messages */ - } - - if (pEndpoint->CurrentTxQueueDepth >= pEndpoint->MaxTxQueueDepth) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d, TX queue is full, Depth:%d, Max:%d \n", - ep, pEndpoint->CurrentTxQueueDepth, pEndpoint->MaxTxQueueDepth)); - UNLOCK_HTC_TX(target); - /* queue is now full, let caller know */ - if (pEndpoint->EpCallBacks.EpSendFull != NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Calling driver's send full callback.... \n")); - pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext, ep); - } - } else { - UNLOCK_HTC_TX(target); - /* queue is now available for new packet, let caller know */ - if (pEndpoint->EpCallBacks.EpSendAvail) - pEndpoint->EpCallBacks.EpSendAvail(pEndpoint->EpCallBacks.pContext, ep); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n")); -} - -/* HTC API - HTCSendPkt */ -A_STATUS HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) -{ - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - HTC_ENDPOINT *pEndpoint; - HTC_ENDPOINT_ID ep; - A_STATUS status = A_OK; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, - ("+HTCSendPkt: Enter endPointId: %d, buffer: 0x%X, length: %d \n", - pPacket->Endpoint, (A_UINT32)pPacket->pBuffer, pPacket->ActualLength)); - - ep = pPacket->Endpoint; - AR_DEBUG_ASSERT(ep < ENDPOINT_MAX); - pEndpoint = &target->EndPoint[ep]; - - do { - - if (HTC_STOPPING(target)) { - status = A_ECANCELED; - pPacket->Status = status; - DO_EP_TX_COMPLETION(pEndpoint,pPacket); - break; - } - /* everything sent through this interface is asynchronous */ - /* fill in HTC completion routines */ - pPacket->Completion = HTCSendPktCompletionHandler; - pPacket->pContext = target; - - HTCTrySend(target, pPacket, ep); - - } while (FALSE); - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPkt \n")); - - return status; -} - - -/* check TX queues to drain because of credit distribution update */ -static INLINE void HTCCheckEndpointTxQueues(HTC_TARGET *target) -{ - HTC_ENDPOINT *pEndpoint; - HTC_ENDPOINT_CREDIT_DIST *pDistItem; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCCheckEndpointTxQueues \n")); - pDistItem = target->EpCreditDistributionListHead; - - /* run through the credit distribution list to see - * if there are packets queued - * NOTE: no locks need to be taken since the distribution list - * is not dynamic (cannot be re-ordered) and we are not modifying any state */ - while (pDistItem != NULL) { - pEndpoint = (HTC_ENDPOINT *)pDistItem->pHTCReserved; - - if (pEndpoint->CurrentTxQueueDepth > 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Ep %d has %d credits and %d Packets in TX Queue \n", - pDistItem->Endpoint, pEndpoint->CreditDist.TxCredits, pEndpoint->CurrentTxQueueDepth)); - /* try to start the stalled queue, this list is ordered by priority. - * Highest priority queue get's processed first, if there are credits available the - * highest priority queue will get a chance to reclaim credits from lower priority - * ones */ - HTCTrySend(target, NULL, pDistItem->Endpoint); - } - - pDistItem = pDistItem->pNext; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCCheckEndpointTxQueues \n")); -} - -/* process credit reports and call distribution function */ -void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint) -{ - int i; - HTC_ENDPOINT *pEndpoint; - int totalCredits = 0; - A_BOOL doDist = FALSE; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCProcessCreditRpt, Credit Report Entries:%d \n", NumEntries)); - - /* lock out TX while we update credits */ - LOCK_HTC_TX(target); - - for (i = 0; i < NumEntries; i++, pRpt++) { - if (pRpt->EndpointID >= ENDPOINT_MAX) { - AR_DEBUG_ASSERT(FALSE); - break; - } - - pEndpoint = &target->EndPoint[pRpt->EndpointID]; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d got %d credits \n", - pRpt->EndpointID, pRpt->Credits)); - - -#ifdef HTC_EP_STAT_PROFILING - - INC_HTC_EP_STAT(pEndpoint, TxCreditRpts, 1); - INC_HTC_EP_STAT(pEndpoint, TxCreditsReturned, pRpt->Credits); - - if (FromEndpoint == pRpt->EndpointID) { - /* this credit report arrived on the same endpoint indicating it arrived in an RX - * packet */ - INC_HTC_EP_STAT(pEndpoint, TxCreditsFromRx, pRpt->Credits); - INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromRx, 1); - } else if (FromEndpoint == ENDPOINT_0) { - /* this credit arrived on endpoint 0 as a NULL message */ - INC_HTC_EP_STAT(pEndpoint, TxCreditsFromEp0, pRpt->Credits); - INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromEp0, 1); - } else { - /* arrived on another endpoint */ - INC_HTC_EP_STAT(pEndpoint, TxCreditsFromOther, pRpt->Credits); - INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromOther, 1); - } - -#endif - - if (ENDPOINT_0 == pRpt->EndpointID) { - /* always give endpoint 0 credits back */ - pEndpoint->CreditDist.TxCredits += pRpt->Credits; - } else { - /* for all other endpoints, update credits to distribute, the distribution function - * will handle giving out credits back to the endpoints */ - pEndpoint->CreditDist.TxCreditsToDist += pRpt->Credits; - /* flag that we have to do the distribution */ - doDist = TRUE; - } - - totalCredits += pRpt->Credits; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Report indicated %d credits to distribute \n", totalCredits)); - - if (doDist) { - /* this was a credit return based on a completed send operations - * note, this is done with the lock held */ - DO_DISTRIBUTION(target, - HTC_CREDIT_DIST_SEND_COMPLETE, - "Send Complete", - target->EpCreditDistributionListHead->pNext); - } - - UNLOCK_HTC_TX(target); - - if (totalCredits) { - HTCCheckEndpointTxQueues(target); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCProcessCreditRpt \n")); -} - -/* flush endpoint TX queue */ -static void HTCFlushEndpointTX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_TX_TAG Tag) -{ - HTC_PACKET *pPacket; - HTC_PACKET_QUEUE discardQueue; - - /* initialize the discard queue */ - INIT_HTC_PACKET_QUEUE(&discardQueue); - - LOCK_HTC_TX(target); - - /* interate from the front of the TX queue and flush out packets */ - ITERATE_OVER_LIST_ALLOW_REMOVE(&pEndpoint->TxQueue, pPacket, HTC_PACKET, ListLink) { - - /* check for removal */ - if ((HTC_TX_PACKET_TAG_ALL == Tag) || (Tag == pPacket->PktInfo.AsTx.Tag)) { - /* remove from queue */ - HTC_PACKET_REMOVE(pPacket); - /* add it to the discard pile */ - HTC_PACKET_ENQUEUE(&discardQueue, pPacket); - pEndpoint->CurrentTxQueueDepth--; - } - - } ITERATE_END; - - UNLOCK_HTC_TX(target); - - /* empty the discard queue */ - while (1) { - pPacket = HTC_PACKET_DEQUEUE(&discardQueue); - if (NULL == pPacket) { - break; - } - pPacket->Status = A_ECANCELED; - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" Flushing TX packet:0x%X, length:%d, ep:%d tag:0x%X \n", - (A_UINT32)pPacket, pPacket->ActualLength, pPacket->Endpoint, pPacket->PktInfo.AsTx.Tag)); - DO_EP_TX_COMPLETION(pEndpoint,pPacket); - } - -} - -void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist) -{ -#ifdef DEBUG - HTC_ENDPOINT *pEndpoint = (HTC_ENDPOINT *)pEPDist->pHTCReserved; -#endif - - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("--- EP : %d ServiceID: 0x%X --------------\n", - pEPDist->Endpoint, pEPDist->ServiceID)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" this:0x%X next:0x%X prev:0x%X\n", - (A_UINT32)pEPDist, (A_UINT32)pEPDist->pNext, (A_UINT32)pEPDist->pPrev)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" DistFlags : 0x%X \n", pEPDist->DistFlags)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsNorm : %d \n", pEPDist->TxCreditsNorm)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsMin : %d \n", pEPDist->TxCreditsMin)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCredits : %d \n", pEPDist->TxCredits)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsAssigned : %d \n", pEPDist->TxCreditsAssigned)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsSeek : %d \n", pEPDist->TxCreditsSeek)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditSize : %d \n", pEPDist->TxCreditSize)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsPerMaxMsg : %d \n", pEPDist->TxCreditsPerMaxMsg)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsToDist : %d \n", pEPDist->TxCreditsToDist)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxQueueDepth : %d \n", pEndpoint->CurrentTxQueueDepth)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("----------------------------------------------------\n")); -} - -void DumpCreditDistStates(HTC_TARGET *target) -{ - HTC_ENDPOINT_CREDIT_DIST *pEPList = target->EpCreditDistributionListHead; - - while (pEPList != NULL) { - DumpCreditDist(pEPList); - pEPList = pEPList->pNext; - } - - if (target->DistributeCredits != NULL) { - DO_DISTRIBUTION(target, - HTC_DUMP_CREDIT_STATE, - "Dump State", - NULL); - } -} - -/* flush all send packets from all endpoint queues */ -void HTCFlushSendPkts(HTC_TARGET *target) -{ - HTC_ENDPOINT *pEndpoint; - int i; - - DumpCreditDistStates(target); - - for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) { - pEndpoint = &target->EndPoint[i]; - if (pEndpoint->ServiceID == 0) { - /* not in use.. */ - continue; - } - HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL); - } - -} - -/* HTC API to flush an endpoint's TX queue*/ -void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag) -{ - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; - - if (pEndpoint->ServiceID == 0) { - AR_DEBUG_ASSERT(FALSE); - /* not in use.. */ - return; - } - - HTCFlushEndpointTX(target, pEndpoint, Tag); -} - -/* HTC API to indicate activity to the credit distribution function */ -void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, - HTC_ENDPOINT_ID Endpoint, - A_BOOL Active) -{ - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; - A_BOOL doDist = FALSE; - - if (pEndpoint->ServiceID == 0) { - AR_DEBUG_ASSERT(FALSE); - /* not in use.. */ - return; - } - - LOCK_HTC_TX(target); - - if (Active) { - if (!(pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE)) { - /* mark active now */ - pEndpoint->CreditDist.DistFlags |= HTC_EP_ACTIVE; - doDist = TRUE; - } - } else { - if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) { - /* mark inactive now */ - pEndpoint->CreditDist.DistFlags &= ~HTC_EP_ACTIVE; - doDist = TRUE; - } - } - - if (doDist) { - /* do distribution again based on activity change - * note, this is done with the lock held */ - DO_DISTRIBUTION(target, - HTC_CREDIT_DIST_ACTIVITY_CHANGE, - "Activity Change", - target->EpCreditDistributionListHead->pNext); - } - - UNLOCK_HTC_TX(target); - -} |