Staging: rt3070: remove dead CONFIG_AP_SUPPORT code
[linux-2.6] / drivers / staging / rt3070 / 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
291                         else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))*/)
292                         {
293                                 // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
294                                 // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
295                                 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
296                                 break;
297                         }
298                 }
299                 // end Iverson
300                 else
301                 {
302                         if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
303                         {       // Limit BulkOut size to about 24k bytes.
304                                 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
305                                 break;
306                         }
307
308                         else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))*/)
309                         {       // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
310                                 // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
311                                 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
312                                 break;
313                         }
314                 }
315
316                 if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
317                 {
318                         pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
319                         break;
320                 }
321                 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
322                 {
323                 if (pTxInfo->QSEL != FIFO_EDCA)
324                 {
325                         printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL);
326                         printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
327                         hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
328                 }
329                 }
330
331                 if (pTxInfo->USBDMATxPktLen <= 8)
332                 {
333                         BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
334                         DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
335                                         pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
336                         {
337                                 DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x  %x  %x  %x  %x  %x  %x  %x \n",
338                                         pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
339                                         ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
340                         }
341                         pAd->bForcePrintTX = TRUE;
342                         BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
343                         pAd->BulkOutPending[BulkOutPipeId] = FALSE;
344                         BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
345                         //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
346                         return;
347                 }
348
349                         // Increase Total transmit byte counter
350                 pAd->RalinkCounters.OneSecTransmittedByteCount +=  pTxWI->MPDUtotalByteCount;
351                 pAd->RalinkCounters.TransmittedByteCount +=  pTxWI->MPDUtotalByteCount;
352
353                 pLastTxInfo = pTxInfo;
354
355                 // Make sure we use EDCA QUEUE.
356                 pTxInfo->QSEL = FIFO_EDCA; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
357                 ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
358                 TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
359
360                 if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
361                         pTxInfo->USBDMANextVLD = 1;
362
363                 if (pTxInfo->SwUseLastRound == 1)
364                 {
365                         if (pHTTXContext->CurWritePosition == 8)
366                                 pTxInfo->USBDMANextVLD = 0;
367                         pTxInfo->SwUseLastRound = 0;
368
369                         bTxQLastRound = TRUE;
370                         pHTTXContext->ENextBulkOutPosition = 8;
371
372                         break;
373                 }
374         }while (TRUE);
375
376         // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
377         if (pLastTxInfo)
378         {
379                 pLastTxInfo->USBDMANextVLD = 0;
380         }
381
382         /*
383                 We need to copy SavedPad when following condition matched!
384                         1. Not the last round of the TxQueue and
385                         2. any match of following cases:
386                                 (1). The End Position of this bulk out is reach to the Currenct Write position and
387                                                 the TxInfo and related header already write to the CurWritePosition.
388                                         =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
389
390                                 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
391                                         =>(ENextBulkOutPosition != CurWritePosition)
392         */
393         if ((bTxQLastRound == FALSE) &&
394                  (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
395                   (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
396                 )
397         {
398                 NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
399                 pHTTXContext->bCopySavePad = TRUE;
400                 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
401                 {
402                         PUCHAR  pBuf = &pHTTXContext->SavedPad[0];
403                         DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
404                                 pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
405                                 pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
406
407                         pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
408                         DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7]));
409                 }
410                 //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
411         }
412
413         if (pAd->bForcePrintTX == TRUE)
414                 DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
415         //DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));
416
417                 // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
418         pAppendant = &pWirelessPkt[TmpBulkEndPos];
419         NdisZeroMemory(pAppendant, 8);
420                 ThisBulkSize += 4;
421                 pHTTXContext->LastOne = TRUE;
422                 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
423                         ThisBulkSize += 4;
424         pHTTXContext->BulkOutSize = ThisBulkSize;
425
426         pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
427         BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
428
429         // Init Tx context descriptor
430         RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
431
432         pUrb = pHTTXContext->pUrb;
433         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
434         {
435                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
436
437                 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
438                 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
439                 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
440                 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
441
442                 return;
443         }
444
445         BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
446         pHTTXContext->IRPPending = TRUE;
447         BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
448         pAd->BulkOutReq++;
449
450 }
451
452
453 VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
454 {
455         PHT_TX_CONTEXT  pHTTXContext;
456         PRTMP_ADAPTER   pAd;
457         POS_COOKIE              pObj;
458         UCHAR                   BulkOutPipeId;
459
460
461         pHTTXContext    = (PHT_TX_CONTEXT)pUrb->context;
462         pAd                     = pHTTXContext->pAd;
463         pObj                    = (POS_COOKIE) pAd->OS_Cookie;
464
465         // Store BulkOut PipeId
466         BulkOutPipeId   = pHTTXContext->BulkOutPipeId;
467         pAd->BulkOutDataOneSecCount++;
468
469         switch (BulkOutPipeId)
470         {
471                 case 0:
472                                 pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
473                                 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
474                                 break;
475                 case 1:
476                                 pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
477                                 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
478                                 break;
479                 case 2:
480                                 pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
481                                 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
482                                 break;
483                 case 3:
484                                 pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
485                                 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
486                                 break;
487                 case 4:
488                                 pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
489                                 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
490                                 break;
491         }
492 }
493
494
495 /*
496         ========================================================================
497
498         Routine Description:
499
500         Arguments:
501
502         Return Value:
503
504         Note: NULL frame use BulkOutPipeId = 0
505
506         ========================================================================
507 */
508 VOID    RTUSBBulkOutNullFrame(
509         IN      PRTMP_ADAPTER   pAd)
510 {
511         PTX_CONTEXT             pNullContext = &(pAd->NullContext);
512         PURB                    pUrb;
513         int                             ret = 0;
514         unsigned long   IrqFlags;
515
516         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
517         if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
518         {
519                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
520                 return;
521         }
522         pAd->BulkOutPending[0] = TRUE;
523         pAd->watchDogTxPendingCnt[0] = 1;
524         pNullContext->IRPPending = TRUE;
525         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
526
527         // Increase Total transmit byte counter
528         pAd->RalinkCounters.TransmittedByteCount +=  pNullContext->BulkOutSize;
529
530
531         // Clear Null frame bulk flag
532         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
533
534         // Init Tx context descriptor
535         RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
536
537         pUrb = pNullContext->pUrb;
538         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
539         {
540                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
541                 pAd->BulkOutPending[0] = FALSE;
542                 pAd->watchDogTxPendingCnt[0] = 0;
543                 pNullContext->IRPPending = FALSE;
544                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
545
546                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
547                 return;
548         }
549
550 }
551
552 // NULL frame use BulkOutPipeId = 0
553 VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
554 {
555         PRTMP_ADAPTER           pAd;
556         PTX_CONTEXT                     pNullContext;
557         NTSTATUS                        Status;
558         POS_COOKIE                      pObj;
559
560
561         pNullContext    = (PTX_CONTEXT)pUrb->context;
562         pAd                     = pNullContext->pAd;
563         Status                  = pUrb->status;
564
565         pObj = (POS_COOKIE) pAd->OS_Cookie;
566         pObj->null_frame_complete_task.data = (unsigned long)pUrb;
567         tasklet_hi_schedule(&pObj->null_frame_complete_task);
568
569 }
570
571 /*
572         ========================================================================
573
574         Routine Description:
575
576         Arguments:
577
578         Return Value:
579
580         Note: MLME use BulkOutPipeId = 0
581
582         ========================================================================
583 */
584 VOID    RTUSBBulkOutMLMEPacket(
585         IN      PRTMP_ADAPTER   pAd,
586         IN      UCHAR                   Index)
587 {
588         PTX_CONTEXT             pMLMEContext;
589         PURB                    pUrb;
590         int                             ret = 0;
591         unsigned long   IrqFlags;
592
593         pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
594         pUrb = pMLMEContext->pUrb;
595
596         if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
597                 (pMLMEContext->InUse == FALSE) ||
598                 (pMLMEContext->bWaitingBulkOut == FALSE))
599         {
600
601
602                 // Clear MLME bulk flag
603                 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
604
605                 return;
606         }
607
608
609         RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
610         if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
611         {
612                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
613                 return;
614         }
615
616         pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
617         pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
618         pMLMEContext->IRPPending = TRUE;
619         pMLMEContext->bWaitingBulkOut = FALSE;
620         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
621
622         // Increase Total transmit byte counter
623         pAd->RalinkCounters.TransmittedByteCount +=  pMLMEContext->BulkOutSize;
624
625         // Clear MLME bulk flag
626         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
627
628         // Init Tx context descriptor
629         RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
630
631         //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
632         pUrb->transfer_dma      = 0;
633         pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
634
635         pUrb = pMLMEContext->pUrb;
636         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
637         {
638                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
639                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
640                 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
641                 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
642                 pMLMEContext->IRPPending = FALSE;
643                 pMLMEContext->bWaitingBulkOut = TRUE;
644                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
645
646                 return;
647         }
648
649         //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
650 //      printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
651 }
652
653
654 VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
655 {
656         PTX_CONTEXT                     pMLMEContext;
657         PRTMP_ADAPTER           pAd;
658         NTSTATUS                        Status;
659         POS_COOKIE                      pObj;
660         int                                     index;
661
662         //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
663         pMLMEContext    = (PTX_CONTEXT)pUrb->context;
664         pAd                     = pMLMEContext->pAd;
665         pObj                    = (POS_COOKIE)pAd->OS_Cookie;
666         Status                  = pUrb->status;
667         index                   = pMLMEContext->SelfIdx;
668
669         pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
670         tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
671 }
672
673
674 /*
675         ========================================================================
676
677         Routine Description:
678
679         Arguments:
680
681         Return Value:
682
683         Note: PsPoll use BulkOutPipeId = 0
684
685         ========================================================================
686 */
687 VOID    RTUSBBulkOutPsPoll(
688         IN      PRTMP_ADAPTER   pAd)
689 {
690         PTX_CONTEXT             pPsPollContext = &(pAd->PsPollContext);
691         PURB                    pUrb;
692         int                             ret = 0;
693         unsigned long   IrqFlags;
694
695         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
696         if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
697         {
698                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
699                 return;
700         }
701         pAd->BulkOutPending[0] = TRUE;
702         pAd->watchDogTxPendingCnt[0] = 1;
703         pPsPollContext->IRPPending = TRUE;
704         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
705
706
707         // Clear PS-Poll bulk flag
708         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
709
710         // Init Tx context descriptor
711         RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
712
713         pUrb = pPsPollContext->pUrb;
714         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
715         {
716                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
717                 pAd->BulkOutPending[0] = FALSE;
718                 pAd->watchDogTxPendingCnt[0] = 0;
719                 pPsPollContext->IRPPending = FALSE;
720                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
721
722                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
723                 return;
724         }
725
726 }
727
728 // PS-Poll frame use BulkOutPipeId = 0
729 VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
730 {
731         PRTMP_ADAPTER           pAd;
732         PTX_CONTEXT                     pPsPollContext;
733         NTSTATUS                        Status;
734         POS_COOKIE                      pObj;
735
736
737         pPsPollContext= (PTX_CONTEXT)pUrb->context;
738         pAd = pPsPollContext->pAd;
739         Status = pUrb->status;
740         pObj = (POS_COOKIE) pAd->OS_Cookie;
741         pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
742         tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
743
744 }
745
746 VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
747 {
748         PRX_CONTEXT             pRxContext;
749         PURB                    pUrb;
750         int                             ret = 0;
751         unsigned long   IrqFlags;
752
753         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
754         pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
755         if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
756         {
757                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
758                 return;
759         }
760         pRxContext->InUse = TRUE;
761         pRxContext->IRPPending = TRUE;
762         pAd->PendingRx++;
763         pAd->BulkInReq++;
764         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
765
766         // Init Rx context descriptor
767         NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
768         RTUSBInitRxDesc(pAd, pRxContext);
769
770         pUrb = pRxContext->pUrb;
771         if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
772         {       // fail
773
774                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
775                 pRxContext->InUse = FALSE;
776                 pRxContext->IRPPending = FALSE;
777                 pAd->PendingRx--;
778                 pAd->BulkInReq--;
779                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
780                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
781         }
782         else
783         {       // success
784                 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
785                 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
786         }
787 }
788
789
790 /*
791         ========================================================================
792
793         Routine Description:
794         USB_RxPacket initializes a URB and uses the Rx IRP to submit it
795         to USB. It checks if an Rx Descriptor is available and passes the
796         the coresponding buffer to be filled. If no descriptor is available
797         fails the request. When setting the completion routine we pass our
798         Adapter Object as Context.
799
800         Arguments:
801
802         Return Value:
803                 TRUE                    found matched tuple cache
804                 FALSE                   no matched found
805
806         Note:
807
808         ========================================================================
809 */
810 #define fRTMP_ADAPTER_NEED_STOP_RX              \
811                 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
812                  fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
813                  fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
814
815 #define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX       \
816                 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
817                  fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
818                  fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
819
820 VOID    RTUSBBulkReceive(
821         IN      PRTMP_ADAPTER   pAd)
822 {
823         PRX_CONTEXT             pRxContext;
824         unsigned long   IrqFlags;
825
826
827         /* sanity check */
828         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
829                 return;
830
831         while(1)
832         {
833
834                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
835                 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
836                 if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
837                         (pRxContext->bRxHandling == FALSE))
838                 {
839                         pRxContext->bRxHandling = TRUE;
840                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
841
842                         // read RxContext, Since not
843                         STARxDoneInterruptHandle(pAd, TRUE);
844
845                         // Finish to handle this bulkIn buffer.
846                         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
847                         pRxContext->BulkInOffset = 0;
848                         pRxContext->Readable = FALSE;
849                         pRxContext->bRxHandling = FALSE;
850                         pAd->ReadPosition = 0;
851                         pAd->TransferBufferLength = 0;
852                         INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
853                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
854
855                 }
856                 else
857                 {
858                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
859                         break;
860                 }
861         }
862
863         if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
864                 DoBulkIn(pAd);
865
866 }
867
868
869 /*
870         ========================================================================
871
872         Routine Description:
873                 This routine process Rx Irp and call rx complete function.
874
875         Arguments:
876                 DeviceObject    Pointer to the device object for next lower
877                                                 device. DeviceObject passed in here belongs to
878                                                 the next lower driver in the stack because we
879                                                 were invoked via IoCallDriver in USB_RxPacket
880                                                 AND it is not OUR device object
881           Irp                           Ptr to completed IRP
882           Context                       Ptr to our Adapter object (context specified
883                                                 in IoSetCompletionRoutine
884
885         Return Value:
886                 Always returns STATUS_MORE_PROCESSING_REQUIRED
887
888         Note:
889                 Always returns STATUS_MORE_PROCESSING_REQUIRED
890         ========================================================================
891 */
892 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
893 {
894         // use a receive tasklet to handle received packets;
895         // or sometimes hardware IRQ will be disabled here, so we can not
896         // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
897         PRX_CONTEXT             pRxContext;
898         PRTMP_ADAPTER   pAd;
899         POS_COOKIE              pObj;
900
901
902         pRxContext      = (PRX_CONTEXT)pUrb->context;
903         pAd             = pRxContext->pAd;
904         pObj            = (POS_COOKIE) pAd->OS_Cookie;
905
906         pObj->rx_done_task.data = (unsigned long)pUrb;
907         tasklet_hi_schedule(&pObj->rx_done_task);
908
909 }
910
911 /*
912         ========================================================================
913
914         Routine Description:
915
916         Arguments:
917
918         Return Value:
919
920         Note:
921
922         ========================================================================
923 */
924 VOID    RTUSBKickBulkOut(
925         IN      PRTMP_ADAPTER pAd)
926 {
927         // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
928         if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
929                 )
930         {
931                 // 2. PS-Poll frame is next
932                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
933                 {
934                         RTUSBBulkOutPsPoll(pAd);
935                 }
936
937                 // 5. Mlme frame is next
938                 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
939                                  (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
940                 {
941                         RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
942                 }
943
944                 // 6. Data frame normal is next
945                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
946                 {
947                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
948                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
949                                 ))
950                         {
951                                 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
952                         }
953                 }
954                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
955                 {
956                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
957                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
958                                 ))
959                         {
960                                 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
961                         }
962                 }
963                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
964                 {
965                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
966                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
967                                 ))
968                         {
969                                 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
970                         }
971                 }
972                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
973                 {
974                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
975                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
976                                 ))
977                         {
978                                 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
979                         }
980                 }
981                 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
982                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5))
983                 {
984                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
985                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
986                                 ))
987                         {
988                         }
989                 }
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