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 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
56 usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
58 FILL_BULK_URB(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);
65 IN PTX_CONTEXT pTxContext,
66 IN UCHAR BulkOutPipeId,
67 IN usb_complete_t Func)
71 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
73 pUrb = pTxContext->pUrb;
76 // Store BulkOut PipeId
77 pTxContext->BulkOutPipeId = BulkOutPipeId;
79 if (pTxContext->bAggregatible)
81 pSrc = &pTxContext->TransferBuffer->Aggregation[2];
85 pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
89 //Initialize a tx bulk urb
90 RTUSB_FILL_BULK_URB(pUrb,
92 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
94 pTxContext->BulkOutSize,
98 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
99 if (pTxContext->bAggregatible)
100 pUrb->transfer_dma = (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
102 pUrb->transfer_dma = pTxContext->data_dma;
104 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
109 VOID RTUSBInitHTTxDesc(
110 IN PRTMP_ADAPTER pAd,
111 IN PHT_TX_CONTEXT pTxContext,
112 IN UCHAR BulkOutPipeId,
113 IN ULONG BulkOutSize,
114 IN usb_complete_t Func)
118 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
120 pUrb = pTxContext->pUrb;
123 // Store BulkOut PipeId
124 pTxContext->BulkOutPipeId = BulkOutPipeId;
126 pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
129 //Initialize a tx bulk urb
130 RTUSB_FILL_BULK_URB(pUrb,
132 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
138 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
139 pUrb->transfer_dma = (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
140 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
145 VOID RTUSBInitRxDesc(
146 IN PRTMP_ADAPTER pAd,
147 IN PRX_CONTEXT pRxContext)
150 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
154 pUrb = pRxContext->pUrb;
157 if ( pAd->BulkInMaxPacketSize == 64)
160 RX_bulk_size = MAX_RXBULK_SIZE;
162 //Initialize a rx bulk urb
163 RTUSB_FILL_BULK_URB(pUrb,
165 usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
166 &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
167 RX_bulk_size - (pAd->NextRxBulkInPosition),
168 (usb_complete_t)RTUSBBulkRxComplete,
171 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
172 pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
173 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
180 ========================================================================
190 ========================================================================
193 #define BULK_OUT_LOCK(pLock, IrqFlags) \
194 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
195 RTMP_IRQ_LOCK((pLock), IrqFlags);
197 #define BULK_OUT_UNLOCK(pLock, IrqFlags) \
198 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
199 RTMP_IRQ_UNLOCK((pLock), IrqFlags);
202 VOID RTUSBBulkOutDataPacket(
203 IN PRTMP_ADAPTER pAd,
204 IN UCHAR BulkOutPipeId,
208 PHT_TX_CONTEXT pHTTXContext;
211 PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL;
213 ULONG TmpBulkEndPos, ThisBulkSize;
214 unsigned long IrqFlags = 0, IrqFlags2 = 0;
215 PUCHAR pWirelessPkt, pAppendant;
216 BOOLEAN bTxQLastRound = FALSE;
217 UCHAR allzero[4]= {0x0,0x0,0x0,0x0};
219 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
220 if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
222 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
225 pAd->BulkOutPending[BulkOutPipeId] = TRUE;
227 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
230 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
231 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
234 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
237 pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
239 BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
240 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
241 || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
243 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
245 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
246 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
249 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
250 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
252 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
257 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
258 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
260 //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
261 // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
262 // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
263 pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
265 TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
266 pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
268 if ((pHTTXContext->bCopySavePad == TRUE))
270 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
272 DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n",
273 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
274 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
276 NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
277 pHTTXContext->bCopySavePad = FALSE;
278 if (pAd->bForcePrintTX == TRUE)
279 DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
284 pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
285 pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
287 if (pAd->bForcePrintTX == TRUE)
288 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU));
290 // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
291 //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))
292 if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK))
294 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
296 // Limit BulkOut size to about 4k bytes.
297 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
300 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
302 // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
303 // 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.
304 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
311 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
312 { // Limit BulkOut size to about 24k bytes.
313 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
316 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
317 { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
318 // 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.
319 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
324 if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
326 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
330 if (pTxInfo->QSEL != FIFO_EDCA)
332 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL);
333 printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
334 hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
337 if (pTxInfo->USBDMATxPktLen <= 8)
339 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
340 DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
341 pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
343 DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n",
344 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
345 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
347 pAd->bForcePrintTX = TRUE;
348 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
349 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
350 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
351 //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
355 // Increase Total transmit byte counter
356 pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount;
357 pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount;
359 pLastTxInfo = pTxInfo;
361 // Make sure we use EDCA QUEUE.
362 pTxInfo->QSEL = FIFO_EDCA;
363 ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
364 TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
366 if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
367 pTxInfo->USBDMANextVLD = 1;
369 if (pTxInfo->SwUseLastRound == 1)
371 if (pHTTXContext->CurWritePosition == 8)
372 pTxInfo->USBDMANextVLD = 0;
373 pTxInfo->SwUseLastRound = 0;
375 bTxQLastRound = TRUE;
376 pHTTXContext->ENextBulkOutPosition = 8;
379 RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
380 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
381 #endif // RT_BIG_ENDIAN //
387 RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
388 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
389 #endif // RT_BIG_ENDIAN //
393 // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
397 RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
398 #endif // RT_BIG_ENDIAN //
399 pLastTxInfo->USBDMANextVLD = 0;
401 RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
402 #endif // RT_BIG_ENDIAN //
406 We need to copy SavedPad when following condition matched!
407 1. Not the last round of the TxQueue and
408 2. any match of following cases:
409 (1). The End Position of this bulk out is reach to the Currenct Write position and
410 the TxInfo and related header already write to the CurWritePosition.
411 =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
413 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
414 =>(ENextBulkOutPosition != CurWritePosition)
416 if ((bTxQLastRound == FALSE) &&
417 (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
418 (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
421 NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
422 pHTTXContext->bCopySavePad = TRUE;
423 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
425 PUCHAR pBuf = &pHTTXContext->SavedPad[0];
426 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",
427 pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
428 pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
430 pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
431 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]));
433 //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
436 if (pAd->bForcePrintTX == TRUE)
437 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));
438 //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));
440 // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
441 pAppendant = &pWirelessPkt[TmpBulkEndPos];
442 NdisZeroMemory(pAppendant, 8);
444 pHTTXContext->LastOne = TRUE;
445 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
447 pHTTXContext->BulkOutSize = ThisBulkSize;
449 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
450 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
452 // Init Tx context descriptor
453 RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
455 pUrb = pHTTXContext->pUrb;
456 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
458 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
460 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
461 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
462 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
463 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
468 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
469 pHTTXContext->IRPPending = TRUE;
470 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
476 VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
478 #if 0 // sample, IRQ LOCK
481 PHT_TX_CONTEXT pHTTXContext;
484 unsigned long IrqFlags;
486 DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutDataPacketComplete\n"));
488 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
489 pAd = pHTTXContext->pAd;
490 pObj = (POS_COOKIE) pAd->OS_Cookie;
491 Status = pUrb->status;
493 // Store BulkOut PipeId
494 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
495 pAd->BulkOutDataOneSecCount++;
497 //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
498 // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
500 RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
501 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
502 pHTTXContext->IRPPending = FALSE;
503 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
505 if (Status == USB_ST_NOERROR)
507 pAd->BulkOutComplete++;
509 pAd->Counters8023.GoodTransmits++;
510 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
511 FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
512 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
520 pAd->BulkOutCompleteOther++;
522 pBuf = &pHTTXContext->TransferBuffer->WirelessPacket[pHTTXContext->NextBulkOutPosition];
524 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
525 DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
526 DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
527 //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
529 if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
530 fRTMP_ADAPTER_HALT_IN_PROGRESS |
531 fRTMP_ADAPTER_NIC_NOT_EXIST |
532 fRTMP_ADAPTER_BULKOUT_RESET)))
534 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
535 pAd->bulkResetPipeid = BulkOutPipeId;
540 // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
541 // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
543 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
544 if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
545 (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
546 !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
548 // Indicate There is data avaliable
549 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
551 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
553 // Always call Bulk routine, even reset bulk.
554 // The protection of rest bulk should be in BulkOut routine
555 RTUSBKickBulkOut(pAd);
558 //DBGPRINT(RT_DEBUG_LOUD,("Done-A(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d\n", BulkOutPipeId, in_interrupt(),
559 // pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
561 switch (BulkOutPipeId)
564 pObj->ac0_dma_done_task.data = (unsigned long)pAd;
565 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
568 pObj->ac1_dma_done_task.data = (unsigned long)pAd;
569 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
572 pObj->ac2_dma_done_task.data = (unsigned long)pAd;
573 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
576 pObj->ac3_dma_done_task.data = (unsigned long)pAd;
577 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
580 pObj->hcca_dma_done_task.data = (unsigned long)pAd;
581 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
587 PHT_TX_CONTEXT pHTTXContext;
593 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
594 pAd = pHTTXContext->pAd;
595 pObj = (POS_COOKIE) pAd->OS_Cookie;
597 // Store BulkOut PipeId
598 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
599 pAd->BulkOutDataOneSecCount++;
601 switch (BulkOutPipeId)
604 pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
605 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
608 pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
609 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
612 pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
613 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
616 pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
617 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
620 pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
621 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
632 ========================================================================
640 Note: NULL frame use BulkOutPipeId = 0
642 ========================================================================
644 VOID RTUSBBulkOutNullFrame(
645 IN PRTMP_ADAPTER pAd)
647 PTX_CONTEXT pNullContext = &(pAd->NullContext);
650 unsigned long IrqFlags;
652 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
653 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
655 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
658 pAd->BulkOutPending[0] = TRUE;
659 pAd->watchDogTxPendingCnt[0] = 1;
660 pNullContext->IRPPending = TRUE;
661 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
663 // Increase Total transmit byte counter
664 pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
667 // Clear Null frame bulk flag
668 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
671 RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO);
672 #endif // RT_BIG_ENDIAN //
674 // Init Tx context descriptor
675 RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
677 pUrb = pNullContext->pUrb;
678 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
680 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
681 pAd->BulkOutPending[0] = FALSE;
682 pAd->watchDogTxPendingCnt[0] = 0;
683 pNullContext->IRPPending = FALSE;
684 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
686 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
692 // NULL frame use BulkOutPipeId = 0
693 VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
696 PTX_CONTEXT pNullContext;
698 #if 0 // sample, IRQ LOCK
699 unsigned long IrqFlags;
704 pNullContext = (PTX_CONTEXT)pUrb->context;
705 pAd = pNullContext->pAd;
706 Status = pUrb->status;
708 #if 0 // sample, IRQ LOCK
709 // Reset Null frame context flags
710 pNullContext->IRPPending = FALSE;
711 pNullContext->InUse = FALSE;
713 if (Status == USB_ST_NOERROR)
715 // Don't worry about the queue is empty or not, this function will check itself
716 //RTMPUSBDeQueuePacket(pAd, 0);
717 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
721 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
722 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
723 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
724 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
726 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed\n"));
727 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
728 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
732 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
733 pAd->BulkOutPending[0] = FALSE;
734 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
736 // Always call Bulk routine, even reset bulk.
737 // The protectioon of rest bulk should be in BulkOut routine
738 RTUSBKickBulkOut(pAd);
741 pObj = (POS_COOKIE) pAd->OS_Cookie;
742 pObj->null_frame_complete_task.data = (unsigned long)pUrb;
743 tasklet_hi_schedule(&pObj->null_frame_complete_task);
748 #if 0 // For RT2870, RTS frame not used now, but maybe will use it latter.
750 ========================================================================
758 Note: RTS frame use BulkOutPipeId = 0
760 ========================================================================
762 VOID RTUSBBulkOutRTSFrame(
763 IN PRTMP_ADAPTER pAd)
765 PTX_CONTEXT pRTSContext = &(pAd->RTSContext);
768 unsigned long IrqFlags;
771 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
773 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
775 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
777 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
780 RTMP_IRQ_LOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
781 if ((pAd->BulkOutPending[PipeID] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
783 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
786 pAd->BulkOutPending[PipeID] = TRUE;
787 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
789 // Increase Total transmit byte counter
790 pAd->RalinkCounters.TransmittedByteCount += pRTSContext->BulkOutSize;
792 DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutRTSFrame \n"));
794 // Clear RTS frame bulk flag
795 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_RTS);
798 RTMPDescriptorEndianChange((PUCHAR)pRTSContext->TransferBuffer, TYPE_TXINFO);
799 #endif // RT_BIG_ENDIAN //
801 // Init Tx context descriptor
802 RTUSBInitTxDesc(pAd, pRTSContext, PipeID, (usb_complete_t)RTUSBBulkOutRTSFrameComplete);
803 pRTSContext->IRPPending = TRUE;
805 pUrb = pRTSContext->pUrb;
806 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
808 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutRTSFrame: Submit Tx URB failed %d\n", ret));
812 DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutRTSFrame \n"));
816 // RTS frame use BulkOutPipeId = 0
817 VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
820 PTX_CONTEXT pRTSContext;
822 #if 0 // sample, IRQ LOCK
823 unsigned long IrqFlags;
827 DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutRTSFrameComplete\n"));
829 pRTSContext = (PTX_CONTEXT)pUrb->context;
830 pAd = pRTSContext->pAd;
831 Status = pUrb->status;
833 #if 0 // sample, IRQ LOCK
834 // Reset RTS frame context flags
835 pRTSContext->IRPPending = FALSE;
836 pRTSContext->InUse = FALSE;
838 if (Status == USB_ST_NOERROR)
840 // Don't worry about the queue is empty or not, this function will check itself
841 //RTMPUSBDeQueuePacket(pAd, pRTSContext->BulkOutPipeId);
842 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
846 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
847 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
848 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
849 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
851 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
852 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
853 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
857 RTMP_IRQ_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags);
858 pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
859 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags);
861 // Always call Bulk routine, even reset bulk.
862 // The protectioon of rest bulk should be in BulkOut routine
863 RTUSBKickBulkOut(pAd);
866 pObj = (POS_COOKIE) pAd->OS_Cookie;
867 pObj->rts_frame_complete_task.data = (unsigned long)pUrb;
868 tasklet_hi_schedule(&pObj->rts_frame_complete_task);
871 DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutRTSFrameComplete\n"));
877 ========================================================================
885 Note: MLME use BulkOutPipeId = 0
887 ========================================================================
889 VOID RTUSBBulkOutMLMEPacket(
890 IN PRTMP_ADAPTER pAd,
893 PTX_CONTEXT pMLMEContext;
896 unsigned long IrqFlags;
898 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
899 pUrb = pMLMEContext->pUrb;
901 if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
902 (pMLMEContext->InUse == FALSE) ||
903 (pMLMEContext->bWaitingBulkOut == FALSE))
907 // Clear MLME bulk flag
908 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
914 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
915 if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
917 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
921 pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
922 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
923 pMLMEContext->IRPPending = TRUE;
924 pMLMEContext->bWaitingBulkOut = FALSE;
925 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
927 // Increase Total transmit byte counter
928 pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
930 // Clear MLME bulk flag
931 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
934 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacket\n"));
937 printk("MLME-Out, C=%d!, D=%d, F=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
939 //TODO: Need to remove it when formal release
940 PTXINFO_STRUC pTxInfo;
942 pTxInfo = (PTXINFO_STRUC)pMLMEContext->TransferBuffer;
943 if (pTxInfo->QSEL != FIFO_EDCA)
945 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL);
946 printk("\tMLME_Index=%d!\n", Index);
947 hex_dump("Wrong QSel Pkt:", (PUCHAR)pMLMEContext->TransferBuffer, pTxInfo->USBDMATxPktLen);
953 RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO);
954 #endif // RT_BIG_ENDIAN //
956 // Init Tx context descriptor
957 RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
959 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
960 //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
961 pUrb->transfer_dma = 0;
962 pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
965 pUrb = pMLMEContext->pUrb;
966 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
968 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
969 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
970 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
971 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
972 pMLMEContext->IRPPending = FALSE;
973 pMLMEContext->bWaitingBulkOut = TRUE;
974 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
979 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
980 // printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
984 VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
986 PTX_CONTEXT pMLMEContext;
991 #if 0 // sample, IRQ LOCK
992 unsigned long IrqFlags;
993 PNDIS_PACKET pPacket;
997 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
998 pMLMEContext = (PTX_CONTEXT)pUrb->context;
999 pAd = pMLMEContext->pAd;
1000 pObj = (POS_COOKIE)pAd->OS_Cookie;
1001 Status = pUrb->status;
1002 index = pMLMEContext->SelfIdx;
1005 #if 0 // sample, IRQ LOCK
1006 ASSERT((pAd->MgmtRing.TxDmaIdx == index));
1007 //printk("MLME-Done-B: C=%d, D=%d, F=%d, Self=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx, pMLMEContext->SelfIdx);
1009 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1012 if (Status != USB_ST_NOERROR)
1014 //Bulk-Out fail status handle
1015 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1016 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1017 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1018 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1020 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1021 // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
1022 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1023 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1026 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1027 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1029 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1030 // Reset MLME context flags
1031 pMLMEContext->IRPPending = FALSE;
1032 pMLMEContext->InUse = FALSE;
1033 pMLMEContext->bWaitingBulkOut = FALSE;
1034 pMLMEContext->BulkOutSize = 0;
1036 pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
1037 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
1039 // Increase MgmtRing Index
1040 INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
1041 pAd->MgmtRing.TxSwFreeIdx++;
1043 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1045 // No-matter success or fail, we free the mgmt packet.
1047 RTMPFreeNdisPacket(pAd, pPacket);
1050 //Bulk-Out fail status handle
1051 if (Status != USB_ST_NOERROR)
1053 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1054 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1055 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1056 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1058 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1059 // TODO: How to handle about the MLMEBulkOut failed issue. Need to reset the endpoint?
1060 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1061 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1066 //printk("MLME-Done-A: C=%d, D=%d, F=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
1068 pObj->mgmt_dma_done_task.data = (unsigned long)pAd;
1069 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
1071 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacketComplete\n"));
1072 // printk("<---RTUSBBulkOutMLMEPacketComplete, Cpu=%d, Dma=%d, SwIdx=%d!\n",
1073 // pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
1077 pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
1078 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
1084 ========================================================================
1086 Routine Description:
1092 Note: PsPoll use BulkOutPipeId = 0
1094 ========================================================================
1096 VOID RTUSBBulkOutPsPoll(
1097 IN PRTMP_ADAPTER pAd)
1099 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
1102 unsigned long IrqFlags;
1104 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1105 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
1107 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1110 pAd->BulkOutPending[0] = TRUE;
1111 pAd->watchDogTxPendingCnt[0] = 1;
1112 pPsPollContext->IRPPending = TRUE;
1113 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1116 // Clear PS-Poll bulk flag
1117 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
1119 #ifdef RT_BIG_ENDIAN
1120 RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO);
1121 #endif // RT_BIG_ENDIAN //
1123 // Init Tx context descriptor
1124 RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
1126 pUrb = pPsPollContext->pUrb;
1127 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1129 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1130 pAd->BulkOutPending[0] = FALSE;
1131 pAd->watchDogTxPendingCnt[0] = 0;
1132 pPsPollContext->IRPPending = FALSE;
1133 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1135 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
1141 // PS-Poll frame use BulkOutPipeId = 0
1142 VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
1145 PTX_CONTEXT pPsPollContext;
1147 #if 0 // sample, IRQ LOCK
1148 unsigned long IrqFlags;
1153 pPsPollContext= (PTX_CONTEXT)pUrb->context;
1154 pAd = pPsPollContext->pAd;
1155 Status = pUrb->status;
1157 #if 0 // sample, IRQ LOCK
1158 // Reset PsPoll context flags
1159 pPsPollContext->IRPPending = FALSE;
1160 pPsPollContext->InUse = FALSE;
1162 if (Status == USB_ST_NOERROR)
1164 // Don't worry about the queue is empty or not, this function will check itself
1165 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1167 else // STATUS_OTHER
1169 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1170 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1171 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1172 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1174 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
1175 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1176 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1180 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1181 pAd->BulkOutPending[0] = FALSE;
1182 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1184 // Always call Bulk routine, even reset bulk.
1185 // The protectioon of rest bulk should be in BulkOut routine
1186 RTUSBKickBulkOut(pAd);
1189 pObj = (POS_COOKIE) pAd->OS_Cookie;
1190 pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
1191 tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
1198 ========================================================================
1200 Routine Description:
1201 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
1202 to USB. It checks if an Rx Descriptor is available and passes the
1203 the coresponding buffer to be filled. If no descriptor is available
1204 fails the request. When setting the completion routine we pass our
1205 Adapter Object as Context.
1210 TRUE found matched tuple cache
1211 FALSE no matched found
1215 ========================================================================
1217 VOID RTUSBBulkReceive(
1218 IN PRTMP_ADAPTER pAd)
1220 PRX_CONTEXT pRxContext;
1223 unsigned long IrqFlags;
1226 /* device had been closed */
1227 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS))
1230 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1232 // Last is time point between 2 separate URB.
1233 if (pAd->NextRxBulkInPosition == 0)
1235 //pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % (RX_RING_SIZE);
1236 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1238 else if ((pAd->NextRxBulkInPosition&0x1ff) != 0)
1240 //pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % (RX_RING_SIZE);
1241 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1242 DBGPRINT_RAW(RT_DEBUG_TRACE, ("pAd->NextRxBulkInPosition = 0x%lx. End of URB.\n", pAd->NextRxBulkInPosition ));
1243 pAd->NextRxBulkInPosition = 0;
1246 if (pAd->NextRxBulkInPosition == MAX_RXBULK_SIZE)
1247 pAd->NextRxBulkInPosition = 0;
1249 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1251 // TODO: Why need to check if pRxContext->InUsed == TRUE?
1252 //if ((pRxContext->InUse == TRUE) || (pRxContext->Readable == TRUE))
1253 if ((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE))
1255 DBGPRINT_RAW(RT_DEBUG_TRACE, ("pRxContext[%d] InUse = %d.pRxContext->Readable = %d. Return.\n", pAd->NextRxBulkInIndex,pRxContext->InUse, pRxContext->Readable ));
1256 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1258 // read RxContext, Since not
1259 #ifdef CONFIG_STA_SUPPORT
1260 STARxDoneInterruptHandle(pAd, TRUE);
1261 #endif // CONFIG_STA_SUPPORT //
1265 pRxContext->InUse = TRUE;
1266 pRxContext->IRPPending= TRUE;
1268 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1270 // Init Rx context descriptor
1271 NdisZeroMemory(pRxContext->TransferBuffer, BUFFER_SIZE);
1272 RTUSBInitRxDesc(pAd, pRxContext);
1274 pUrb = pRxContext->pUrb;
1275 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1277 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
1282 NdisInterlockedIncrement(&pAd->PendingRx);
1286 // read RxContext, Since not
1287 #ifdef CONFIG_STA_SUPPORT
1288 STARxDoneInterruptHandle(pAd, FALSE);
1289 #endif // CONFIG_STA_SUPPORT //
1293 ========================================================================
1295 Routine Description:
1296 This routine process Rx Irp and call rx complete function.
1299 DeviceObject Pointer to the device object for next lower
1300 device. DeviceObject passed in here belongs to
1301 the next lower driver in the stack because we
1302 were invoked via IoCallDriver in USB_RxPacket
1303 AND it is not OUR device object
1304 Irp Ptr to completed IRP
1305 Context Ptr to our Adapter object (context specified
1306 in IoSetCompletionRoutine
1309 Always returns STATUS_MORE_PROCESSING_REQUIRED
1312 Always returns STATUS_MORE_PROCESSING_REQUIRED
1313 ========================================================================
1315 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
1318 PRX_CONTEXT pRxContext;
1323 pRxContext = (PRX_CONTEXT)pUrb->context;
1324 pAd = pRxContext->pAd;
1325 // pObj = (POS_COOKIE) pAd->OS_Cookie;
1328 Status = pUrb->status;
1329 //pRxContext->pIrp = NULL;
1331 pRxContext->InUse = FALSE;
1332 pRxContext->IRPPending = FALSE;
1334 if (Status == USB_ST_NOERROR)
1336 pAd->BulkInComplete++;
1337 pRxContext->Readable = TRUE;
1338 pAd->NextRxBulkInPosition = 0;
1341 else // STATUS_OTHER
1343 pAd->BulkInCompleteFail++;
1344 // Still read this packet although it may comtain wrong bytes.
1345 pRxContext->Readable = FALSE;
1346 // Parsing all packets. because after reset, the index will reset to all zero.
1348 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1349 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET)) &&
1350 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1351 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1354 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status = %d\n", Status));
1355 DBGPRINT_RAW(RT_DEBUG_ERROR, ("==>NextRxBulkInIndex=0x%x, NextRxBulkInReadIndex=0x%x, TransferBufferLength= 0x%x\n",
1356 pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
1358 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1359 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
1364 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1365 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET)) &&
1366 // (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) &&
1367 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) &&
1368 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1369 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1371 RTUSBBulkReceive(pAd);
1374 STARxDoneInterruptHandle(pAd, FALSE);
1376 pObj->rx_bh.data = (unsigned long)pUrb;
1377 tasklet_schedule(&pObj->rx_bh);
1382 // Call RxPacket to process packet and return the status
1383 NdisInterlockedDecrement(&pAd->PendingRx);
1387 // use a receive tasklet to handle received packets;
1388 // or sometimes hardware IRQ will be disabled here, so we can not
1389 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
1390 PRX_CONTEXT pRxContext;
1395 pRxContext = (PRX_CONTEXT)pUrb->context;
1396 pAd = pRxContext->pAd;
1397 pObj = (POS_COOKIE) pAd->OS_Cookie;
1399 pObj->rx_done_task.data = (unsigned long)pUrb;
1400 tasklet_hi_schedule(&pObj->rx_done_task);
1406 VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
1408 PRX_CONTEXT pRxContext;
1411 unsigned long IrqFlags;
1413 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1414 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1415 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
1417 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1420 pRxContext->InUse = TRUE;
1421 pRxContext->IRPPending = TRUE;
1424 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1426 // Init Rx context descriptor
1427 NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
1428 RTUSBInitRxDesc(pAd, pRxContext);
1430 pUrb = pRxContext->pUrb;
1431 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1434 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1435 pRxContext->InUse = FALSE;
1436 pRxContext->IRPPending = FALSE;
1439 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1440 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
1445 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1446 pRxContext->IRPPending = TRUE;
1447 //NdisInterlockedIncrement(&pAd->PendingRx);
1449 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1452 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1453 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
1459 ========================================================================
1461 Routine Description:
1462 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
1463 to USB. It checks if an Rx Descriptor is available and passes the
1464 the coresponding buffer to be filled. If no descriptor is available
1465 fails the request. When setting the completion routine we pass our
1466 Adapter Object as Context.
1471 TRUE found matched tuple cache
1472 FALSE no matched found
1476 ========================================================================
1478 #define fRTMP_ADAPTER_NEED_STOP_RX \
1479 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
1480 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
1481 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
1483 #define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
1484 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
1485 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
1486 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
1488 VOID RTUSBBulkReceive(
1489 IN PRTMP_ADAPTER pAd)
1491 PRX_CONTEXT pRxContext;
1492 unsigned long IrqFlags;
1496 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
1502 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1503 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
1504 if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
1505 (pRxContext->bRxHandling == FALSE))
1507 pRxContext->bRxHandling = TRUE;
1508 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1510 // read RxContext, Since not
1511 #ifdef CONFIG_STA_SUPPORT
1512 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1513 STARxDoneInterruptHandle(pAd, TRUE);
1514 #endif // CONFIG_STA_SUPPORT //
1516 // Finish to handle this bulkIn buffer.
1517 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1518 pRxContext->BulkInOffset = 0;
1519 pRxContext->Readable = FALSE;
1520 pRxContext->bRxHandling = FALSE;
1521 pAd->ReadPosition = 0;
1522 pAd->TransferBufferLength = 0;
1523 INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
1524 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1529 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1534 if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
1541 ========================================================================
1543 Routine Description:
1544 This routine process Rx Irp and call rx complete function.
1547 DeviceObject Pointer to the device object for next lower
1548 device. DeviceObject passed in here belongs to
1549 the next lower driver in the stack because we
1550 were invoked via IoCallDriver in USB_RxPacket
1551 AND it is not OUR device object
1552 Irp Ptr to completed IRP
1553 Context Ptr to our Adapter object (context specified
1554 in IoSetCompletionRoutine
1557 Always returns STATUS_MORE_PROCESSING_REQUIRED
1560 Always returns STATUS_MORE_PROCESSING_REQUIRED
1561 ========================================================================
1563 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
1565 // use a receive tasklet to handle received packets;
1566 // or sometimes hardware IRQ will be disabled here, so we can not
1567 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
1568 PRX_CONTEXT pRxContext;
1573 pRxContext = (PRX_CONTEXT)pUrb->context;
1574 pAd = pRxContext->pAd;
1575 pObj = (POS_COOKIE) pAd->OS_Cookie;
1577 pObj->rx_done_task.data = (unsigned long)pUrb;
1578 tasklet_hi_schedule(&pObj->rx_done_task);
1587 ========================================================================
1589 Routine Description:
1597 ========================================================================
1599 VOID RTUSBKickBulkOut(
1600 IN PRTMP_ADAPTER pAd)
1602 // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
1603 if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
1606 #endif // RALINK_ATE //
1609 #if 0 // not used now in RT28xx, but may used latter.
1610 // 1. Data Fragment has highest priority
1611 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG))
1613 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1614 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1617 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
1620 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_2))
1622 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1623 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1626 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
1629 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_3))
1631 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1632 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1635 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
1638 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_4))
1640 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1641 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1644 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
1649 // 2. PS-Poll frame is next
1650 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
1652 RTUSBBulkOutPsPoll(pAd);
1655 // 5. Mlme frame is next
1656 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
1657 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
1659 RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
1662 // 6. Data frame normal is next
1663 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
1665 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1666 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1669 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
1672 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
1674 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1675 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1678 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
1681 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
1683 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1684 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1687 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
1690 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
1692 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1693 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1696 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
1700 // 7. Null frame is the last
1701 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
1703 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1705 RTUSBBulkOutNullFrame(pAd);
1709 // 8. No data avaliable
1716 /* If the mode is in ATE mode. */
1717 else if((ATE_ON(pAd)) &&
1718 !RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX))// PETER : watch out !
1720 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE))
1722 ATE_RTUSBBulkOutDataPacket(pAd, 0);
1725 #endif // RALINK_ATE //
1730 ========================================================================
1732 Routine Description:
1733 Call from Reset action after BulkOut failed.
1740 ========================================================================
1742 VOID RTUSBCleanUpDataBulkOutQueue(
1743 IN PRTMP_ADAPTER pAd)
1746 PHT_TX_CONTEXT pTxContext;
1748 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1750 for (Idx = 0; Idx < 4; Idx++)
1752 pTxContext = &pAd->TxContext[Idx];
1754 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1755 pTxContext->LastOne = FALSE;
1756 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1757 pAd->BulkOutPending[Idx] = FALSE;
1758 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1761 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1765 ========================================================================
1767 Routine Description:
1775 ========================================================================
1777 VOID RTUSBCleanUpMLMEBulkOutQueue(
1778 IN PRTMP_ADAPTER pAd)
1780 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
1782 #if 0 // Do nothing!
1783 NdisAcquireSpinLock(&pAd->MLMEBulkOutLock);
1784 while (pAd->PrioRingTxCnt > 0)
1786 pAd->MLMEContext[pAd->PrioRingFirstIndex].InUse = FALSE;
1788 pAd->PrioRingFirstIndex++;
1789 if (pAd->PrioRingFirstIndex >= MGMT_RING_SIZE)
1791 pAd->PrioRingFirstIndex = 0;
1794 pAd->PrioRingTxCnt--;
1796 NdisReleaseSpinLock(&pAd->MLMEBulkOutLock);
1799 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1804 ========================================================================
1806 Routine Description:
1815 ========================================================================
1817 VOID RTUSBCancelPendingIRPs(
1818 IN PRTMP_ADAPTER pAd)
1820 RTUSBCancelPendingBulkInIRP(pAd);
1821 RTUSBCancelPendingBulkOutIRP(pAd);
1825 ========================================================================
1827 Routine Description:
1835 ========================================================================
1837 VOID RTUSBCancelPendingBulkInIRP(
1838 IN PRTMP_ADAPTER pAd)
1840 PRX_CONTEXT pRxContext;
1843 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
1844 for ( i = 0; i < (RX_RING_SIZE); i++)
1846 pRxContext = &(pAd->RxContext[i]);
1847 if(pRxContext->IRPPending == TRUE)
1849 RTUSB_UNLINK_URB(pRxContext->pUrb);
1850 pRxContext->IRPPending = FALSE;
1851 pRxContext->InUse = FALSE;
1852 //NdisInterlockedDecrement(&pAd->PendingRx);
1856 DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1861 ========================================================================
1863 Routine Description:
1871 ========================================================================
1873 VOID RTUSBCancelPendingBulkOutIRP(
1874 IN PRTMP_ADAPTER pAd)
1876 PHT_TX_CONTEXT pHTTXContext;
1877 PTX_CONTEXT pMLMEContext;
1878 PTX_CONTEXT pBeaconContext;
1879 PTX_CONTEXT pNullContext;
1880 PTX_CONTEXT pPsPollContext;
1881 PTX_CONTEXT pRTSContext;
1883 // unsigned int IrqFlags;
1884 // NDIS_SPIN_LOCK *pLock;
1885 // BOOLEAN *pPending;
1888 // pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
1889 // pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
1891 for (Idx = 0; Idx < 4; Idx++)
1893 pHTTXContext = &(pAd->TxContext[Idx]);
1895 if (pHTTXContext->IRPPending == TRUE)
1898 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1899 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1900 // when the last IRP on the list has been cancelled; that's how we exit this loop
1903 RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1905 // Sleep 200 microseconds to give cancellation time to work
1910 pHTTXContext->bCopySavePad = 0;
1911 pHTTXContext->CurWritePosition = 0;
1912 pHTTXContext->CurWriteRealPos = 0;
1913 pHTTXContext->bCurWriting = FALSE;
1914 pHTTXContext->NextBulkOutPosition = 0;
1915 pHTTXContext->ENextBulkOutPosition = 0;
1916 #endif // RALINK_ATE //
1917 pAd->BulkOutPending[Idx] = FALSE;
1920 //RTMP_IRQ_LOCK(pLock, IrqFlags);
1921 for (i = 0; i < MGMT_RING_SIZE; i++)
1923 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
1924 if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
1927 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1928 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1929 // when the last IRP on the list has been cancelled; that's how we exit this loop
1932 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1933 pMLMEContext->IRPPending = FALSE;
1935 // Sleep 200 microsecs to give cancellation time to work
1939 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1940 //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
1943 for (i = 0; i < BEACON_RING_SIZE; i++)
1945 pBeaconContext = &(pAd->BeaconContext[i]);
1947 if(pBeaconContext->IRPPending == TRUE)
1950 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1951 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1952 // when the last IRP on the list has been cancelled; that's how we exit this loop
1955 RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1957 // Sleep 200 microsecs to give cancellation time to work
1962 pNullContext = &(pAd->NullContext);
1963 if (pNullContext->IRPPending == TRUE)
1964 RTUSB_UNLINK_URB(pNullContext->pUrb);
1966 pRTSContext = &(pAd->RTSContext);
1967 if (pRTSContext->IRPPending == TRUE)
1968 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1970 pPsPollContext = &(pAd->PsPollContext);
1971 if (pPsPollContext->IRPPending == TRUE)
1972 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1974 for (Idx = 0; Idx < 4; Idx++)
1976 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1977 pAd->BulkOutPending[Idx] = FALSE;
1978 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);