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