Merge branch 'tc1100-wmi' into release
[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                                   __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                                  (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         /*
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                         u8 *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(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         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(struct urb *pUrb, struct pt_regs * pt_regs)
593 {
594         struct rt_rtmp_adapter *pAd;
595         struct rt_tx_context *pNullContext;
596         int Status;
597         struct os_cookie *pObj;
598
599         pNullContext = (struct rt_tx_context *)pUrb->context;
600         pAd = pNullContext->pAd;
601         Status = pUrb->status;
602
603         pObj = (struct os_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(struct rt_rtmp_adapter *pAd, u8 Index)
622 {
623         struct rt_tx_context *pMLMEContext;
624         PURB pUrb;
625         int ret = 0;
626         unsigned long IrqFlags;
627
628         pMLMEContext =
629             (struct rt_tx_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(struct urb *pUrb, struct pt_regs * pt_regs)
688 {
689         struct rt_tx_context *pMLMEContext;
690         struct rt_rtmp_adapter *pAd;
691         int Status;
692         struct os_cookie *pObj;
693         int index;
694
695         /*DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n")); */
696         pMLMEContext = (struct rt_tx_context *)pUrb->context;
697         pAd = pMLMEContext->pAd;
698         pObj = (struct os_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(struct rt_rtmp_adapter *pAd)
720 {
721         struct rt_tx_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(struct urb *pUrb, struct pt_regs * pt_regs)
762 {
763         struct rt_rtmp_adapter *pAd;
764         struct rt_tx_context *pPsPollContext;
765         int Status;
766         struct os_cookie *pObj;
767
768         pPsPollContext = (struct rt_tx_context *)pUrb->context;
769         pAd = pPsPollContext->pAd;
770         Status = pUrb->status;
771
772         pObj = (struct os_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(struct rt_rtmp_adapter *pAd)
778 {
779         struct rt_rx_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(struct rt_rtmp_adapter *pAd)
849 {
850         struct rt_rx_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(struct urb *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         struct rt_rx_context *pRxContext;
921         struct rt_rtmp_adapter *pAd;
922         struct os_cookie *pObj;
923
924         pRxContext = (struct rt_rx_context *)pUrb->context;
925         pAd = pRxContext->pAd;
926         pObj = (struct os_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(struct rt_rtmp_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(struct rt_rtmp_adapter *pAd)
1037 {
1038         u8 Idx;
1039         struct rt_ht_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(struct rt_rtmp_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(struct rt_rtmp_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(struct rt_rtmp_adapter *pAd)
1108 {
1109         struct rt_rx_context *pRxContext;
1110         u32 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(struct rt_rtmp_adapter *pAd)
1140 {
1141         struct rt_ht_tx_context *pHTTXContext;
1142         struct rt_tx_context *pMLMEContext;
1143         struct rt_tx_context *pBeaconContext;
1144         struct rt_tx_context *pNullContext;
1145         struct rt_tx_context *pPsPollContext;
1146         struct rt_tx_context *pRTSContext;
1147         u32 i, Idx;
1148 /*      unsigned int            IrqFlags; */
1149 /*      spinlock_t          *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 = (struct rt_tx_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 // */