]> rtime.felk.cvut.cz Git - mcf548x/linux.git/blob - drivers/staging/rt2860/rt_usb.c
Initial 2.6.37
[mcf548x/linux.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(struct rt_rtmp_adapter *pAd)
81 {
82         struct rt_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(struct rt_rtmp_adapter *pAd)
137 {
138         int ret;
139         struct rt_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         struct rt_rtmp_adapter *pAd;
201         struct urb *pUrb;
202         struct os_cookie *pObj;
203         struct rt_ht_tx_context *pHTTXContext;
204         u8 BulkOutPipeId;
205         int Status;
206         unsigned long IrqFlags;
207
208         pUrb = (struct urb *)data;
209         pHTTXContext = (struct rt_ht_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                 u8 *pBuf;
238
239                 pAd->BulkOutCompleteOther++;
240
241                 pBuf =
242                     &pHTTXContext->TransferBuffer->field.
243                     WirelessPacket[pHTTXContext->NextBulkOutPosition];
244
245                 if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
246                                           fRTMP_ADAPTER_HALT_IN_PROGRESS |
247                                           fRTMP_ADAPTER_NIC_NOT_EXIST |
248                                           fRTMP_ADAPTER_BULKOUT_RESET))) {
249                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
250                         pAd->bulkResetPipeid = BulkOutPipeId;
251                         pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
252                 }
253                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
254
255                 DBGPRINT_RAW(RT_DEBUG_ERROR,
256                              ("BulkOutDataPacket failed: ReasonCode=%d!\n",
257                               Status));
258                 DBGPRINT_RAW(RT_DEBUG_ERROR,
259                              ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
260                               pAd->BulkOutReq, pAd->BulkOutComplete,
261                               pAd->BulkOutCompleteOther));
262                 DBGPRINT_RAW(RT_DEBUG_ERROR,
263                              ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n",
264                               pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4],
265                               pBuf[5], pBuf[6], pBuf[7]));
266                 /*DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther)); */
267
268         }
269
270         /* */
271         /* bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut */
272         /* bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. */
273         /* */
274         /*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
275         if ((pHTTXContext->ENextBulkOutPosition !=
276              pHTTXContext->CurWritePosition)
277             && (pHTTXContext->ENextBulkOutPosition !=
278                 (pHTTXContext->CurWritePosition + 8))
279             && !RTUSB_TEST_BULK_FLAG(pAd,
280                                      (fRTUSB_BULK_OUT_DATA_FRAG <<
281                                       BulkOutPipeId))) {
282                 /* Indicate There is data avaliable */
283                 RTUSB_SET_BULK_FLAG(pAd,
284                                     (fRTUSB_BULK_OUT_DATA_NORMAL <<
285                                      BulkOutPipeId));
286         }
287         /*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
288
289         /* Always call Bulk routine, even reset bulk. */
290         /* The protection of rest bulk should be in BulkOut routine */
291         RTUSBKickBulkOut(pAd);
292 }
293
294 static void rtusb_null_frame_done_tasklet(unsigned long data)
295 {
296         struct rt_rtmp_adapter *pAd;
297         struct rt_tx_context *pNullContext;
298         struct urb *pUrb;
299         int Status;
300         unsigned long irqFlag;
301
302         pUrb = (struct urb *)data;
303         pNullContext = (struct rt_tx_context *)pUrb->context;
304         pAd = pNullContext->pAd;
305         Status = pUrb->status;
306
307         /* Reset Null frame context flags */
308         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
309         pNullContext->IRPPending = FALSE;
310         pNullContext->InUse = FALSE;
311         pAd->BulkOutPending[0] = FALSE;
312         pAd->watchDogTxPendingCnt[0] = 0;
313
314         if (Status == USB_ST_NOERROR) {
315                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
316
317                 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
318         } else {                /* STATUS_OTHER */
319                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
320                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
321                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
322                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
323                         DBGPRINT_RAW(RT_DEBUG_ERROR,
324                                      ("Bulk Out Null Frame Failed, ReasonCode=%d!\n",
325                                       Status));
326                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
327                         pAd->bulkResetPipeid =
328                             (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
329                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
330                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
331                                                 NULL, 0);
332                 } else {
333                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
334                 }
335         }
336
337         /* Always call Bulk routine, even reset bulk. */
338         /* The protectioon of rest bulk should be in BulkOut routine */
339         RTUSBKickBulkOut(pAd);
340 }
341
342 static void rtusb_rts_frame_done_tasklet(unsigned long data)
343 {
344         struct rt_rtmp_adapter *pAd;
345         struct rt_tx_context *pRTSContext;
346         struct urb *pUrb;
347         int Status;
348         unsigned long irqFlag;
349
350         pUrb = (struct urb *)data;
351         pRTSContext = (struct rt_tx_context *)pUrb->context;
352         pAd = pRTSContext->pAd;
353         Status = pUrb->status;
354
355         /* Reset RTS frame context flags */
356         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
357         pRTSContext->IRPPending = FALSE;
358         pRTSContext->InUse = FALSE;
359
360         if (Status == USB_ST_NOERROR) {
361                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
362                 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
363         } else {                /* STATUS_OTHER */
364                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
365                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
366                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
367                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
368                         DBGPRINT_RAW(RT_DEBUG_ERROR,
369                                      ("Bulk Out RTS Frame Failed\n"));
370                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
371                         pAd->bulkResetPipeid =
372                             (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
373                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
374                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
375                                                 NULL, 0);
376                 } else {
377                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
378                 }
379         }
380
381         RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
382         pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
383         RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
384
385         /* Always call Bulk routine, even reset bulk. */
386         /* The protectioon of rest bulk should be in BulkOut routine */
387         RTUSBKickBulkOut(pAd);
388
389 }
390
391 static void rtusb_pspoll_frame_done_tasklet(unsigned long data)
392 {
393         struct rt_rtmp_adapter *pAd;
394         struct rt_tx_context *pPsPollContext;
395         struct urb *pUrb;
396         int Status;
397
398         pUrb = (struct urb *)data;
399         pPsPollContext = (struct rt_tx_context *)pUrb->context;
400         pAd = pPsPollContext->pAd;
401         Status = pUrb->status;
402
403         /* Reset PsPoll context flags */
404         pPsPollContext->IRPPending = FALSE;
405         pPsPollContext->InUse = FALSE;
406         pAd->watchDogTxPendingCnt[0] = 0;
407
408         if (Status == USB_ST_NOERROR) {
409                 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
410         } else {                /* STATUS_OTHER */
411                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
412                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
413                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
414                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
415                         DBGPRINT_RAW(RT_DEBUG_ERROR,
416                                      ("Bulk Out PSPoll Failed\n"));
417                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
418                         pAd->bulkResetPipeid =
419                             (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
420                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
421                                                 NULL, 0);
422                 }
423         }
424
425         RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
426         pAd->BulkOutPending[0] = FALSE;
427         RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
428
429         /* Always call Bulk routine, even reset bulk. */
430         /* The protectioon of rest bulk should be in BulkOut routine */
431         RTUSBKickBulkOut(pAd);
432
433 }
434
435 /*
436 ========================================================================
437 Routine Description:
438     Handle received packets.
439
440 Arguments:
441         data                            - URB information pointer
442
443 Return Value:
444     None
445
446 Note:
447 ========================================================================
448 */
449 static void rx_done_tasklet(unsigned long data)
450 {
451         struct urb *pUrb;
452         struct rt_rx_context *pRxContext;
453         struct rt_rtmp_adapter *pAd;
454         int Status;
455         unsigned int IrqFlags;
456
457         pUrb = (struct urb *)data;
458         pRxContext = (struct rt_rx_context *)pUrb->context;
459         pAd = pRxContext->pAd;
460         Status = pUrb->status;
461
462         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
463         pRxContext->InUse = FALSE;
464         pRxContext->IRPPending = FALSE;
465         pRxContext->BulkInOffset += pUrb->actual_length;
466         /*NdisInterlockedDecrement(&pAd->PendingRx); */
467         pAd->PendingRx--;
468
469         if (Status == USB_ST_NOERROR) {
470                 pAd->BulkInComplete++;
471                 pAd->NextRxBulkInPosition = 0;
472                 if (pRxContext->BulkInOffset) { /* As jan's comment, it may bulk-in success but size is zero. */
473                         pRxContext->Readable = TRUE;
474                         INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
475                 }
476                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
477         } else {                        /* STATUS_OTHER */
478                 pAd->BulkInCompleteFail++;
479                 /* Still read this packet although it may comtain wrong bytes. */
480                 pRxContext->Readable = FALSE;
481                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
482
483                 /* Parsing all packets. because after reset, the index will reset to all zero. */
484                 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
485                                            fRTMP_ADAPTER_BULKIN_RESET |
486                                            fRTMP_ADAPTER_HALT_IN_PROGRESS |
487                                            fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
488
489                         DBGPRINT_RAW(RT_DEBUG_ERROR,
490                                      ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
491                                       Status, pAd->NextRxBulkInIndex,
492                                       pAd->NextRxBulkInReadIndex,
493                                       pRxContext->pUrb->actual_length));
494
495                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
496                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN,
497                                                 NULL, 0);
498                 }
499         }
500
501         ASSERT((pRxContext->InUse == pRxContext->IRPPending));
502
503         RTUSBBulkReceive(pAd);
504
505         return;
506
507 }
508
509 static void rtusb_mgmt_dma_done_tasklet(unsigned long data)
510 {
511         struct rt_rtmp_adapter *pAd;
512         struct rt_tx_context *pMLMEContext;
513         int index;
514         void *pPacket;
515         struct urb *pUrb;
516         int Status;
517         unsigned long IrqFlags;
518
519         pUrb = (struct urb *)data;
520         pMLMEContext = (struct rt_tx_context *)pUrb->context;
521         pAd = pMLMEContext->pAd;
522         Status = pUrb->status;
523         index = pMLMEContext->SelfIdx;
524
525         ASSERT((pAd->MgmtRing.TxDmaIdx == index));
526
527         RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
528
529         if (Status != USB_ST_NOERROR) {
530                 /*Bulk-Out fail status handle */
531                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
532                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
533                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
534                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
535                         DBGPRINT_RAW(RT_DEBUG_ERROR,
536                                      ("Bulk Out MLME Failed, Status=%d!\n",
537                                       Status));
538                         /* TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt? */
539                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
540                         pAd->bulkResetPipeid =
541                             (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
542                 }
543         }
544
545         pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
546         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
547
548         RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
549         /* Reset MLME context flags */
550         pMLMEContext->IRPPending = FALSE;
551         pMLMEContext->InUse = FALSE;
552         pMLMEContext->bWaitingBulkOut = FALSE;
553         pMLMEContext->BulkOutSize = 0;
554
555         pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
556         pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
557
558         /* Increase MgmtRing Index */
559         INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
560         pAd->MgmtRing.TxSwFreeIdx++;
561         RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
562
563         /* No-matter success or fail, we free the mgmt packet. */
564         if (pPacket)
565                 RTMPFreeNdisPacket(pAd, pPacket);
566
567         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
568                                   fRTMP_ADAPTER_HALT_IN_PROGRESS |
569                                   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
570                 /* do nothing and return directly. */
571         } else {
572                 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. */
573                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
574                                                 NULL, 0);
575                 } else {
576
577                         /* Always call Bulk routine, even reset bulk. */
578                         /* The protectioon of rest bulk should be in BulkOut routine */
579                         if (pAd->MgmtRing.TxSwFreeIdx <
580                             MGMT_RING_SIZE
581                             /* pMLMEContext->bWaitingBulkOut == TRUE */) {
582                                 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
583                         }
584                         RTUSBKickBulkOut(pAd);
585                 }
586         }
587
588 }
589
590 static void rtusb_ac3_dma_done_tasklet(unsigned long data)
591 {
592         struct rt_rtmp_adapter *pAd;
593         struct rt_ht_tx_context *pHTTXContext;
594         u8 BulkOutPipeId = 3;
595         struct urb *pUrb;
596
597         pUrb = (struct urb *)data;
598         pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
599         pAd = pHTTXContext->pAd;
600
601         rtusb_dataout_complete((unsigned long)pUrb);
602
603         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
604                                   fRTMP_ADAPTER_HALT_IN_PROGRESS |
605                                   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
606                 /* do nothing and return directly. */
607         } else {
608                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
609                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
610                                                 NULL, 0);
611                 } else {
612                         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
613                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
614                             /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
615                             (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
616                             (pHTTXContext->bCurWriting == FALSE)) {
617                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
618                                                   MAX_TX_PROCESS);
619                         }
620
621                         RTUSB_SET_BULK_FLAG(pAd,
622                                             fRTUSB_BULK_OUT_DATA_NORMAL << 3);
623                         RTUSBKickBulkOut(pAd);
624                 }
625         }
626
627         return;
628 }
629
630 static void rtusb_ac2_dma_done_tasklet(unsigned long data)
631 {
632         struct rt_rtmp_adapter *pAd;
633         struct rt_ht_tx_context *pHTTXContext;
634         u8 BulkOutPipeId = 2;
635         struct urb *pUrb;
636
637         pUrb = (struct urb *)data;
638         pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
639         pAd = pHTTXContext->pAd;
640
641         rtusb_dataout_complete((unsigned long)pUrb);
642
643         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
644                                   fRTMP_ADAPTER_HALT_IN_PROGRESS |
645                                   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
646                 /* do nothing and return directly. */
647         } else {
648                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
649                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
650                                                 NULL, 0);
651                 } else {
652                         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
653                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
654                             /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
655                             (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
656                             (pHTTXContext->bCurWriting == FALSE)) {
657                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
658                                                   MAX_TX_PROCESS);
659                         }
660
661                         RTUSB_SET_BULK_FLAG(pAd,
662                                             fRTUSB_BULK_OUT_DATA_NORMAL << 2);
663                         RTUSBKickBulkOut(pAd);
664                 }
665         }
666
667         return;
668 }
669
670 static void rtusb_ac1_dma_done_tasklet(unsigned long data)
671 {
672         struct rt_rtmp_adapter *pAd;
673         struct rt_ht_tx_context *pHTTXContext;
674         u8 BulkOutPipeId = 1;
675         struct urb *pUrb;
676
677         pUrb = (struct urb *)data;
678         pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
679         pAd = pHTTXContext->pAd;
680
681         rtusb_dataout_complete((unsigned long)pUrb);
682
683         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
684                                   fRTMP_ADAPTER_HALT_IN_PROGRESS |
685                                   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
686                 /* do nothing and return directly. */
687         } else {
688                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
689                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
690                                                 NULL, 0);
691                 } else {
692                         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
693                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
694                             /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
695                             (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
696                             (pHTTXContext->bCurWriting == FALSE)) {
697                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
698                                                   MAX_TX_PROCESS);
699                         }
700
701                         RTUSB_SET_BULK_FLAG(pAd,
702                                             fRTUSB_BULK_OUT_DATA_NORMAL << 1);
703                         RTUSBKickBulkOut(pAd);
704                 }
705         }
706         return;
707
708 }
709
710 static void rtusb_ac0_dma_done_tasklet(unsigned long data)
711 {
712         struct rt_rtmp_adapter *pAd;
713         struct rt_ht_tx_context *pHTTXContext;
714         u8 BulkOutPipeId = 0;
715         struct urb *pUrb;
716
717         pUrb = (struct urb *)data;
718         pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
719         pAd = pHTTXContext->pAd;
720
721         rtusb_dataout_complete((unsigned long)pUrb);
722
723         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
724                                   fRTMP_ADAPTER_HALT_IN_PROGRESS |
725                                   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
726                 /* do nothing and return directly. */
727         } else {
728                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
729                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
730                                                 NULL, 0);
731                 } else {
732                         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
733                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
734                             /*  ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
735                             (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
736                             (pHTTXContext->bCurWriting == FALSE)) {
737                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
738                                                   MAX_TX_PROCESS);
739                         }
740
741                         RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
742                         RTUSBKickBulkOut(pAd);
743                 }
744         }
745
746         return;
747
748 }
749
750 int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd)
751 {
752         struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
753
754         /* Create receive tasklet */
755         tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
756         tasklet_init(&pObj->mgmt_dma_done_task, rtusb_mgmt_dma_done_tasklet,
757                      (unsigned long)pAd);
758         tasklet_init(&pObj->ac0_dma_done_task, rtusb_ac0_dma_done_tasklet,
759                      (unsigned long)pAd);
760         tasklet_init(&pObj->ac1_dma_done_task, rtusb_ac1_dma_done_tasklet,
761                      (unsigned long)pAd);
762         tasklet_init(&pObj->ac2_dma_done_task, rtusb_ac2_dma_done_tasklet,
763                      (unsigned long)pAd);
764         tasklet_init(&pObj->ac3_dma_done_task, rtusb_ac3_dma_done_tasklet,
765                      (unsigned long)pAd);
766         tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
767         tasklet_init(&pObj->null_frame_complete_task,
768                      rtusb_null_frame_done_tasklet, (unsigned long)pAd);
769         tasklet_init(&pObj->rts_frame_complete_task,
770                      rtusb_rts_frame_done_tasklet, (unsigned long)pAd);
771         tasklet_init(&pObj->pspoll_frame_complete_task,
772                      rtusb_pspoll_frame_done_tasklet, (unsigned long)pAd);
773
774         return NDIS_STATUS_SUCCESS;
775 }
776
777 void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd)
778 {
779         struct os_cookie *pObj;
780
781         pObj = (struct os_cookie *)pAd->OS_Cookie;
782
783         tasklet_kill(&pObj->rx_done_task);
784         tasklet_kill(&pObj->mgmt_dma_done_task);
785         tasklet_kill(&pObj->ac0_dma_done_task);
786         tasklet_kill(&pObj->ac1_dma_done_task);
787         tasklet_kill(&pObj->ac2_dma_done_task);
788         tasklet_kill(&pObj->ac3_dma_done_task);
789         tasklet_kill(&pObj->tbtt_task);
790         tasklet_kill(&pObj->null_frame_complete_task);
791         tasklet_kill(&pObj->rts_frame_complete_task);
792         tasklet_kill(&pObj->pspoll_frame_complete_task);
793 }