Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / rt2860 / rt_usb.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         Justin P. Mattock       11/07/2010      Fix some typos.
37
38 */
39
40 #include "rt_config.h"
41
42 void dump_urb(struct urb *purb)
43 {
44         printk(KERN_DEBUG "urb                  :0x%08lx\n", (unsigned long)purb);
45         printk(KERN_DEBUG "\tdev                   :0x%08lx\n", (unsigned long)purb->dev);
46         printk(KERN_DEBUG "\t\tdev->state          :0x%d\n", purb->dev->state);
47         printk(KERN_DEBUG "\tpipe                  :0x%08x\n", purb->pipe);
48         printk(KERN_DEBUG "\tstatus                :%d\n", purb->status);
49         printk(KERN_DEBUG "\ttransfer_flags        :0x%08x\n", purb->transfer_flags);
50         printk(KERN_DEBUG "\ttransfer_buffer       :0x%08lx\n",
51                (unsigned long)purb->transfer_buffer);
52         printk(KERN_DEBUG "\ttransfer_buffer_length:%d\n", purb->transfer_buffer_length);
53         printk(KERN_DEBUG "\tactual_length         :%d\n", purb->actual_length);
54         printk(KERN_DEBUG "\tsetup_packet          :0x%08lx\n",
55                (unsigned long)purb->setup_packet);
56         printk(KERN_DEBUG "\tstart_frame           :%d\n", purb->start_frame);
57         printk(KERN_DEBUG "\tnumber_of_packets     :%d\n", purb->number_of_packets);
58         printk(KERN_DEBUG "\tinterval              :%d\n", purb->interval);
59         printk(KERN_DEBUG "\terror_count           :%d\n", purb->error_count);
60         printk(KERN_DEBUG "\tcontext               :0x%08lx\n",
61                (unsigned long)purb->context);
62         printk(KERN_DEBUG "\tcomplete              :0x%08lx\n\n",
63                (unsigned long)purb->complete);
64 }
65
66 /*
67 ========================================================================
68 Routine Description:
69     Create kernel threads & tasklets.
70
71 Arguments:
72     *net_dev                    Pointer to wireless net device interface
73
74 Return Value:
75         NDIS_STATUS_SUCCESS
76         NDIS_STATUS_FAILURE
77
78 Note:
79 ========================================================================
80 */
81 int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd)
82 {
83         struct rt_rtmp_os_task *pTask;
84         int status;
85
86         /*
87            Creat TimerQ Thread, We need init timerQ related structure before create the timer thread.
88          */
89         RtmpTimerQInit(pAd);
90
91         pTask = &pAd->timerTask;
92         RtmpOSTaskInit(pTask, "RtmpTimerTask", pAd);
93         status = RtmpOSTaskAttach(pTask, RtmpTimerQThread, pTask);
94         if (status == NDIS_STATUS_FAILURE) {
95                 printk(KERN_WARNING "%s: unable to start RtmpTimerQThread\n",
96                        RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
97                 return NDIS_STATUS_FAILURE;
98         }
99
100         /* Creat MLME Thread */
101         pTask = &pAd->mlmeTask;
102         RtmpOSTaskInit(pTask, "RtmpMlmeTask", pAd);
103         status = RtmpOSTaskAttach(pTask, MlmeThread, pTask);
104         if (status == NDIS_STATUS_FAILURE) {
105                 printk(KERN_WARNING "%s: unable to start MlmeThread\n",
106                        RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
107                 return NDIS_STATUS_FAILURE;
108         }
109
110         /* Creat Command Thread */
111         pTask = &pAd->cmdQTask;
112         RtmpOSTaskInit(pTask, "RtmpCmdQTask", pAd);
113         status = RtmpOSTaskAttach(pTask, RTUSBCmdThread, pTask);
114         if (status == NDIS_STATUS_FAILURE) {
115                 printk(KERN_WARNING "%s: unable to start RTUSBCmdThread\n",
116                        RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
117                 return NDIS_STATUS_FAILURE;
118         }
119
120         return NDIS_STATUS_SUCCESS;
121 }
122
123 /*
124 ========================================================================
125 Routine Description:
126     Close kernel threads.
127
128 Arguments:
129         *pAd                            the raxx interface data pointer
130
131 Return Value:
132     NONE
133
134 Note:
135 ========================================================================
136 */
137 void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd)
138 {
139         int ret;
140         struct rt_rtmp_os_task *pTask;
141
142         /* Sleep 50 milliseconds so pending io might finish normally */
143         RTMPusecDelay(50000);
144
145         /* We want to wait until all pending receives and sends to the */
146         /* device object. We cancel any */
147         /* irps. Wait until sends and receives have stopped. */
148         RTUSBCancelPendingIRPs(pAd);
149
150         /* We need clear timerQ related structure before exits of the timer thread. */
151         RtmpTimerQExit(pAd);
152
153         /* Terminate Mlme Thread */
154         pTask = &pAd->mlmeTask;
155         ret = RtmpOSTaskKill(pTask);
156         if (ret == NDIS_STATUS_FAILURE) {
157                 DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
158                                           RTMP_OS_NETDEV_GET_DEVNAME(pAd->
159                                                                      net_dev),
160                                           pTask->taskName));
161         }
162
163         /* Terminate cmdQ thread */
164         pTask = &pAd->cmdQTask;
165 #ifdef KTHREAD_SUPPORT
166         if (pTask->kthread_task)
167 #else
168         CHECK_PID_LEGALITY(pTask->taskPID)
169 #endif
170         {
171                 mb();
172                 NdisAcquireSpinLock(&pAd->CmdQLock);
173                 pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
174                 NdisReleaseSpinLock(&pAd->CmdQLock);
175                 mb();
176                 /*RTUSBCMDUp(pAd); */
177                 ret = RtmpOSTaskKill(pTask);
178                 if (ret == NDIS_STATUS_FAILURE) {
179                         DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
180                                                   RTMP_OS_NETDEV_GET_DEVNAME
181                                                   (pAd->net_dev),
182                                                   pTask->taskName));
183                 }
184                 pAd->CmdQ.CmdQState = RTMP_TASK_STAT_UNKNOWN;
185         }
186
187         /* Terminate timer thread */
188         pTask = &pAd->timerTask;
189         ret = RtmpOSTaskKill(pTask);
190         if (ret == NDIS_STATUS_FAILURE) {
191                 DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
192                                           RTMP_OS_NETDEV_GET_DEVNAME(pAd->
193                                                                      net_dev),
194                                           pTask->taskName));
195         }
196
197 }
198
199 static void rtusb_dataout_complete(unsigned long data)
200 {
201         struct rt_rtmp_adapter *pAd;
202         struct urb *pUrb;
203         struct os_cookie *pObj;
204         struct rt_ht_tx_context *pHTTXContext;
205         u8 BulkOutPipeId;
206         int Status;
207         unsigned long IrqFlags;
208
209         pUrb = (struct urb *)data;
210         pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
211         pAd = pHTTXContext->pAd;
212         pObj = (struct os_cookie *)pAd->OS_Cookie;
213         Status = pUrb->status;
214
215         /* Store BulkOut PipeId */
216         BulkOutPipeId = pHTTXContext->BulkOutPipeId;
217         pAd->BulkOutDataOneSecCount++;
218
219         /*DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition, */
220         /*              pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); */
221
222         RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
223         pAd->BulkOutPending[BulkOutPipeId] = FALSE;
224         pHTTXContext->IRPPending = FALSE;
225         pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
226
227         if (Status == USB_ST_NOERROR) {
228                 pAd->BulkOutComplete++;
229
230                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
231
232                 pAd->Counters8023.GoodTransmits++;
233                 /*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
234                 FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
235                 /*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
236
237         } else {                /* STATUS_OTHER */
238                 u8 *pBuf;
239
240                 pAd->BulkOutCompleteOther++;
241
242                 pBuf =
243                     &pHTTXContext->TransferBuffer->field.
244                     WirelessPacket[pHTTXContext->NextBulkOutPosition];
245
246                 if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
247                                           fRTMP_ADAPTER_HALT_IN_PROGRESS |
248                                           fRTMP_ADAPTER_NIC_NOT_EXIST |
249                                           fRTMP_ADAPTER_BULKOUT_RESET))) {
250                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
251                         pAd->bulkResetPipeid = BulkOutPipeId;
252                         pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
253                 }
254                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
255
256                 DBGPRINT_RAW(RT_DEBUG_ERROR,
257                              ("BulkOutDataPacket failed: ReasonCode=%d!\n",
258                               Status));
259                 DBGPRINT_RAW(RT_DEBUG_ERROR,
260                              ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
261                               pAd->BulkOutReq, pAd->BulkOutComplete,
262                               pAd->BulkOutCompleteOther));
263                 DBGPRINT_RAW(RT_DEBUG_ERROR,
264                              ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n",
265                               pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4],
266                               pBuf[5], pBuf[6], pBuf[7]));
267                 /*DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther)); */
268
269         }
270
271         /* */
272         /* bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut */
273         /* bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. */
274         /* */
275         /*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
276         if ((pHTTXContext->ENextBulkOutPosition !=
277              pHTTXContext->CurWritePosition)
278             && (pHTTXContext->ENextBulkOutPosition !=
279                 (pHTTXContext->CurWritePosition + 8))
280             && !RTUSB_TEST_BULK_FLAG(pAd,
281                                      (fRTUSB_BULK_OUT_DATA_FRAG <<
282                                       BulkOutPipeId))) {
283                 /* Indicate There is data available */
284                 RTUSB_SET_BULK_FLAG(pAd,
285                                     (fRTUSB_BULK_OUT_DATA_NORMAL <<
286                                      BulkOutPipeId));
287         }
288         /*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
289
290         /* Always call Bulk routine, even reset bulk. */
291         /* The protection of rest bulk should be in BulkOut routine */
292         RTUSBKickBulkOut(pAd);
293 }
294
295 static void rtusb_null_frame_done_tasklet(unsigned long data)
296 {
297         struct rt_rtmp_adapter *pAd;
298         struct rt_tx_context *pNullContext;
299         struct urb *pUrb;
300         int Status;
301         unsigned long irqFlag;
302
303         pUrb = (struct urb *)data;
304         pNullContext = (struct rt_tx_context *)pUrb->context;
305         pAd = pNullContext->pAd;
306         Status = pUrb->status;
307
308         /* Reset Null frame context flags */
309         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
310         pNullContext->IRPPending = FALSE;
311         pNullContext->InUse = FALSE;
312         pAd->BulkOutPending[0] = FALSE;
313         pAd->watchDogTxPendingCnt[0] = 0;
314
315         if (Status == USB_ST_NOERROR) {
316                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
317
318                 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
319         } else {                /* STATUS_OTHER */
320                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
321                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
322                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
323                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
324                         DBGPRINT_RAW(RT_DEBUG_ERROR,
325                                      ("Bulk Out Null Frame Failed, ReasonCode=%d!\n",
326                                       Status));
327                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
328                         pAd->bulkResetPipeid =
329                             (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
330                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
331                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
332                                                 NULL, 0);
333                 } else {
334                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
335                 }
336         }
337
338         /* Always call Bulk routine, even reset bulk. */
339         /* The protection of rest bulk should be in BulkOut routine */
340         RTUSBKickBulkOut(pAd);
341 }
342
343 static void rtusb_rts_frame_done_tasklet(unsigned long data)
344 {
345         struct rt_rtmp_adapter *pAd;
346         struct rt_tx_context *pRTSContext;
347         struct urb *pUrb;
348         int Status;
349         unsigned long irqFlag;
350
351         pUrb = (struct urb *)data;
352         pRTSContext = (struct rt_tx_context *)pUrb->context;
353         pAd = pRTSContext->pAd;
354         Status = pUrb->status;
355
356         /* Reset RTS frame context flags */
357         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
358         pRTSContext->IRPPending = FALSE;
359         pRTSContext->InUse = FALSE;
360
361         if (Status == USB_ST_NOERROR) {
362                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
363                 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
364         } else {                /* STATUS_OTHER */
365                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
366                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
367                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
368                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
369                         DBGPRINT_RAW(RT_DEBUG_ERROR,
370                                      ("Bulk Out RTS Frame Failed\n"));
371                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
372                         pAd->bulkResetPipeid =
373                             (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
374                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
375                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
376                                                 NULL, 0);
377                 } else {
378                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
379                 }
380         }
381
382         RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
383         pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
384         RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
385
386         /* Always call Bulk routine, even reset bulk. */
387         /* The protection of rest bulk should be in BulkOut routine */
388         RTUSBKickBulkOut(pAd);
389
390 }
391
392 static void rtusb_pspoll_frame_done_tasklet(unsigned long data)
393 {
394         struct rt_rtmp_adapter *pAd;
395         struct rt_tx_context *pPsPollContext;
396         struct urb *pUrb;
397         int Status;
398
399         pUrb = (struct urb *)data;
400         pPsPollContext = (struct rt_tx_context *)pUrb->context;
401         pAd = pPsPollContext->pAd;
402         Status = pUrb->status;
403
404         /* Reset PsPoll context flags */
405         pPsPollContext->IRPPending = FALSE;
406         pPsPollContext->InUse = FALSE;
407         pAd->watchDogTxPendingCnt[0] = 0;
408
409         if (Status == USB_ST_NOERROR) {
410                 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
411         } else {                /* STATUS_OTHER */
412                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
413                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
414                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
415                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
416                         DBGPRINT_RAW(RT_DEBUG_ERROR,
417                                      ("Bulk Out PSPoll Failed\n"));
418                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
419                         pAd->bulkResetPipeid =
420                             (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
421                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
422                                                 NULL, 0);
423                 }
424         }
425
426         RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
427         pAd->BulkOutPending[0] = FALSE;
428         RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
429
430         /* Always call Bulk routine, even reset bulk. */
431         /* The protection of rest bulk should be in BulkOut routine */
432         RTUSBKickBulkOut(pAd);
433
434 }
435
436 /*
437 ========================================================================
438 Routine Description:
439     Handle received packets.
440
441 Arguments:
442         data                            - URB information pointer
443
444 Return Value:
445     None
446
447 Note:
448 ========================================================================
449 */
450 static void rx_done_tasklet(unsigned long data)
451 {
452         struct urb *pUrb;
453         struct rt_rx_context *pRxContext;
454         struct rt_rtmp_adapter *pAd;
455         int Status;
456         unsigned int IrqFlags;
457
458         pUrb = (struct urb *)data;
459         pRxContext = (struct rt_rx_context *)pUrb->context;
460         pAd = pRxContext->pAd;
461         Status = pUrb->status;
462
463         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
464         pRxContext->InUse = FALSE;
465         pRxContext->IRPPending = FALSE;
466         pRxContext->BulkInOffset += pUrb->actual_length;
467         /*NdisInterlockedDecrement(&pAd->PendingRx); */
468         pAd->PendingRx--;
469
470         if (Status == USB_ST_NOERROR) {
471                 pAd->BulkInComplete++;
472                 pAd->NextRxBulkInPosition = 0;
473                 if (pRxContext->BulkInOffset) { /* As jan's comment, it may bulk-in success but size is zero. */
474                         pRxContext->Readable = TRUE;
475                         INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
476                 }
477                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
478         } else {                        /* STATUS_OTHER */
479                 pAd->BulkInCompleteFail++;
480                 /* Still read this packet although it may comtain wrong bytes. */
481                 pRxContext->Readable = FALSE;
482                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
483
484                 /* Parsing all packets. because after reset, the index will reset to all zero. */
485                 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
486                                            fRTMP_ADAPTER_BULKIN_RESET |
487                                            fRTMP_ADAPTER_HALT_IN_PROGRESS |
488                                            fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
489
490                         DBGPRINT_RAW(RT_DEBUG_ERROR,
491                                      ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
492                                       Status, pAd->NextRxBulkInIndex,
493                                       pAd->NextRxBulkInReadIndex,
494                                       pRxContext->pUrb->actual_length));
495
496                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
497                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN,
498                                                 NULL, 0);
499                 }
500         }
501
502         ASSERT((pRxContext->InUse == pRxContext->IRPPending));
503
504         RTUSBBulkReceive(pAd);
505
506         return;
507
508 }
509
510 static void rtusb_mgmt_dma_done_tasklet(unsigned long data)
511 {
512         struct rt_rtmp_adapter *pAd;
513         struct rt_tx_context *pMLMEContext;
514         int index;
515         void *pPacket;
516         struct urb *pUrb;
517         int Status;
518         unsigned long IrqFlags;
519
520         pUrb = (struct urb *)data;
521         pMLMEContext = (struct rt_tx_context *)pUrb->context;
522         pAd = pMLMEContext->pAd;
523         Status = pUrb->status;
524         index = pMLMEContext->SelfIdx;
525
526         ASSERT((pAd->MgmtRing.TxDmaIdx == index));
527
528         RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
529
530         if (Status != USB_ST_NOERROR) {
531                 /*Bulk-Out fail status handle */
532                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
533                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
534                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
535                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
536                         DBGPRINT_RAW(RT_DEBUG_ERROR,
537                                      ("Bulk Out MLME Failed, Status=%d!\n",
538                                       Status));
539                         /* TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt? */
540                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
541                         pAd->bulkResetPipeid =
542                             (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
543                 }
544         }
545
546         pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
547         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
548
549         RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
550         /* Reset MLME context flags */
551         pMLMEContext->IRPPending = FALSE;
552         pMLMEContext->InUse = FALSE;
553         pMLMEContext->bWaitingBulkOut = FALSE;
554         pMLMEContext->BulkOutSize = 0;
555
556         pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
557         pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
558
559         /* Increase MgmtRing Index */
560         INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
561         pAd->MgmtRing.TxSwFreeIdx++;
562         RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
563
564         /* No-matter success or fail, we free the mgmt packet. */
565         if (pPacket)
566                 RTMPFreeNdisPacket(pAd, pPacket);
567
568         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
569                                   fRTMP_ADAPTER_HALT_IN_PROGRESS |
570                                   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
571                 /* do nothing and return directly. */
572         } else {
573                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) && ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)) {        /* For Mgmt Bulk-Out failed, ignore it now. */
574                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
575                                                 NULL, 0);
576                 } else {
577
578                         /* Always call Bulk routine, even reset bulk. */
579                         /* The protection of rest bulk should be in BulkOut routine */
580                         if (pAd->MgmtRing.TxSwFreeIdx <
581                             MGMT_RING_SIZE
582                             /* pMLMEContext->bWaitingBulkOut == TRUE */) {
583                                 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
584                         }
585                         RTUSBKickBulkOut(pAd);
586                 }
587         }
588
589 }
590
591 static void rtusb_ac3_dma_done_tasklet(unsigned long data)
592 {
593         struct rt_rtmp_adapter *pAd;
594         struct rt_ht_tx_context *pHTTXContext;
595         u8 BulkOutPipeId = 3;
596         struct urb *pUrb;
597
598         pUrb = (struct urb *)data;
599         pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
600         pAd = pHTTXContext->pAd;
601
602         rtusb_dataout_complete((unsigned long)pUrb);
603
604         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
605                                   fRTMP_ADAPTER_HALT_IN_PROGRESS |
606                                   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
607                 /* do nothing and return directly. */
608         } else {
609                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
610                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
611                                                 NULL, 0);
612                 } else {
613                         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
614                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
615                             /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
616                             (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
617                             (pHTTXContext->bCurWriting == FALSE)) {
618                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
619                                                   MAX_TX_PROCESS);
620                         }
621
622                         RTUSB_SET_BULK_FLAG(pAd,
623                                             fRTUSB_BULK_OUT_DATA_NORMAL << 3);
624                         RTUSBKickBulkOut(pAd);
625                 }
626         }
627
628         return;
629 }
630
631 static void rtusb_ac2_dma_done_tasklet(unsigned long data)
632 {
633         struct rt_rtmp_adapter *pAd;
634         struct rt_ht_tx_context *pHTTXContext;
635         u8 BulkOutPipeId = 2;
636         struct urb *pUrb;
637
638         pUrb = (struct urb *)data;
639         pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
640         pAd = pHTTXContext->pAd;
641
642         rtusb_dataout_complete((unsigned long)pUrb);
643
644         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
645                                   fRTMP_ADAPTER_HALT_IN_PROGRESS |
646                                   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
647                 /* do nothing and return directly. */
648         } else {
649                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
650                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
651                                                 NULL, 0);
652                 } else {
653                         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
654                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
655                             /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
656                             (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
657                             (pHTTXContext->bCurWriting == FALSE)) {
658                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
659                                                   MAX_TX_PROCESS);
660                         }
661
662                         RTUSB_SET_BULK_FLAG(pAd,
663                                             fRTUSB_BULK_OUT_DATA_NORMAL << 2);
664                         RTUSBKickBulkOut(pAd);
665                 }
666         }
667
668         return;
669 }
670
671 static void rtusb_ac1_dma_done_tasklet(unsigned long data)
672 {
673         struct rt_rtmp_adapter *pAd;
674         struct rt_ht_tx_context *pHTTXContext;
675         u8 BulkOutPipeId = 1;
676         struct urb *pUrb;
677
678         pUrb = (struct urb *)data;
679         pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
680         pAd = pHTTXContext->pAd;
681
682         rtusb_dataout_complete((unsigned long)pUrb);
683
684         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
685                                   fRTMP_ADAPTER_HALT_IN_PROGRESS |
686                                   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
687                 /* do nothing and return directly. */
688         } else {
689                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
690                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
691                                                 NULL, 0);
692                 } else {
693                         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
694                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
695                             /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
696                             (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
697                             (pHTTXContext->bCurWriting == FALSE)) {
698                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
699                                                   MAX_TX_PROCESS);
700                         }
701
702                         RTUSB_SET_BULK_FLAG(pAd,
703                                             fRTUSB_BULK_OUT_DATA_NORMAL << 1);
704                         RTUSBKickBulkOut(pAd);
705                 }
706         }
707         return;
708
709 }
710
711 static void rtusb_ac0_dma_done_tasklet(unsigned long data)
712 {
713         struct rt_rtmp_adapter *pAd;
714         struct rt_ht_tx_context *pHTTXContext;
715         u8 BulkOutPipeId = 0;
716         struct urb *pUrb;
717
718         pUrb = (struct urb *)data;
719         pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
720         pAd = pHTTXContext->pAd;
721
722         rtusb_dataout_complete((unsigned long)pUrb);
723
724         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
725                                   fRTMP_ADAPTER_HALT_IN_PROGRESS |
726                                   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
727                 /* do nothing and return directly. */
728         } else {
729                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
730                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
731                                                 NULL, 0);
732                 } else {
733                         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
734                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
735                             /*  ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
736                             (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
737                             (pHTTXContext->bCurWriting == FALSE)) {
738                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
739                                                   MAX_TX_PROCESS);
740                         }
741
742                         RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
743                         RTUSBKickBulkOut(pAd);
744                 }
745         }
746
747         return;
748
749 }
750
751 int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd)
752 {
753         struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
754
755         /* Create receive tasklet */
756         tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
757         tasklet_init(&pObj->mgmt_dma_done_task, rtusb_mgmt_dma_done_tasklet,
758                      (unsigned long)pAd);
759         tasklet_init(&pObj->ac0_dma_done_task, rtusb_ac0_dma_done_tasklet,
760                      (unsigned long)pAd);
761         tasklet_init(&pObj->ac1_dma_done_task, rtusb_ac1_dma_done_tasklet,
762                      (unsigned long)pAd);
763         tasklet_init(&pObj->ac2_dma_done_task, rtusb_ac2_dma_done_tasklet,
764                      (unsigned long)pAd);
765         tasklet_init(&pObj->ac3_dma_done_task, rtusb_ac3_dma_done_tasklet,
766                      (unsigned long)pAd);
767         tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
768         tasklet_init(&pObj->null_frame_complete_task,
769                      rtusb_null_frame_done_tasklet, (unsigned long)pAd);
770         tasklet_init(&pObj->rts_frame_complete_task,
771                      rtusb_rts_frame_done_tasklet, (unsigned long)pAd);
772         tasklet_init(&pObj->pspoll_frame_complete_task,
773                      rtusb_pspoll_frame_done_tasklet, (unsigned long)pAd);
774
775         return NDIS_STATUS_SUCCESS;
776 }
777
778 void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd)
779 {
780         struct os_cookie *pObj;
781
782         pObj = (struct os_cookie *)pAd->OS_Cookie;
783
784         tasklet_kill(&pObj->rx_done_task);
785         tasklet_kill(&pObj->mgmt_dma_done_task);
786         tasklet_kill(&pObj->ac0_dma_done_task);
787         tasklet_kill(&pObj->ac1_dma_done_task);
788         tasklet_kill(&pObj->ac2_dma_done_task);
789         tasklet_kill(&pObj->ac3_dma_done_task);
790         tasklet_kill(&pObj->tbtt_task);
791         tasklet_kill(&pObj->null_frame_complete_task);
792         tasklet_kill(&pObj->rts_frame_complete_task);
793         tasklet_kill(&pObj->pspoll_frame_complete_task);
794 }