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