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