📄 rtusb_bulk.c
字号:
/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * Taiwan, R.O.C. * * (c) Copyright 2002-2007, Ralink Technology, Inc. * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * ************************************************************************* Module Name: rtusb_bulk.c Abstract: Revision History: Who When What -------- ---------- ---------------------------------------------- Name Date Modification logs Paul Lin 06-25-2004 created */#ifdef RTMP_MAC_USB#include "rt_config.h"// Match total 6 bulkout endpoint to corresponding queue.UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT};//static BOOLEAN SingleBulkOut = FALSE;void RTUSB_FILL_BULK_URB (struct urb *pUrb, struct usb_device *pUsb_Dev, unsigned int bulkpipe, void *pTransferBuf, int BufSize, usb_complete_t Complete, void *pContext){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext); #else FILL_BULK_URB(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);#endif}VOID RTUSBInitTxDesc( IN PRTMP_ADAPTER pAd, IN PTX_CONTEXT pTxContext, IN UCHAR BulkOutPipeId, IN usb_complete_t Func){ PURB pUrb; PUCHAR pSrc = NULL; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; pUrb = pTxContext->pUrb; ASSERT(pUrb); // Store BulkOut PipeId pTxContext->BulkOutPipeId = BulkOutPipeId; if (pTxContext->bAggregatible) { pSrc = &pTxContext->TransferBuffer->Aggregation[2]; } else { pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket; } //Initialize a tx bulk urb RTUSB_FILL_BULK_URB(pUrb, pObj->pUsb_Dev, usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]), pSrc, pTxContext->BulkOutSize, Func, pTxContext); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) if (pTxContext->bAggregatible) pUrb->transfer_dma = (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2); else pUrb->transfer_dma = pTxContext->data_dma; pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;#endif}VOID RTUSBInitHTTxDesc( IN PRTMP_ADAPTER pAd, IN PHT_TX_CONTEXT pTxContext, IN UCHAR BulkOutPipeId, IN ULONG BulkOutSize, IN usb_complete_t Func){ PURB pUrb; PUCHAR pSrc = NULL; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; pUrb = pTxContext->pUrb; ASSERT(pUrb); // Store BulkOut PipeId pTxContext->BulkOutPipeId = BulkOutPipeId; pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition]; //Initialize a tx bulk urb RTUSB_FILL_BULK_URB(pUrb, pObj->pUsb_Dev, usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]), pSrc, BulkOutSize, Func, pTxContext); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) pUrb->transfer_dma = (pTxContext->data_dma + pTxContext->NextBulkOutPosition); pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;#endif}VOID RTUSBInitRxDesc( IN PRTMP_ADAPTER pAd, IN PRX_CONTEXT pRxContext){ PURB pUrb; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; ULONG RX_bulk_size; pUrb = pRxContext->pUrb; ASSERT(pUrb); if ( pAd->BulkInMaxPacketSize == 64) RX_bulk_size = 4096; else RX_bulk_size = MAX_RXBULK_SIZE; //Initialize a rx bulk urb RTUSB_FILL_BULK_URB(pUrb, pObj->pUsb_Dev, usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr), &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]), RX_bulk_size - (pAd->NextRxBulkInPosition), (usb_complete_t)RTUSBBulkRxComplete, (void *)pRxContext);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition; pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;#endif }/* ======================================================================== Routine Description: Arguments: Return Value: Note: ========================================================================*/#define BULK_OUT_LOCK(pLock, IrqFlags) \ if(1 /*!(in_interrupt() & 0xffff0000)*/) \ RTMP_IRQ_LOCK((pLock), IrqFlags); #define BULK_OUT_UNLOCK(pLock, IrqFlags) \ if(1 /*!(in_interrupt() & 0xffff0000)*/) \ RTMP_IRQ_UNLOCK((pLock), IrqFlags);VOID RTUSBBulkOutDataPacket( IN PRTMP_ADAPTER pAd, IN UCHAR BulkOutPipeId, IN UCHAR Index){ PHT_TX_CONTEXT pHTTXContext; PURB pUrb; int ret = 0; PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL; PTXWI_STRUC pTxWI; ULONG TmpBulkEndPos, ThisBulkSize; unsigned long IrqFlags = 0, IrqFlags2 = 0; PUCHAR pWirelessPkt, pAppendant; BOOLEAN bTxQLastRound = FALSE; UCHAR allzero[4]= {0x0,0x0,0x0,0x0}; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->BulkOutPending[BulkOutPipeId] = TRUE; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) ) { pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pHTTXContext = &(pAd->TxContext[BulkOutPipeId]); BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; // Clear Data flag RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } // Clear Data flag RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(), // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition; ThisBulkSize = 0; TmpBulkEndPos = pHTTXContext->NextBulkOutPosition; pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0]; if ((pHTTXContext->bCopySavePad == TRUE)) { if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) { DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8); pHTTXContext->bCopySavePad = FALSE; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition)); } do { pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos]; pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU)); // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) {#ifdef INF_AMAZON_SE /*Iverson Add for AMAZON USB (RT2070 && RT3070) to pass WMM A2-T4 ~ A2-T10*/ if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) { /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate*/ if(pTxWI->PacketId == 6) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (BulkOutPipeId == 1) { /*BK No Limit BulkOut size .*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1000) == 0x1000) && (BulkOutPipeId == 0) )) { /*BE Limit BulkOut size to about 4k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1c00) == 0x1c00) && (BulkOutPipeId == 2) )) { /*VI Limit BulkOut size to about 7k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x2500) == 0x2500) && (BulkOutPipeId == 3) )) { /*VO Limit BulkOut size to about 9k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) { /* Limit BulkOut size to about 4k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; }#else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) { // Limit BulkOut size to about 4k bytes. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; }#endif // INF_AMAZON_SE // else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } // end Iverson else {#ifdef INF_AMAZON_SE//#ifdef DOT11_N_SUPPORT// if(((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000) || ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))) // {// /* AMAZON_SE: BG mode Disable BulkOut Aggregate, N mode BulkOut Aggregaet size 24K */// pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;// break;// }// else //#endif // DOT11_N_SUPPORT // // { if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && (pTxWI->AMPDU == 0)) { if (((ThisBulkSize&0x1000) == 0x1000) && (BulkOutPipeId == 0)) { /*BE BulkOut Aggregate 4K for AMAZON B/G throughput and PASS WMM (need usb host patch) */ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((ThisBulkSize&0x1c00) == 0x1c00) && (BulkOutPipeId == 2)) { /*VI BulkOut Aggregate 7K for AMAZON B/G PASS WMM (need usb host patch) */ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((ThisBulkSize&0x2500) == 0x2500) && (BulkOutPipeId == 3)) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; /*V0 BulkOut Aggregate 9K for AMAZON B/G PASS WMM (need usb host patch) */ break; } else if (((ThisBulkSize != 0) && (BulkOutPipeId == 1) ) ) { /*BK BulkOut Disable Aggregate for AMAZON B/G PASS WMM (need usb host patch) */ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; }/* else if(((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0))) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; }*/ }/* else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) { // Limit BulkOut size to about 24k bytes. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } }*/#endif // INF_AMAZON_SE // if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) { // Limit BulkOut size to about 24k bytes. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } if (TmpBulkEndPos == pHTTXContext->CurWritePosition) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } if (pTxInfo->QSEL != FIFO_EDCA) { DBGPRINT(RT_DEBUG_ERROR, ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __FUNCTION__, pTxInfo->QSEL)); DBGPRINT(RT_DEBUG_ERROR, ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition)); } if (pTxInfo->USBDMATxPktLen <= 8) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n", pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos)); { DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } pAd->bForcePrintTX = TRUE; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen)); return; } // Increase Total transmit byte counter pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount; pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount; pLastTxInfo = pTxInfo; // Make sure we use EDCA QUEUE.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -