Staging: rt2870: prepare for rt{28,30}70/common/*.[ch] merge
[linux-2.6] / drivers / staging / rt2870 / common / rtusb_bulk.c
1  /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
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.                                   *
14  *                                                                       *
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.                          *
19  *                                                                       *
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.             *
24  *                                                                       *
25  *************************************************************************
26
27         Module Name:
28         rtusb_bulk.c
29
30         Abstract:
31
32         Revision History:
33         Who                     When            What
34         --------        ----------      ----------------------------------------------
35         Name            Date            Modification logs
36         Paul Lin        06-25-2004      created
37
38 */
39
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};
43
44 //static BOOLEAN SingleBulkOut = FALSE;
45
46 void RTUSB_FILL_BULK_URB (struct urb *pUrb,
47         struct usb_device *pUsb_Dev,
48         unsigned int bulkpipe,
49         void *pTransferBuf,
50         int BufSize,
51         usb_complete_t Complete,
52         void *pContext)
53 {
54
55         usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
56
57 }
58
59 VOID    RTUSBInitTxDesc(
60         IN      PRTMP_ADAPTER   pAd,
61         IN      PTX_CONTEXT             pTxContext,
62         IN      UCHAR                   BulkOutPipeId,
63         IN      usb_complete_t  Func)
64 {
65         PURB                            pUrb;
66         PUCHAR                          pSrc = NULL;
67         POS_COOKIE                      pObj = (POS_COOKIE) pAd->OS_Cookie;
68
69         pUrb = pTxContext->pUrb;
70         ASSERT(pUrb);
71
72         // Store BulkOut PipeId
73         pTxContext->BulkOutPipeId = BulkOutPipeId;
74
75         if (pTxContext->bAggregatible)
76         {
77                 pSrc = &pTxContext->TransferBuffer->Aggregation[2];
78         }
79         else
80         {
81                 pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
82         }
83
84
85         //Initialize a tx bulk urb
86         RTUSB_FILL_BULK_URB(pUrb,
87                                                 pObj->pUsb_Dev,
88                                                 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
89                                                 pSrc,
90                                                 pTxContext->BulkOutSize,
91                                                 Func,
92                                                 pTxContext);
93
94         if (pTxContext->bAggregatible)
95                 pUrb->transfer_dma      = (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
96         else
97                 pUrb->transfer_dma      = pTxContext->data_dma;
98
99         pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
100
101 }
102
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)
109 {
110         PURB                            pUrb;
111         PUCHAR                          pSrc = NULL;
112         POS_COOKIE                      pObj = (POS_COOKIE) pAd->OS_Cookie;
113
114         pUrb = pTxContext->pUrb;
115         ASSERT(pUrb);
116
117         // Store BulkOut PipeId
118         pTxContext->BulkOutPipeId = BulkOutPipeId;
119
120         pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
121
122
123         //Initialize a tx bulk urb
124         RTUSB_FILL_BULK_URB(pUrb,
125                                                 pObj->pUsb_Dev,
126                                                 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
127                                                 pSrc,
128                                                 BulkOutSize,
129                                                 Func,
130                                                 pTxContext);
131
132         pUrb->transfer_dma      = (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
133         pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
134
135 }
136
137 VOID    RTUSBInitRxDesc(
138         IN      PRTMP_ADAPTER   pAd,
139         IN      PRX_CONTEXT             pRxContext)
140 {
141         PURB                            pUrb;
142         POS_COOKIE                      pObj = (POS_COOKIE) pAd->OS_Cookie;
143         ULONG                           RX_bulk_size;
144
145
146         pUrb = pRxContext->pUrb;
147         ASSERT(pUrb);
148
149         if ( pAd->BulkInMaxPacketSize == 64)
150                 RX_bulk_size = 4096;
151         else
152                 RX_bulk_size = MAX_RXBULK_SIZE;
153
154         //Initialize a rx bulk urb
155         RTUSB_FILL_BULK_URB(pUrb,
156                                                 pObj->pUsb_Dev,
157                                                 usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
158                                                 &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
159                                                 RX_bulk_size - (pAd->NextRxBulkInPosition),
160                                                 (usb_complete_t)RTUSBBulkRxComplete,
161                                                 (void *)pRxContext);
162
163         pUrb->transfer_dma      = pRxContext->data_dma + pAd->NextRxBulkInPosition;
164         pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
165
166
167 }
168
169 /*
170         ========================================================================
171
172         Routine Description:
173
174         Arguments:
175
176         Return Value:
177
178         Note:
179
180         ========================================================================
181 */
182
183 #define BULK_OUT_LOCK(pLock, IrqFlags)  \
184                 if(1 /*!(in_interrupt() & 0xffff0000)*/)        \
185                         RTMP_IRQ_LOCK((pLock), IrqFlags);
186
187 #define BULK_OUT_UNLOCK(pLock, IrqFlags)        \
188                 if(1 /*!(in_interrupt() & 0xffff0000)*/)        \
189                         RTMP_IRQ_UNLOCK((pLock), IrqFlags);
190
191
192 VOID    RTUSBBulkOutDataPacket(
193         IN      PRTMP_ADAPTER   pAd,
194         IN      UCHAR                   BulkOutPipeId,
195         IN      UCHAR                   Index)
196 {
197
198         PHT_TX_CONTEXT  pHTTXContext;
199         PURB                    pUrb;
200         int                             ret = 0;
201         PTXINFO_STRUC   pTxInfo, pLastTxInfo = NULL;
202         PTXWI_STRUC             pTxWI;
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};
208
209         BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
210         if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
211         {
212                 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
213                 return;
214         }
215         pAd->BulkOutPending[BulkOutPipeId] = TRUE;
216
217         if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
218                 )
219         {
220                 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
221                 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
222                 return;
223         }
224         BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
225
226
227         pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
228
229         BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
230         if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
231                 || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
232         {
233                 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
234
235                 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
236                 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
237
238                 // Clear Data flag
239                 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
240                 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
241
242                 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
243                 return;
244         }
245
246         // Clear Data flag
247         RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
248         RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
249
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;
254         ThisBulkSize = 0;
255         TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
256         pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
257
258         if ((pHTTXContext->bCopySavePad == TRUE))
259         {
260                 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
261                 {
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]));
265                 }
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));
270         }
271
272         do
273         {
274                 pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
275                 pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
276
277                 if (pAd->bForcePrintTX == TRUE)
278                         DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n",   pTxWI->AMPDU));
279
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))
283                 {
284                         if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
285                         {
286                                 // Limit BulkOut size to about 4k bytes.
287                                 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
288                                 break;
289                         }
290                         else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))*/)
291                         {
292                                 // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
293                                 // 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.
294                                 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
295                                 break;
296                         }
297                 }
298                 // end Iverson
299                 else
300                 {
301                         if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
302                         {       // Limit BulkOut size to about 24k bytes.
303                                 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
304                                 break;
305                         }
306                         else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))*/)
307                         {       // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
308                                 // 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.
309                                 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
310                                 break;
311                         }
312                 }
313
314                 if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
315                 {
316                         pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
317                         break;
318                 }
319
320                 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
321                 if (pTxInfo->QSEL != FIFO_EDCA)
322                 {
323                         printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL);
324                         printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
325                         hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
326                 }
327
328                 if (pTxInfo->USBDMATxPktLen <= 8)
329                 {
330                         BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
331                         DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
332                                         pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
333                         {
334                                 DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x  %x  %x  %x  %x  %x  %x  %x \n",
335                                         pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
336                                         ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
337                         }
338                         pAd->bForcePrintTX = TRUE;
339                         BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
340                         pAd->BulkOutPending[BulkOutPipeId] = FALSE;
341                         BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
342                         //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
343                         return;
344                 }
345
346                         // Increase Total transmit byte counter
347                 pAd->RalinkCounters.OneSecTransmittedByteCount +=  pTxWI->MPDUtotalByteCount;
348                 pAd->RalinkCounters.TransmittedByteCount +=  pTxWI->MPDUtotalByteCount;
349
350                 pLastTxInfo = pTxInfo;
351
352                 // Make sure we use EDCA QUEUE.
353                 pTxInfo->QSEL = FIFO_EDCA;  //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
354                 ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
355                 TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
356
357                 if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
358                         pTxInfo->USBDMANextVLD = 1;
359
360                 if (pTxInfo->SwUseLastRound == 1)
361                 {
362                         if (pHTTXContext->CurWritePosition == 8)
363                                 pTxInfo->USBDMANextVLD = 0;
364                         pTxInfo->SwUseLastRound = 0;
365
366                         bTxQLastRound = TRUE;
367                         pHTTXContext->ENextBulkOutPosition = 8;
368
369                         break;
370                 }
371         }while (TRUE);
372
373         // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
374         if (pLastTxInfo)
375         {
376                 pLastTxInfo->USBDMANextVLD = 0;
377         }
378
379         /*
380                 We need to copy SavedPad when following condition matched!
381                         1. Not the last round of the TxQueue and
382                         2. any match of following cases:
383                                 (1). The End Position of this bulk out is reach to the Currenct Write position and
384                                                 the TxInfo and related header already write to the CurWritePosition.
385                                         =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
386
387                                 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
388                                         =>(ENextBulkOutPosition != CurWritePosition)
389         */
390         if ((bTxQLastRound == FALSE) &&
391                  (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
392                   (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
393                 )
394         {
395                 NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
396                 pHTTXContext->bCopySavePad = TRUE;
397                 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
398                 {
399                         PUCHAR  pBuf = &pHTTXContext->SavedPad[0];
400                         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",
401                                 pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
402                                 pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
403
404                         pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
405                         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]));
406                 }
407                 //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
408         }
409
410         if (pAd->bForcePrintTX == TRUE)
411                 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));
412         //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));
413
414                 // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
415         pAppendant = &pWirelessPkt[TmpBulkEndPos];
416         NdisZeroMemory(pAppendant, 8);
417                 ThisBulkSize += 4;
418                 pHTTXContext->LastOne = TRUE;
419                 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
420                         ThisBulkSize += 4;
421         pHTTXContext->BulkOutSize = ThisBulkSize;
422
423         pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
424         BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
425
426         // Init Tx context descriptor
427         RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
428
429         pUrb = pHTTXContext->pUrb;
430         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
431         {
432                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
433
434                 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
435                 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
436                 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
437                 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
438
439                 return;
440         }
441
442         BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
443         pHTTXContext->IRPPending = TRUE;
444         BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
445         pAd->BulkOutReq++;
446
447 }
448
449
450 VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
451 {
452         PHT_TX_CONTEXT  pHTTXContext;
453         PRTMP_ADAPTER   pAd;
454         POS_COOKIE              pObj;
455         UCHAR                   BulkOutPipeId;
456
457
458         pHTTXContext    = (PHT_TX_CONTEXT)pUrb->context;
459         pAd                     = pHTTXContext->pAd;
460         pObj                    = (POS_COOKIE) pAd->OS_Cookie;
461
462         // Store BulkOut PipeId
463         BulkOutPipeId   = pHTTXContext->BulkOutPipeId;
464         pAd->BulkOutDataOneSecCount++;
465
466         switch (BulkOutPipeId)
467         {
468                 case 0:
469                                 pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
470                                 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
471                                 break;
472                 case 1:
473                                 pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
474                                 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
475                                 break;
476                 case 2:
477                                 pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
478                                 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
479                                 break;
480                 case 3:
481                                 pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
482                                 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
483                                 break;
484                 case 4:
485                                 pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
486                                 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
487                                 break;
488         }
489 }
490
491
492 /*
493         ========================================================================
494
495         Routine Description:
496
497         Arguments:
498
499         Return Value:
500
501         Note: NULL frame use BulkOutPipeId = 0
502
503         ========================================================================
504 */
505 VOID    RTUSBBulkOutNullFrame(
506         IN      PRTMP_ADAPTER   pAd)
507 {
508         PTX_CONTEXT             pNullContext = &(pAd->NullContext);
509         PURB                    pUrb;
510         int                             ret = 0;
511         unsigned long   IrqFlags;
512
513         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
514         if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
515         {
516                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
517                 return;
518         }
519         pAd->BulkOutPending[0] = TRUE;
520         pAd->watchDogTxPendingCnt[0] = 1;
521         pNullContext->IRPPending = TRUE;
522         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
523
524         // Increase Total transmit byte counter
525         pAd->RalinkCounters.TransmittedByteCount +=  pNullContext->BulkOutSize;
526
527
528         // Clear Null frame bulk flag
529         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
530
531         // Init Tx context descriptor
532         RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
533
534         pUrb = pNullContext->pUrb;
535         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
536         {
537                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
538                 pAd->BulkOutPending[0] = FALSE;
539                 pAd->watchDogTxPendingCnt[0] = 0;
540                 pNullContext->IRPPending = FALSE;
541                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
542
543                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
544                 return;
545         }
546
547 }
548
549 // NULL frame use BulkOutPipeId = 0
550 VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
551 {
552         PRTMP_ADAPTER           pAd;
553         PTX_CONTEXT                     pNullContext;
554         NTSTATUS                        Status;
555         POS_COOKIE                      pObj;
556
557
558         pNullContext    = (PTX_CONTEXT)pUrb->context;
559         pAd                     = pNullContext->pAd;
560         Status                  = pUrb->status;
561
562         pObj = (POS_COOKIE) pAd->OS_Cookie;
563         pObj->null_frame_complete_task.data = (unsigned long)pUrb;
564         tasklet_hi_schedule(&pObj->null_frame_complete_task);
565 }
566
567 /*
568         ========================================================================
569
570         Routine Description:
571
572         Arguments:
573
574         Return Value:
575
576         Note: MLME use BulkOutPipeId = 0
577
578         ========================================================================
579 */
580 VOID    RTUSBBulkOutMLMEPacket(
581         IN      PRTMP_ADAPTER   pAd,
582         IN      UCHAR                   Index)
583 {
584         PTX_CONTEXT             pMLMEContext;
585         PURB                    pUrb;
586         int                             ret = 0;
587         unsigned long   IrqFlags;
588
589         pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
590         pUrb = pMLMEContext->pUrb;
591
592         if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
593                 (pMLMEContext->InUse == FALSE) ||
594                 (pMLMEContext->bWaitingBulkOut == FALSE))
595         {
596
597
598                 // Clear MLME bulk flag
599                 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
600
601                 return;
602         }
603
604
605         RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
606         if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
607         {
608                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
609                 return;
610         }
611
612         pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
613         pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
614         pMLMEContext->IRPPending = TRUE;
615         pMLMEContext->bWaitingBulkOut = FALSE;
616         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
617
618         // Increase Total transmit byte counter
619         pAd->RalinkCounters.TransmittedByteCount +=  pMLMEContext->BulkOutSize;
620
621         // Clear MLME bulk flag
622         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
623
624         // Init Tx context descriptor
625         RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
626
627         //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
628         pUrb->transfer_dma      = 0;
629         pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
630
631         pUrb = pMLMEContext->pUrb;
632         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
633         {
634                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
635                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
636                 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
637                 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
638                 pMLMEContext->IRPPending = FALSE;
639                 pMLMEContext->bWaitingBulkOut = TRUE;
640                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
641
642                 return;
643         }
644
645         //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
646 //      printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
647 }
648
649
650 VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
651 {
652         PTX_CONTEXT                     pMLMEContext;
653         PRTMP_ADAPTER           pAd;
654         NTSTATUS                        Status;
655         POS_COOKIE                      pObj;
656         int                                     index;
657
658         //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
659         pMLMEContext    = (PTX_CONTEXT)pUrb->context;
660         pAd                     = pMLMEContext->pAd;
661         pObj                    = (POS_COOKIE)pAd->OS_Cookie;
662         Status                  = pUrb->status;
663         index                   = pMLMEContext->SelfIdx;
664
665         pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
666         tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
667 }
668
669
670 /*
671         ========================================================================
672
673         Routine Description:
674
675         Arguments:
676
677         Return Value:
678
679         Note: PsPoll use BulkOutPipeId = 0
680
681         ========================================================================
682 */
683 VOID    RTUSBBulkOutPsPoll(
684         IN      PRTMP_ADAPTER   pAd)
685 {
686         PTX_CONTEXT             pPsPollContext = &(pAd->PsPollContext);
687         PURB                    pUrb;
688         int                             ret = 0;
689         unsigned long   IrqFlags;
690
691         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
692         if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
693         {
694                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
695                 return;
696         }
697         pAd->BulkOutPending[0] = TRUE;
698         pAd->watchDogTxPendingCnt[0] = 1;
699         pPsPollContext->IRPPending = TRUE;
700         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
701
702
703         // Clear PS-Poll bulk flag
704         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
705
706         // Init Tx context descriptor
707         RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
708
709         pUrb = pPsPollContext->pUrb;
710         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
711         {
712                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
713                 pAd->BulkOutPending[0] = FALSE;
714                 pAd->watchDogTxPendingCnt[0] = 0;
715                 pPsPollContext->IRPPending = FALSE;
716                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
717
718                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
719                 return;
720         }
721
722 }
723
724 // PS-Poll frame use BulkOutPipeId = 0
725 VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
726 {
727         PRTMP_ADAPTER           pAd;
728         PTX_CONTEXT                     pPsPollContext;
729         NTSTATUS                        Status;
730         POS_COOKIE                      pObj;
731
732
733         pPsPollContext= (PTX_CONTEXT)pUrb->context;
734         pAd = pPsPollContext->pAd;
735         Status = pUrb->status;
736
737         pObj = (POS_COOKIE) pAd->OS_Cookie;
738         pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
739         tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
740 }
741
742 VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
743 {
744         PRX_CONTEXT             pRxContext;
745         PURB                    pUrb;
746         int                             ret = 0;
747         unsigned long   IrqFlags;
748
749         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
750         pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
751         if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
752         {
753                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
754                 return;
755         }
756         pRxContext->InUse = TRUE;
757         pRxContext->IRPPending = TRUE;
758         pAd->PendingRx++;
759         pAd->BulkInReq++;
760         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
761
762         // Init Rx context descriptor
763         NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
764         RTUSBInitRxDesc(pAd, pRxContext);
765
766         pUrb = pRxContext->pUrb;
767         if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
768         {       // fail
769
770                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
771                 pRxContext->InUse = FALSE;
772                 pRxContext->IRPPending = FALSE;
773                 pAd->PendingRx--;
774                 pAd->BulkInReq--;
775                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
776                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
777         }
778         else
779         {       // success
780                 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
781                 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
782         }
783 }
784
785
786 /*
787         ========================================================================
788
789         Routine Description:
790         USB_RxPacket initializes a URB and uses the Rx IRP to submit it
791         to USB. It checks if an Rx Descriptor is available and passes the
792         the coresponding buffer to be filled. If no descriptor is available
793         fails the request. When setting the completion routine we pass our
794         Adapter Object as Context.
795
796         Arguments:
797
798         Return Value:
799                 TRUE                    found matched tuple cache
800                 FALSE                   no matched found
801
802         Note:
803
804         ========================================================================
805 */
806 #define fRTMP_ADAPTER_NEED_STOP_RX              \
807                 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
808                  fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
809                  fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
810
811 #define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX       \
812                 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
813                  fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
814                  fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
815
816 VOID    RTUSBBulkReceive(
817         IN      PRTMP_ADAPTER   pAd)
818 {
819         PRX_CONTEXT             pRxContext;
820         unsigned long   IrqFlags;
821
822
823         /* sanity check */
824         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
825                 return;
826
827         while(1)
828         {
829
830                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
831                 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
832                 if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
833                         (pRxContext->bRxHandling == FALSE))
834                 {
835                         pRxContext->bRxHandling = TRUE;
836                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
837
838                         // read RxContext, Since not
839                         STARxDoneInterruptHandle(pAd, TRUE);
840
841                         // Finish to handle this bulkIn buffer.
842                         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
843                         pRxContext->BulkInOffset = 0;
844                         pRxContext->Readable = FALSE;
845                         pRxContext->bRxHandling = FALSE;
846                         pAd->ReadPosition = 0;
847                         pAd->TransferBufferLength = 0;
848                         INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
849                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
850
851                 }
852                 else
853                 {
854                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
855                         break;
856                 }
857         }
858
859         if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
860                 DoBulkIn(pAd);
861
862 }
863
864
865 /*
866         ========================================================================
867
868         Routine Description:
869                 This routine process Rx Irp and call rx complete function.
870
871         Arguments:
872                 DeviceObject    Pointer to the device object for next lower
873                                                 device. DeviceObject passed in here belongs to
874                                                 the next lower driver in the stack because we
875                                                 were invoked via IoCallDriver in USB_RxPacket
876                                                 AND it is not OUR device object
877           Irp                           Ptr to completed IRP
878           Context                       Ptr to our Adapter object (context specified
879                                                 in IoSetCompletionRoutine
880
881         Return Value:
882                 Always returns STATUS_MORE_PROCESSING_REQUIRED
883
884         Note:
885                 Always returns STATUS_MORE_PROCESSING_REQUIRED
886         ========================================================================
887 */
888 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
889 {
890         // use a receive tasklet to handle received packets;
891         // or sometimes hardware IRQ will be disabled here, so we can not
892         // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
893         PRX_CONTEXT             pRxContext;
894         PRTMP_ADAPTER   pAd;
895         POS_COOKIE              pObj;
896
897
898         pRxContext      = (PRX_CONTEXT)pUrb->context;
899         pAd             = pRxContext->pAd;
900         pObj            = (POS_COOKIE) pAd->OS_Cookie;
901
902         pObj->rx_done_task.data = (unsigned long)pUrb;
903         tasklet_hi_schedule(&pObj->rx_done_task);
904
905 }
906
907
908
909 /*
910         ========================================================================
911
912         Routine Description:
913
914         Arguments:
915
916         Return Value:
917
918         Note:
919
920         ========================================================================
921 */
922 VOID    RTUSBKickBulkOut(
923         IN      PRTMP_ADAPTER pAd)
924 {
925         // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
926         if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
927                 )
928         {
929                 // 2. PS-Poll frame is next
930                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
931                 {
932                         RTUSBBulkOutPsPoll(pAd);
933                 }
934
935                 // 5. Mlme frame is next
936                 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
937                                  (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
938                 {
939                         RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
940                 }
941
942                 // 6. Data frame normal is next
943                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
944                 {
945                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
946                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
947                                 ))
948                         {
949                                 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
950                         }
951                 }
952                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
953                 {
954                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
955                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
956                                 ))
957                         {
958                                 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
959                         }
960                 }
961                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
962                 {
963                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
964                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
965                                 ))
966                         {
967                                 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
968                         }
969                 }
970                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
971                 {
972                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
973                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
974                                 ))
975                         {
976                                 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
977                         }
978                 }
979 #ifdef RT30xx
980                 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
981                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5))
982                 {
983                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
984                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
985                                 ))
986                         {
987                         }
988                 }
989 #endif
990
991                 // 7. Null frame is the last
992                 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
993                 {
994                         if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
995                         {
996                                 RTUSBBulkOutNullFrame(pAd);
997                         }
998                 }
999
1000                 // 8. No data avaliable
1001                 else
1002                 {
1003
1004                 }
1005         }
1006 }
1007
1008 /*
1009         ========================================================================
1010
1011         Routine Description:
1012         Call from Reset action after BulkOut failed.
1013         Arguments:
1014
1015         Return Value:
1016
1017         Note:
1018
1019         ========================================================================
1020 */
1021 VOID    RTUSBCleanUpDataBulkOutQueue(
1022         IN      PRTMP_ADAPTER   pAd)
1023 {
1024         UCHAR                   Idx;
1025         PHT_TX_CONTEXT  pTxContext;
1026
1027         DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1028
1029         for (Idx = 0; Idx < 4; Idx++)
1030         {
1031                 pTxContext = &pAd->TxContext[Idx];
1032
1033                 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1034                 pTxContext->LastOne = FALSE;
1035                 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1036                 pAd->BulkOutPending[Idx] = FALSE;
1037                 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1038         }
1039
1040         DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1041 }
1042
1043 /*
1044         ========================================================================
1045
1046         Routine Description:
1047
1048         Arguments:
1049
1050         Return Value:
1051
1052         Note:
1053
1054         ========================================================================
1055 */
1056 VOID    RTUSBCleanUpMLMEBulkOutQueue(
1057         IN      PRTMP_ADAPTER   pAd)
1058 {
1059         DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
1060         DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1061 }
1062
1063
1064 /*
1065         ========================================================================
1066
1067         Routine Description:
1068
1069         Arguments:
1070
1071         Return Value:
1072
1073
1074         Note:
1075
1076         ========================================================================
1077 */
1078 VOID    RTUSBCancelPendingIRPs(
1079         IN      PRTMP_ADAPTER   pAd)
1080 {
1081         RTUSBCancelPendingBulkInIRP(pAd);
1082         RTUSBCancelPendingBulkOutIRP(pAd);
1083 }
1084
1085 /*
1086         ========================================================================
1087
1088         Routine Description:
1089
1090         Arguments:
1091
1092         Return Value:
1093
1094         Note:
1095
1096         ========================================================================
1097 */
1098 VOID    RTUSBCancelPendingBulkInIRP(
1099         IN      PRTMP_ADAPTER   pAd)
1100 {
1101         PRX_CONTEXT             pRxContext;
1102         UINT                    i;
1103
1104         DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
1105         for ( i = 0; i < (RX_RING_SIZE); i++)
1106         {
1107                 pRxContext = &(pAd->RxContext[i]);
1108                 if(pRxContext->IRPPending == TRUE)
1109                 {
1110                         RTUSB_UNLINK_URB(pRxContext->pUrb);
1111                         pRxContext->IRPPending = FALSE;
1112                         pRxContext->InUse = FALSE;
1113                         //NdisInterlockedDecrement(&pAd->PendingRx);
1114                         //pAd->PendingRx--;
1115                 }
1116         }
1117         DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1118 }
1119
1120
1121 /*
1122         ========================================================================
1123
1124         Routine Description:
1125
1126         Arguments:
1127
1128         Return Value:
1129
1130         Note:
1131
1132         ========================================================================
1133 */
1134 VOID    RTUSBCancelPendingBulkOutIRP(
1135         IN      PRTMP_ADAPTER   pAd)
1136 {
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;
1143         UINT                            i, Idx;
1144 //      unsigned int            IrqFlags;
1145 //      NDIS_SPIN_LOCK          *pLock;
1146 //      BOOLEAN                         *pPending;
1147
1148
1149 //      pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
1150 //      pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
1151
1152         for (Idx = 0; Idx < 4; Idx++)
1153         {
1154                 pHTTXContext = &(pAd->TxContext[Idx]);
1155
1156                 if (pHTTXContext->IRPPending == TRUE)
1157                 {
1158
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
1162                         //
1163
1164                         RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1165
1166                         // Sleep 200 microseconds to give cancellation time to work
1167                         RTMPusecDelay(200);
1168                 }
1169
1170                 pAd->BulkOutPending[Idx] = FALSE;
1171         }
1172
1173         //RTMP_IRQ_LOCK(pLock, IrqFlags);
1174         for (i = 0; i < MGMT_RING_SIZE; i++)
1175         {
1176                 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
1177                 if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
1178                 {
1179
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
1183                         //
1184
1185                         RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1186                         pMLMEContext->IRPPending = FALSE;
1187
1188                         // Sleep 200 microsecs to give cancellation time to work
1189                         RTMPusecDelay(200);
1190                 }
1191         }
1192         pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1193         //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
1194
1195
1196         for (i = 0; i < BEACON_RING_SIZE; i++)
1197         {
1198                 pBeaconContext = &(pAd->BeaconContext[i]);
1199
1200                 if(pBeaconContext->IRPPending == TRUE)
1201                 {
1202
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
1206                         //
1207
1208                         RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1209
1210                         // Sleep 200 microsecs to give cancellation time to work
1211                         RTMPusecDelay(200);
1212                 }
1213         }
1214
1215         pNullContext = &(pAd->NullContext);
1216         if (pNullContext->IRPPending == TRUE)
1217                 RTUSB_UNLINK_URB(pNullContext->pUrb);
1218
1219         pRTSContext = &(pAd->RTSContext);
1220         if (pRTSContext->IRPPending == TRUE)
1221                 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1222
1223         pPsPollContext = &(pAd->PsPollContext);
1224         if (pPsPollContext->IRPPending == TRUE)
1225                 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1226
1227         for (Idx = 0; Idx < 4; Idx++)
1228         {
1229                 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1230                 pAd->BulkOutPending[Idx] = FALSE;
1231                 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1232         }
1233 }
1234