2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 06-25-2004 created
40 #include "../rt_config.h"
41 // Match total 6 bulkout endpoint to corresponding queue.
42 UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT};
44 //static BOOLEAN SingleBulkOut = FALSE;
46 void RTUSB_FILL_BULK_URB (struct urb *pUrb,
47 struct usb_device *pUsb_Dev,
48 unsigned int bulkpipe,
51 usb_complete_t Complete,
55 usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
61 IN PTX_CONTEXT pTxContext,
62 IN UCHAR BulkOutPipeId,
63 IN usb_complete_t Func)
67 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
69 pUrb = pTxContext->pUrb;
72 // Store BulkOut PipeId
73 pTxContext->BulkOutPipeId = BulkOutPipeId;
75 if (pTxContext->bAggregatible)
77 pSrc = &pTxContext->TransferBuffer->Aggregation[2];
81 pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
85 //Initialize a tx bulk urb
86 RTUSB_FILL_BULK_URB(pUrb,
88 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
90 pTxContext->BulkOutSize,
94 if (pTxContext->bAggregatible)
95 pUrb->transfer_dma = (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
97 pUrb->transfer_dma = pTxContext->data_dma;
99 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
103 VOID RTUSBInitHTTxDesc(
104 IN PRTMP_ADAPTER pAd,
105 IN PHT_TX_CONTEXT pTxContext,
106 IN UCHAR BulkOutPipeId,
107 IN ULONG BulkOutSize,
108 IN usb_complete_t Func)
112 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
114 pUrb = pTxContext->pUrb;
117 // Store BulkOut PipeId
118 pTxContext->BulkOutPipeId = BulkOutPipeId;
120 pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
123 //Initialize a tx bulk urb
124 RTUSB_FILL_BULK_URB(pUrb,
126 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
132 pUrb->transfer_dma = (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
133 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
137 VOID RTUSBInitRxDesc(
138 IN PRTMP_ADAPTER pAd,
139 IN PRX_CONTEXT pRxContext)
142 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
146 pUrb = pRxContext->pUrb;
149 if ( pAd->BulkInMaxPacketSize == 64)
152 RX_bulk_size = MAX_RXBULK_SIZE;
154 //Initialize a rx bulk urb
155 RTUSB_FILL_BULK_URB(pUrb,
157 usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
158 &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
159 RX_bulk_size - (pAd->NextRxBulkInPosition),
160 (usb_complete_t)RTUSBBulkRxComplete,
163 pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
164 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
170 ========================================================================
180 ========================================================================
183 #define BULK_OUT_LOCK(pLock, IrqFlags) \
184 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
185 RTMP_IRQ_LOCK((pLock), IrqFlags);
187 #define BULK_OUT_UNLOCK(pLock, IrqFlags) \
188 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
189 RTMP_IRQ_UNLOCK((pLock), IrqFlags);
192 VOID RTUSBBulkOutDataPacket(
193 IN PRTMP_ADAPTER pAd,
194 IN UCHAR BulkOutPipeId,
198 PHT_TX_CONTEXT pHTTXContext;
201 PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL;
203 ULONG TmpBulkEndPos, ThisBulkSize;
204 unsigned long IrqFlags = 0, IrqFlags2 = 0;
205 PUCHAR pWirelessPkt, pAppendant;
206 BOOLEAN bTxQLastRound = FALSE;
207 UCHAR allzero[4]= {0x0,0x0,0x0,0x0};
209 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
210 if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
212 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
215 pAd->BulkOutPending[BulkOutPipeId] = TRUE;
217 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
220 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
221 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
224 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
227 pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
229 BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
230 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
231 || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
233 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
235 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
236 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
239 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
240 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
242 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
247 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
248 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
250 //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
251 // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
252 // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
253 pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
255 TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
256 pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
258 if ((pHTTXContext->bCopySavePad == TRUE))
260 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
262 DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n",
263 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
264 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
266 NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
267 pHTTXContext->bCopySavePad = FALSE;
268 if (pAd->bForcePrintTX == TRUE)
269 DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
274 pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
275 pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
277 if (pAd->bForcePrintTX == TRUE)
278 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU));
280 // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
281 //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))
282 if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK))
284 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
286 // Limit BulkOut size to about 4k bytes.
287 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
291 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
293 // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
294 // 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.
295 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
302 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
303 { // Limit BulkOut size to about 24k bytes.
304 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
308 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
309 { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
310 // 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.
311 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
316 if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
318 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
321 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
323 if (pTxInfo->QSEL != FIFO_EDCA)
325 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL);
326 printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
327 hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
331 if (pTxInfo->USBDMATxPktLen <= 8)
333 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
334 DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
335 pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
337 DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n",
338 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
339 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
341 pAd->bForcePrintTX = TRUE;
342 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
343 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
344 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
345 //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
349 // Increase Total transmit byte counter
350 pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount;
351 pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount;
353 pLastTxInfo = pTxInfo;
355 // Make sure we use EDCA QUEUE.
356 pTxInfo->QSEL = FIFO_EDCA; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
357 ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
358 TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
360 if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
361 pTxInfo->USBDMANextVLD = 1;
363 if (pTxInfo->SwUseLastRound == 1)
365 if (pHTTXContext->CurWritePosition == 8)
366 pTxInfo->USBDMANextVLD = 0;
367 pTxInfo->SwUseLastRound = 0;
369 bTxQLastRound = TRUE;
370 pHTTXContext->ENextBulkOutPosition = 8;
376 // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
379 pLastTxInfo->USBDMANextVLD = 0;
383 We need to copy SavedPad when following condition matched!
384 1. Not the last round of the TxQueue and
385 2. any match of following cases:
386 (1). The End Position of this bulk out is reach to the Currenct Write position and
387 the TxInfo and related header already write to the CurWritePosition.
388 =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
390 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
391 =>(ENextBulkOutPosition != CurWritePosition)
393 if ((bTxQLastRound == FALSE) &&
394 (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
395 (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
398 NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
399 pHTTXContext->bCopySavePad = TRUE;
400 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
402 PUCHAR pBuf = &pHTTXContext->SavedPad[0];
403 DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
404 pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
405 pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
407 pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
408 DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7]));
410 //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
413 if (pAd->bForcePrintTX == TRUE)
414 DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
415 //DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));
417 // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
418 pAppendant = &pWirelessPkt[TmpBulkEndPos];
419 NdisZeroMemory(pAppendant, 8);
421 pHTTXContext->LastOne = TRUE;
422 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
424 pHTTXContext->BulkOutSize = ThisBulkSize;
426 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
427 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
429 // Init Tx context descriptor
430 RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
432 pUrb = pHTTXContext->pUrb;
433 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
435 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
437 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
438 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
439 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
440 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
445 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
446 pHTTXContext->IRPPending = TRUE;
447 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
453 VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
455 PHT_TX_CONTEXT pHTTXContext;
461 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
462 pAd = pHTTXContext->pAd;
463 pObj = (POS_COOKIE) pAd->OS_Cookie;
465 // Store BulkOut PipeId
466 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
467 pAd->BulkOutDataOneSecCount++;
469 switch (BulkOutPipeId)
472 pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
473 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
476 pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
477 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
480 pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
481 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
484 pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
485 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
488 pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
489 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
496 ========================================================================
504 Note: NULL frame use BulkOutPipeId = 0
506 ========================================================================
508 VOID RTUSBBulkOutNullFrame(
509 IN PRTMP_ADAPTER pAd)
511 PTX_CONTEXT pNullContext = &(pAd->NullContext);
514 unsigned long IrqFlags;
516 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
517 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
519 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
522 pAd->BulkOutPending[0] = TRUE;
523 pAd->watchDogTxPendingCnt[0] = 1;
524 pNullContext->IRPPending = TRUE;
525 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
527 // Increase Total transmit byte counter
528 pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
531 // Clear Null frame bulk flag
532 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
534 // Init Tx context descriptor
535 RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
537 pUrb = pNullContext->pUrb;
538 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
540 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
541 pAd->BulkOutPending[0] = FALSE;
542 pAd->watchDogTxPendingCnt[0] = 0;
543 pNullContext->IRPPending = FALSE;
544 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
546 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
552 // NULL frame use BulkOutPipeId = 0
553 VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
556 PTX_CONTEXT pNullContext;
561 pNullContext = (PTX_CONTEXT)pUrb->context;
562 pAd = pNullContext->pAd;
563 Status = pUrb->status;
565 pObj = (POS_COOKIE) pAd->OS_Cookie;
566 pObj->null_frame_complete_task.data = (unsigned long)pUrb;
567 tasklet_hi_schedule(&pObj->null_frame_complete_task);
572 ========================================================================
580 Note: MLME use BulkOutPipeId = 0
582 ========================================================================
584 VOID RTUSBBulkOutMLMEPacket(
585 IN PRTMP_ADAPTER pAd,
588 PTX_CONTEXT pMLMEContext;
591 unsigned long IrqFlags;
593 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
594 pUrb = pMLMEContext->pUrb;
596 if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
597 (pMLMEContext->InUse == FALSE) ||
598 (pMLMEContext->bWaitingBulkOut == FALSE))
602 // Clear MLME bulk flag
603 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
609 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
610 if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
612 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
616 pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
617 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
618 pMLMEContext->IRPPending = TRUE;
619 pMLMEContext->bWaitingBulkOut = FALSE;
620 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
622 // Increase Total transmit byte counter
623 pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
625 // Clear MLME bulk flag
626 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
628 // Init Tx context descriptor
629 RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
631 //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
632 pUrb->transfer_dma = 0;
633 pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
635 pUrb = pMLMEContext->pUrb;
636 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
638 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
639 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
640 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
641 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
642 pMLMEContext->IRPPending = FALSE;
643 pMLMEContext->bWaitingBulkOut = TRUE;
644 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
649 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
650 // printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
654 VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
656 PTX_CONTEXT pMLMEContext;
662 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
663 pMLMEContext = (PTX_CONTEXT)pUrb->context;
664 pAd = pMLMEContext->pAd;
665 pObj = (POS_COOKIE)pAd->OS_Cookie;
666 Status = pUrb->status;
667 index = pMLMEContext->SelfIdx;
669 pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
670 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
675 ========================================================================
683 Note: PsPoll use BulkOutPipeId = 0
685 ========================================================================
687 VOID RTUSBBulkOutPsPoll(
688 IN PRTMP_ADAPTER pAd)
690 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
693 unsigned long IrqFlags;
695 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
696 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
698 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
701 pAd->BulkOutPending[0] = TRUE;
702 pAd->watchDogTxPendingCnt[0] = 1;
703 pPsPollContext->IRPPending = TRUE;
704 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
707 // Clear PS-Poll bulk flag
708 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
710 // Init Tx context descriptor
711 RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
713 pUrb = pPsPollContext->pUrb;
714 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
716 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
717 pAd->BulkOutPending[0] = FALSE;
718 pAd->watchDogTxPendingCnt[0] = 0;
719 pPsPollContext->IRPPending = FALSE;
720 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
722 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
728 // PS-Poll frame use BulkOutPipeId = 0
729 VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
732 PTX_CONTEXT pPsPollContext;
737 pPsPollContext= (PTX_CONTEXT)pUrb->context;
738 pAd = pPsPollContext->pAd;
739 Status = pUrb->status;
740 pObj = (POS_COOKIE) pAd->OS_Cookie;
741 pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
742 tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
746 VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
748 PRX_CONTEXT pRxContext;
751 unsigned long IrqFlags;
753 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
754 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
755 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
757 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
760 pRxContext->InUse = TRUE;
761 pRxContext->IRPPending = TRUE;
764 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
766 // Init Rx context descriptor
767 NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
768 RTUSBInitRxDesc(pAd, pRxContext);
770 pUrb = pRxContext->pUrb;
771 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
774 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
775 pRxContext->InUse = FALSE;
776 pRxContext->IRPPending = FALSE;
779 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
780 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
784 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
785 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
791 ========================================================================
794 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
795 to USB. It checks if an Rx Descriptor is available and passes the
796 the coresponding buffer to be filled. If no descriptor is available
797 fails the request. When setting the completion routine we pass our
798 Adapter Object as Context.
803 TRUE found matched tuple cache
804 FALSE no matched found
808 ========================================================================
810 #define fRTMP_ADAPTER_NEED_STOP_RX \
811 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
812 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
813 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
815 #define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
816 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
817 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
818 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
820 VOID RTUSBBulkReceive(
821 IN PRTMP_ADAPTER pAd)
823 PRX_CONTEXT pRxContext;
824 unsigned long IrqFlags;
828 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
834 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
835 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
836 if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
837 (pRxContext->bRxHandling == FALSE))
839 pRxContext->bRxHandling = TRUE;
840 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
842 // read RxContext, Since not
843 STARxDoneInterruptHandle(pAd, TRUE);
845 // Finish to handle this bulkIn buffer.
846 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
847 pRxContext->BulkInOffset = 0;
848 pRxContext->Readable = FALSE;
849 pRxContext->bRxHandling = FALSE;
850 pAd->ReadPosition = 0;
851 pAd->TransferBufferLength = 0;
852 INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
853 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
858 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
863 if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
870 ========================================================================
873 This routine process Rx Irp and call rx complete function.
876 DeviceObject Pointer to the device object for next lower
877 device. DeviceObject passed in here belongs to
878 the next lower driver in the stack because we
879 were invoked via IoCallDriver in USB_RxPacket
880 AND it is not OUR device object
881 Irp Ptr to completed IRP
882 Context Ptr to our Adapter object (context specified
883 in IoSetCompletionRoutine
886 Always returns STATUS_MORE_PROCESSING_REQUIRED
889 Always returns STATUS_MORE_PROCESSING_REQUIRED
890 ========================================================================
892 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
894 // use a receive tasklet to handle received packets;
895 // or sometimes hardware IRQ will be disabled here, so we can not
896 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
897 PRX_CONTEXT pRxContext;
902 pRxContext = (PRX_CONTEXT)pUrb->context;
903 pAd = pRxContext->pAd;
904 pObj = (POS_COOKIE) pAd->OS_Cookie;
906 pObj->rx_done_task.data = (unsigned long)pUrb;
907 tasklet_hi_schedule(&pObj->rx_done_task);
912 ========================================================================
922 ========================================================================
924 VOID RTUSBKickBulkOut(
925 IN PRTMP_ADAPTER pAd)
927 // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
928 if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
931 // 2. PS-Poll frame is next
932 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
934 RTUSBBulkOutPsPoll(pAd);
937 // 5. Mlme frame is next
938 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
939 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
941 RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
944 // 6. Data frame normal is next
945 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
947 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
948 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
951 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
954 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
956 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
957 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
960 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
963 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
965 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
966 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
969 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
972 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
974 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
975 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
978 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
981 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
982 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5))
984 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
985 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
991 // 7. Null frame is the last
992 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
994 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
996 RTUSBBulkOutNullFrame(pAd);
1000 // 8. No data avaliable
1009 ========================================================================
1011 Routine Description:
1012 Call from Reset action after BulkOut failed.
1019 ========================================================================
1021 VOID RTUSBCleanUpDataBulkOutQueue(
1022 IN PRTMP_ADAPTER pAd)
1025 PHT_TX_CONTEXT pTxContext;
1027 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1029 for (Idx = 0; Idx < 4; Idx++)
1031 pTxContext = &pAd->TxContext[Idx];
1033 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1034 pTxContext->LastOne = FALSE;
1035 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1036 pAd->BulkOutPending[Idx] = FALSE;
1037 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1040 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1044 ========================================================================
1046 Routine Description:
1054 ========================================================================
1056 VOID RTUSBCleanUpMLMEBulkOutQueue(
1057 IN PRTMP_ADAPTER pAd)
1059 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
1060 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1065 ========================================================================
1067 Routine Description:
1076 ========================================================================
1078 VOID RTUSBCancelPendingIRPs(
1079 IN PRTMP_ADAPTER pAd)
1081 RTUSBCancelPendingBulkInIRP(pAd);
1082 RTUSBCancelPendingBulkOutIRP(pAd);
1086 ========================================================================
1088 Routine Description:
1096 ========================================================================
1098 VOID RTUSBCancelPendingBulkInIRP(
1099 IN PRTMP_ADAPTER pAd)
1101 PRX_CONTEXT pRxContext;
1104 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
1105 for ( i = 0; i < (RX_RING_SIZE); i++)
1107 pRxContext = &(pAd->RxContext[i]);
1108 if(pRxContext->IRPPending == TRUE)
1110 RTUSB_UNLINK_URB(pRxContext->pUrb);
1111 pRxContext->IRPPending = FALSE;
1112 pRxContext->InUse = FALSE;
1113 //NdisInterlockedDecrement(&pAd->PendingRx);
1117 DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1122 ========================================================================
1124 Routine Description:
1132 ========================================================================
1134 VOID RTUSBCancelPendingBulkOutIRP(
1135 IN PRTMP_ADAPTER pAd)
1137 PHT_TX_CONTEXT pHTTXContext;
1138 PTX_CONTEXT pMLMEContext;
1139 PTX_CONTEXT pBeaconContext;
1140 PTX_CONTEXT pNullContext;
1141 PTX_CONTEXT pPsPollContext;
1142 PTX_CONTEXT pRTSContext;
1144 // unsigned int IrqFlags;
1145 // NDIS_SPIN_LOCK *pLock;
1146 // BOOLEAN *pPending;
1149 // pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
1150 // pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
1152 for (Idx = 0; Idx < 4; Idx++)
1154 pHTTXContext = &(pAd->TxContext[Idx]);
1156 if (pHTTXContext->IRPPending == TRUE)
1159 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1160 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1161 // when the last IRP on the list has been cancelled; that's how we exit this loop
1164 RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1166 // Sleep 200 microseconds to give cancellation time to work
1170 pAd->BulkOutPending[Idx] = FALSE;
1173 //RTMP_IRQ_LOCK(pLock, IrqFlags);
1174 for (i = 0; i < MGMT_RING_SIZE; i++)
1176 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
1177 if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
1180 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1181 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1182 // when the last IRP on the list has been cancelled; that's how we exit this loop
1185 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1186 pMLMEContext->IRPPending = FALSE;
1188 // Sleep 200 microsecs to give cancellation time to work
1192 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1193 //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
1196 for (i = 0; i < BEACON_RING_SIZE; i++)
1198 pBeaconContext = &(pAd->BeaconContext[i]);
1200 if(pBeaconContext->IRPPending == TRUE)
1203 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1204 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1205 // when the last IRP on the list has been cancelled; that's how we exit this loop
1208 RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1210 // Sleep 200 microsecs to give cancellation time to work
1215 pNullContext = &(pAd->NullContext);
1216 if (pNullContext->IRPPending == TRUE)
1217 RTUSB_UNLINK_URB(pNullContext->pUrb);
1219 pRTSContext = &(pAd->RTSContext);
1220 if (pRTSContext->IRPPending == TRUE)
1221 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1223 pPsPollContext = &(pAd->PsPollContext);
1224 if (pPsPollContext->IRPPending == TRUE)
1225 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1227 for (Idx = 0; Idx < 4; Idx++)
1229 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1230 pAd->BulkOutPending[Idx] = FALSE;
1231 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);