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