]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/staging/rt2870/common/rtusb_bulk.c
a45f64810dce9017a6d5b16294a6694c90ff4d81
[net-next-2.6.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 UCHAR 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(IN PRTMP_ADAPTER pAd,
62                      IN PTX_CONTEXT pTxContext,
63                      IN UCHAR BulkOutPipeId, 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                 pSrc = &pTxContext->TransferBuffer->Aggregation[2];
77         } else {
78                 pSrc =
79                     (PUCHAR) 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(IN PRTMP_ADAPTER pAd,
100                        IN PHT_TX_CONTEXT pTxContext,
101                        IN UCHAR BulkOutPipeId,
102                        IN ULONG BulkOutSize, IN usb_complete_t Func)
103 {
104         PURB pUrb;
105         PUCHAR pSrc = NULL;
106         POS_COOKIE pObj = (POS_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(IN PRTMP_ADAPTER pAd, IN PRX_CONTEXT pRxContext)
132 {
133         PURB pUrb;
134         POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
135         ULONG 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(IN PRTMP_ADAPTER pAd,
183                             IN UCHAR BulkOutPipeId, IN UCHAR Index)
184 {
185
186         PHT_TX_CONTEXT pHTTXContext;
187         PURB pUrb;
188         int ret = 0;
189         PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL;
190         PTXWI_STRUC pTxWI;
191         ULONG TmpBulkEndPos, ThisBulkSize;
192         unsigned long IrqFlags = 0, IrqFlags2 = 0;
193         PUCHAR pWirelessPkt, pAppendant;
194         BOOLEAN bTxQLastRound = FALSE;
195         UCHAR 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 = (PTXINFO_STRUC) & pWirelessPkt[TmpBulkEndPos];
277                 pTxWI =
278                     (PTXWI_STRUC) & 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                                   __FUNCTION__, 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                                  (PUCHAR) & 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         /*
409            We need to copy SavedPad when following condition matched!
410            1. Not the last round of the TxQueue and
411            2. any match of following cases:
412            (1). The End Position of this bulk out is reach to the Currenct Write position and
413            the TxInfo and related header already write to the CurWritePosition.
414            =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
415
416            (2). The EndPosition of the bulk out is not reach to the Current Write Position.
417            =>(ENextBulkOutPosition != CurWritePosition)
418          */
419         if ((bTxQLastRound == FALSE) &&
420             (((pHTTXContext->ENextBulkOutPosition ==
421                pHTTXContext->CurWritePosition)
422               && (pHTTXContext->CurWriteRealPos >
423                   pHTTXContext->CurWritePosition))
424              || (pHTTXContext->ENextBulkOutPosition !=
425                  pHTTXContext->CurWritePosition))
426             ) {
427                 NdisMoveMemory(pHTTXContext->SavedPad,
428                                &pWirelessPkt[pHTTXContext->
429                                              ENextBulkOutPosition], 8);
430                 pHTTXContext->bCopySavePad = TRUE;
431                 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) {
432                         PUCHAR pBuf = &pHTTXContext->SavedPad[0];
433                         DBGPRINT_RAW(RT_DEBUG_ERROR,
434                                      ("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
435                                       pBuf[0], pBuf[1], pBuf[2], pBuf[3],
436                                       pBuf[4], pBuf[5], pBuf[6], pBuf[7],
437                                       pHTTXContext->CurWritePosition,
438                                       pHTTXContext->CurWriteRealPos,
439                                       pHTTXContext->bCurWriting,
440                                       pHTTXContext->NextBulkOutPosition,
441                                       TmpBulkEndPos, ThisBulkSize));
442
443                         pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
444                         DBGPRINT_RAW(RT_DEBUG_ERROR,
445                                      ("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n",
446                                       pBuf[0], pBuf[1], pBuf[2], pBuf[3],
447                                       pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
448                 }
449                 /*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad)); */
450         }
451
452         if (pAd->bForcePrintTX == TRUE)
453                 DBGPRINT(RT_DEBUG_TRACE,
454                          ("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n",
455                           ThisBulkSize, pHTTXContext->CurWritePosition,
456                           pHTTXContext->NextBulkOutPosition,
457                           pHTTXContext->ENextBulkOutPosition,
458                           pHTTXContext->bCopySavePad));
459         /*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)); */
460
461         /* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize. */
462         pAppendant = &pWirelessPkt[TmpBulkEndPos];
463         NdisZeroMemory(pAppendant, 8);
464         ThisBulkSize += 4;
465         pHTTXContext->LastOne = TRUE;
466         if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
467                 ThisBulkSize += 4;
468         pHTTXContext->BulkOutSize = ThisBulkSize;
469
470         pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
471         BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
472
473         /* Init Tx context descriptor */
474         RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize,
475                           (usb_complete_t) RTUSBBulkOutDataPacketComplete);
476
477         pUrb = pHTTXContext->pUrb;
478         if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 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(purbb_t pUrb, struct pt_regs * pt_regs)
499 {
500         PHT_TX_CONTEXT pHTTXContext;
501         PRTMP_ADAPTER pAd;
502         POS_COOKIE pObj;
503         UCHAR BulkOutPipeId;
504
505         pHTTXContext = (PHT_TX_CONTEXT) pUrb->context;
506         pAd = pHTTXContext->pAd;
507         pObj = (POS_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(IN PRTMP_ADAPTER pAd)
548 {
549         PTX_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         if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {
577                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
578                 pAd->BulkOutPending[0] = FALSE;
579                 pAd->watchDogTxPendingCnt[0] = 0;
580                 pNullContext->IRPPending = FALSE;
581                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
582
583                 DBGPRINT(RT_DEBUG_ERROR,
584                          ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n",
585                           ret));
586                 return;
587         }
588
589 }
590
591 /* NULL frame use BulkOutPipeId = 0 */
592 VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs * pt_regs)
593 {
594         PRTMP_ADAPTER pAd;
595         PTX_CONTEXT pNullContext;
596         NTSTATUS Status;
597         POS_COOKIE pObj;
598
599         pNullContext = (PTX_CONTEXT) pUrb->context;
600         pAd = pNullContext->pAd;
601         Status = pUrb->status;
602
603         pObj = (POS_COOKIE) pAd->OS_Cookie;
604         pObj->null_frame_complete_task.data = (unsigned long)pUrb;
605         tasklet_hi_schedule(&pObj->null_frame_complete_task);
606 }
607
608 /*
609         ========================================================================
610
611         Routine Description:
612
613         Arguments:
614
615         Return Value:
616
617         Note: MLME use BulkOutPipeId = 0
618
619         ========================================================================
620 */
621 VOID RTUSBBulkOutMLMEPacket(IN PRTMP_ADAPTER pAd, IN UCHAR Index)
622 {
623         PTX_CONTEXT pMLMEContext;
624         PURB pUrb;
625         int ret = 0;
626         unsigned long IrqFlags;
627
628         pMLMEContext =
629             (PTX_CONTEXT) pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
630         pUrb = pMLMEContext->pUrb;
631
632         if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
633             (pMLMEContext->InUse == FALSE) ||
634             (pMLMEContext->bWaitingBulkOut == FALSE)) {
635
636                 /* Clear MLME bulk flag */
637                 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
638
639                 return;
640         }
641
642         RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
643         if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE)
644             || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
645                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
646                 return;
647         }
648
649         pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
650         pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
651         pMLMEContext->IRPPending = TRUE;
652         pMLMEContext->bWaitingBulkOut = FALSE;
653         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
654
655         /* Increase Total transmit byte counter */
656         pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
657
658         /* Clear MLME bulk flag */
659         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
660
661         /* Init Tx context descriptor */
662         RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX,
663                         (usb_complete_t) RTUSBBulkOutMLMEPacketComplete);
664
665         /*For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping. */
666         pUrb->transfer_dma = 0;
667         pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
668
669         pUrb = pMLMEContext->pUrb;
670         if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {
671                 DBGPRINT(RT_DEBUG_ERROR,
672                          ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n",
673                           ret));
674                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
675                 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
676                 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
677                 pMLMEContext->IRPPending = FALSE;
678                 pMLMEContext->bWaitingBulkOut = TRUE;
679                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
680
681                 return;
682         }
683         /*DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n")); */
684 /*      printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx); */
685 }
686
687 VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs * pt_regs)
688 {
689         PTX_CONTEXT pMLMEContext;
690         PRTMP_ADAPTER pAd;
691         NTSTATUS Status;
692         POS_COOKIE pObj;
693         int index;
694
695         /*DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n")); */
696         pMLMEContext = (PTX_CONTEXT) pUrb->context;
697         pAd = pMLMEContext->pAd;
698         pObj = (POS_COOKIE) pAd->OS_Cookie;
699         Status = pUrb->status;
700         index = pMLMEContext->SelfIdx;
701
702         pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
703         tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
704 }
705
706 /*
707         ========================================================================
708
709         Routine Description:
710
711         Arguments:
712
713         Return Value:
714
715         Note: PsPoll use BulkOutPipeId = 0
716
717         ========================================================================
718 */
719 VOID RTUSBBulkOutPsPoll(IN PRTMP_ADAPTER pAd)
720 {
721         PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
722         PURB pUrb;
723         int ret = 0;
724         unsigned long IrqFlags;
725
726         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
727         if ((pAd->BulkOutPending[0] == TRUE)
728             || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
729                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
730                 return;
731         }
732         pAd->BulkOutPending[0] = TRUE;
733         pAd->watchDogTxPendingCnt[0] = 1;
734         pPsPollContext->IRPPending = TRUE;
735         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
736
737         /* Clear PS-Poll bulk flag */
738         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
739
740         /* Init Tx context descriptor */
741         RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX,
742                         (usb_complete_t) RTUSBBulkOutPsPollComplete);
743
744         pUrb = pPsPollContext->pUrb;
745         if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {
746                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
747                 pAd->BulkOutPending[0] = FALSE;
748                 pAd->watchDogTxPendingCnt[0] = 0;
749                 pPsPollContext->IRPPending = FALSE;
750                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
751
752                 DBGPRINT(RT_DEBUG_ERROR,
753                          ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n",
754                           ret));
755                 return;
756         }
757
758 }
759
760 /* PS-Poll frame use BulkOutPipeId = 0 */
761 VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb, struct pt_regs * pt_regs)
762 {
763         PRTMP_ADAPTER pAd;
764         PTX_CONTEXT pPsPollContext;
765         NTSTATUS Status;
766         POS_COOKIE pObj;
767
768         pPsPollContext = (PTX_CONTEXT) pUrb->context;
769         pAd = pPsPollContext->pAd;
770         Status = pUrb->status;
771
772         pObj = (POS_COOKIE) pAd->OS_Cookie;
773         pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
774         tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
775 }
776
777 VOID DoBulkIn(IN RTMP_ADAPTER * pAd)
778 {
779         PRX_CONTEXT pRxContext;
780         PURB pUrb;
781         int ret = 0;
782         unsigned long IrqFlags;
783
784         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
785         pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
786         if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE)
787             || (pRxContext->InUse == TRUE)) {
788                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
789                 return;
790         }
791         pRxContext->InUse = TRUE;
792         pRxContext->IRPPending = TRUE;
793         pAd->PendingRx++;
794         pAd->BulkInReq++;
795         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
796
797         /* Init Rx context descriptor */
798         NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
799         RTUSBInitRxDesc(pAd, pRxContext);
800
801         pUrb = pRxContext->pUrb;
802         if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {      /* fail */
803
804                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
805                 pRxContext->InUse = FALSE;
806                 pRxContext->IRPPending = FALSE;
807                 pAd->PendingRx--;
808                 pAd->BulkInReq--;
809                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
810                 DBGPRINT(RT_DEBUG_ERROR,
811                          ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
812         } else {                /* success */
813                 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
814                 /*printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex); */
815         }
816 }
817
818 /*
819         ========================================================================
820
821         Routine Description:
822         USB_RxPacket initializes a URB and uses the Rx IRP to submit it
823         to USB. It checks if an Rx Descriptor is available and passes the
824         the coresponding buffer to be filled. If no descriptor is available
825         fails the request. When setting the completion routine we pass our
826         Adapter Object as Context.
827
828         Arguments:
829
830         Return Value:
831                 TRUE                    found matched tuple cache
832                 FALSE                   no matched found
833
834         Note:
835
836         ========================================================================
837 */
838 #define fRTMP_ADAPTER_NEED_STOP_RX              \
839                 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
840                  fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
841                  fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
842
843 #define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX       \
844                 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
845                  fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
846                  fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
847
848 VOID RTUSBBulkReceive(IN PRTMP_ADAPTER pAd)
849 {
850         PRX_CONTEXT pRxContext;
851         unsigned long IrqFlags;
852
853         /* sanity check */
854         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
855                 return;
856
857         while (1) {
858
859                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
860                 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
861                 if (((pRxContext->InUse == FALSE)
862                      && (pRxContext->Readable == TRUE))
863                     && (pRxContext->bRxHandling == FALSE)) {
864                         pRxContext->bRxHandling = TRUE;
865                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
866
867                         /* read RxContext, Since not */
868                         STARxDoneInterruptHandle(pAd, TRUE);
869
870                         /* Finish to handle this bulkIn buffer. */
871                         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
872                         pRxContext->BulkInOffset = 0;
873                         pRxContext->Readable = FALSE;
874                         pRxContext->bRxHandling = FALSE;
875                         pAd->ReadPosition = 0;
876                         pAd->TransferBufferLength = 0;
877                         INC_RING_INDEX(pAd->NextRxBulkInReadIndex,
878                                        RX_RING_SIZE);
879                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
880
881                 } else {
882                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
883                         break;
884                 }
885         }
886
887         if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
888                 DoBulkIn(pAd);
889
890 }
891
892 /*
893         ========================================================================
894
895         Routine Description:
896                 This routine process Rx Irp and call rx complete function.
897
898         Arguments:
899                 DeviceObject    Pointer to the device object for next lower
900                                                 device. DeviceObject passed in here belongs to
901                                                 the next lower driver in the stack because we
902                                                 were invoked via IoCallDriver in USB_RxPacket
903                                                 AND it is not OUR device object
904           Irp                           Ptr to completed IRP
905           Context                       Ptr to our Adapter object (context specified
906                                                 in IoSetCompletionRoutine
907
908         Return Value:
909                 Always returns STATUS_MORE_PROCESSING_REQUIRED
910
911         Note:
912                 Always returns STATUS_MORE_PROCESSING_REQUIRED
913         ========================================================================
914 */
915 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
916 {
917         /* use a receive tasklet to handle received packets; */
918         /* or sometimes hardware IRQ will be disabled here, so we can not */
919         /* use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :< */
920         PRX_CONTEXT pRxContext;
921         PRTMP_ADAPTER pAd;
922         POS_COOKIE pObj;
923
924         pRxContext = (PRX_CONTEXT) pUrb->context;
925         pAd = pRxContext->pAd;
926         pObj = (POS_COOKIE) pAd->OS_Cookie;
927
928         pObj->rx_done_task.data = (unsigned long)pUrb;
929         tasklet_hi_schedule(&pObj->rx_done_task);
930
931 }
932
933 /*
934         ========================================================================
935
936         Routine Description:
937
938         Arguments:
939
940         Return Value:
941
942         Note:
943
944         ========================================================================
945 */
946 VOID RTUSBKickBulkOut(IN PRTMP_ADAPTER pAd)
947 {
948         /* BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged. */
949         if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)
950             ) {
951                 /* 2. PS-Poll frame is next */
952                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL)) {
953                         RTUSBBulkOutPsPoll(pAd);
954                 }
955                 /* 5. Mlme frame is next */
956                 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) ||
957                          (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) {
958                         RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
959                 }
960                 /* 6. Data frame normal is next */
961                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL)) {
962                         if (((!RTMP_TEST_FLAG
963                               (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
964                              ||
965                              (!OPSTATUS_TEST_FLAG
966                               (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
967                             )) {
968                                 RTUSBBulkOutDataPacket(pAd, 0,
969                                                        pAd->
970                                                        NextBulkOutIndex[0]);
971                         }
972                 }
973                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2)) {
974                         if (((!RTMP_TEST_FLAG
975                               (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
976                              ||
977                              (!OPSTATUS_TEST_FLAG
978                               (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
979                             )) {
980                                 RTUSBBulkOutDataPacket(pAd, 1,
981                                                        pAd->
982                                                        NextBulkOutIndex[1]);
983                         }
984                 }
985                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3)) {
986                         if (((!RTMP_TEST_FLAG
987                               (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
988                              ||
989                              (!OPSTATUS_TEST_FLAG
990                               (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
991                             )) {
992                                 RTUSBBulkOutDataPacket(pAd, 2,
993                                                        pAd->
994                                                        NextBulkOutIndex[2]);
995                         }
996                 }
997                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4)) {
998                         if (((!RTMP_TEST_FLAG
999                               (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1000                              ||
1001                              (!OPSTATUS_TEST_FLAG
1002                               (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1003                             )) {
1004                                 RTUSBBulkOutDataPacket(pAd, 3,
1005                                                        pAd->
1006                                                        NextBulkOutIndex[3]);
1007                         }
1008                 }
1009                 /* 7. Null frame is the last */
1010                 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) {
1011                         if (!RTMP_TEST_FLAG
1012                             (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
1013                                 RTUSBBulkOutNullFrame(pAd);
1014                         }
1015                 }
1016                 /* 8. No data avaliable */
1017                 else {
1018
1019                 }
1020         }
1021 }
1022
1023 /*
1024         ========================================================================
1025
1026         Routine Description:
1027         Call from Reset action after BulkOut failed.
1028         Arguments:
1029
1030         Return Value:
1031
1032         Note:
1033
1034         ========================================================================
1035 */
1036 VOID RTUSBCleanUpDataBulkOutQueue(IN PRTMP_ADAPTER pAd)
1037 {
1038         UCHAR Idx;
1039         PHT_TX_CONTEXT pTxContext;
1040
1041         DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1042
1043         for (Idx = 0; Idx < 4; Idx++) {
1044                 pTxContext = &pAd->TxContext[Idx];
1045
1046                 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1047                 pTxContext->LastOne = FALSE;
1048                 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1049                 pAd->BulkOutPending[Idx] = FALSE;
1050                 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1051         }
1052
1053         DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1054 }
1055
1056 /*
1057         ========================================================================
1058
1059         Routine Description:
1060
1061         Arguments:
1062
1063         Return Value:
1064
1065         Note:
1066
1067         ========================================================================
1068 */
1069 VOID RTUSBCleanUpMLMEBulkOutQueue(IN PRTMP_ADAPTER pAd)
1070 {
1071         DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
1072         DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1073 }
1074
1075 /*
1076         ========================================================================
1077
1078         Routine Description:
1079
1080         Arguments:
1081
1082         Return Value:
1083
1084         Note:
1085
1086         ========================================================================
1087 */
1088 VOID RTUSBCancelPendingIRPs(IN PRTMP_ADAPTER pAd)
1089 {
1090         RTUSBCancelPendingBulkInIRP(pAd);
1091         RTUSBCancelPendingBulkOutIRP(pAd);
1092 }
1093
1094 /*
1095         ========================================================================
1096
1097         Routine Description:
1098
1099         Arguments:
1100
1101         Return Value:
1102
1103         Note:
1104
1105         ========================================================================
1106 */
1107 VOID RTUSBCancelPendingBulkInIRP(IN PRTMP_ADAPTER pAd)
1108 {
1109         PRX_CONTEXT pRxContext;
1110         UINT i;
1111
1112         DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
1113         for (i = 0; i < (RX_RING_SIZE); i++) {
1114                 pRxContext = &(pAd->RxContext[i]);
1115                 if (pRxContext->IRPPending == TRUE) {
1116                         RTUSB_UNLINK_URB(pRxContext->pUrb);
1117                         pRxContext->IRPPending = FALSE;
1118                         pRxContext->InUse = FALSE;
1119                         /*NdisInterlockedDecrement(&pAd->PendingRx); */
1120                         /*pAd->PendingRx--; */
1121                 }
1122         }
1123         DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1124 }
1125
1126 /*
1127         ========================================================================
1128
1129         Routine Description:
1130
1131         Arguments:
1132
1133         Return Value:
1134
1135         Note:
1136
1137         ========================================================================
1138 */
1139 VOID RTUSBCancelPendingBulkOutIRP(IN PRTMP_ADAPTER pAd)
1140 {
1141         PHT_TX_CONTEXT pHTTXContext;
1142         PTX_CONTEXT pMLMEContext;
1143         PTX_CONTEXT pBeaconContext;
1144         PTX_CONTEXT pNullContext;
1145         PTX_CONTEXT pPsPollContext;
1146         PTX_CONTEXT pRTSContext;
1147         UINT i, Idx;
1148 /*      unsigned int            IrqFlags; */
1149 /*      NDIS_SPIN_LOCK          *pLock; */
1150 /*      BOOLEAN                         *pPending; */
1151
1152 /*      pLock = &pAd->BulkOutLock[MGMTPIPEIDX]; */
1153 /*      pPending = &pAd->BulkOutPending[MGMTPIPEIDX]; */
1154
1155         for (Idx = 0; Idx < 4; Idx++) {
1156                 pHTTXContext = &(pAd->TxContext[Idx]);
1157
1158                 if (pHTTXContext->IRPPending == TRUE) {
1159
1160                         /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
1161                         /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
1162                         /*      when the last IRP on the list has been  cancelled; that's how we exit this loop */
1163                         /* */
1164
1165                         RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1166
1167                         /* Sleep 200 microseconds to give cancellation time to work */
1168                         RTMPusecDelay(200);
1169                 }
1170
1171                 pAd->BulkOutPending[Idx] = FALSE;
1172         }
1173
1174         /*RTMP_IRQ_LOCK(pLock, IrqFlags); */
1175         for (i = 0; i < MGMT_RING_SIZE; i++) {
1176                 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
1177                 if (pMLMEContext && (pMLMEContext->IRPPending == TRUE)) {
1178
1179                         /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
1180                         /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
1181                         /*      when the last IRP on the list has been  cancelled; that's how we exit this loop */
1182                         /* */
1183
1184                         RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1185                         pMLMEContext->IRPPending = FALSE;
1186
1187                         /* Sleep 200 microsecs to give cancellation time to work */
1188                         RTMPusecDelay(200);
1189                 }
1190         }
1191         pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1192         /*RTMP_IRQ_UNLOCK(pLock, IrqFlags); */
1193
1194         for (i = 0; i < BEACON_RING_SIZE; i++) {
1195                 pBeaconContext = &(pAd->BeaconContext[i]);
1196
1197                 if (pBeaconContext->IRPPending == TRUE) {
1198
1199                         /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
1200                         /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
1201                         /*      when the last IRP on the list has been  cancelled; that's how we exit this loop */
1202                         /* */
1203
1204                         RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1205
1206                         /* Sleep 200 microsecs to give cancellation time to work */
1207                         RTMPusecDelay(200);
1208                 }
1209         }
1210
1211         pNullContext = &(pAd->NullContext);
1212         if (pNullContext->IRPPending == TRUE)
1213                 RTUSB_UNLINK_URB(pNullContext->pUrb);
1214
1215         pRTSContext = &(pAd->RTSContext);
1216         if (pRTSContext->IRPPending == TRUE)
1217                 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1218
1219         pPsPollContext = &(pAd->PsPollContext);
1220         if (pPsPollContext->IRPPending == TRUE)
1221                 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1222
1223         for (Idx = 0; Idx < 4; Idx++) {
1224                 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1225                 pAd->BulkOutPending[Idx] = FALSE;
1226                 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1227         }
1228 }
1229
1230 #endif /* RTMP_MAC_USB // */