Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rt2860 / rt_usb.c
blobeb037d2e04a2435470cdceacd524366ad63baf00
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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 *************************************************************************
27 Module Name:
28 rtusb_bulk.c
30 Abstract:
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Justin P. Mattock 11/07/2010 Fix some typos.
40 #include "rt_config.h"
42 void dump_urb(struct urb *purb)
44 printk(KERN_DEBUG "urb :0x%08lx\n", (unsigned long)purb);
45 printk(KERN_DEBUG "\tdev :0x%08lx\n", (unsigned long)purb->dev);
46 printk(KERN_DEBUG "\t\tdev->state :0x%d\n", purb->dev->state);
47 printk(KERN_DEBUG "\tpipe :0x%08x\n", purb->pipe);
48 printk(KERN_DEBUG "\tstatus :%d\n", purb->status);
49 printk(KERN_DEBUG "\ttransfer_flags :0x%08x\n", purb->transfer_flags);
50 printk(KERN_DEBUG "\ttransfer_buffer :0x%08lx\n",
51 (unsigned long)purb->transfer_buffer);
52 printk(KERN_DEBUG "\ttransfer_buffer_length:%d\n", purb->transfer_buffer_length);
53 printk(KERN_DEBUG "\tactual_length :%d\n", purb->actual_length);
54 printk(KERN_DEBUG "\tsetup_packet :0x%08lx\n",
55 (unsigned long)purb->setup_packet);
56 printk(KERN_DEBUG "\tstart_frame :%d\n", purb->start_frame);
57 printk(KERN_DEBUG "\tnumber_of_packets :%d\n", purb->number_of_packets);
58 printk(KERN_DEBUG "\tinterval :%d\n", purb->interval);
59 printk(KERN_DEBUG "\terror_count :%d\n", purb->error_count);
60 printk(KERN_DEBUG "\tcontext :0x%08lx\n",
61 (unsigned long)purb->context);
62 printk(KERN_DEBUG "\tcomplete :0x%08lx\n\n",
63 (unsigned long)purb->complete);
67 ========================================================================
68 Routine Description:
69 Create kernel threads & tasklets.
71 Arguments:
72 *net_dev Pointer to wireless net device interface
74 Return Value:
75 NDIS_STATUS_SUCCESS
76 NDIS_STATUS_FAILURE
78 Note:
79 ========================================================================
81 int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd)
83 struct rt_rtmp_os_task *pTask;
84 int status;
87 Creat TimerQ Thread, We need init timerQ related structure before create the timer thread.
89 RtmpTimerQInit(pAd);
91 pTask = &pAd->timerTask;
92 RtmpOSTaskInit(pTask, "RtmpTimerTask", pAd);
93 status = RtmpOSTaskAttach(pTask, RtmpTimerQThread, pTask);
94 if (status == NDIS_STATUS_FAILURE) {
95 printk(KERN_WARNING "%s: unable to start RtmpTimerQThread\n",
96 RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
97 return NDIS_STATUS_FAILURE;
100 /* Creat MLME Thread */
101 pTask = &pAd->mlmeTask;
102 RtmpOSTaskInit(pTask, "RtmpMlmeTask", pAd);
103 status = RtmpOSTaskAttach(pTask, MlmeThread, pTask);
104 if (status == NDIS_STATUS_FAILURE) {
105 printk(KERN_WARNING "%s: unable to start MlmeThread\n",
106 RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
107 return NDIS_STATUS_FAILURE;
110 /* Creat Command Thread */
111 pTask = &pAd->cmdQTask;
112 RtmpOSTaskInit(pTask, "RtmpCmdQTask", pAd);
113 status = RtmpOSTaskAttach(pTask, RTUSBCmdThread, pTask);
114 if (status == NDIS_STATUS_FAILURE) {
115 printk(KERN_WARNING "%s: unable to start RTUSBCmdThread\n",
116 RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
117 return NDIS_STATUS_FAILURE;
120 return NDIS_STATUS_SUCCESS;
124 ========================================================================
125 Routine Description:
126 Close kernel threads.
128 Arguments:
129 *pAd the raxx interface data pointer
131 Return Value:
132 NONE
134 Note:
135 ========================================================================
137 void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd)
139 int ret;
140 struct rt_rtmp_os_task *pTask;
142 /* Sleep 50 milliseconds so pending io might finish normally */
143 RTMPusecDelay(50000);
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);
150 /* We need clear timerQ related structure before exits of the timer thread. */
151 RtmpTimerQExit(pAd);
153 /* Terminate Mlme Thread */
154 pTask = &pAd->mlmeTask;
155 ret = RtmpOSTaskKill(pTask);
156 if (ret == NDIS_STATUS_FAILURE) {
157 DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
158 RTMP_OS_NETDEV_GET_DEVNAME(pAd->
159 net_dev),
160 pTask->taskName));
163 /* Terminate cmdQ thread */
164 pTask = &pAd->cmdQTask;
165 #ifdef KTHREAD_SUPPORT
166 if (pTask->kthread_task)
167 #else
168 CHECK_PID_LEGALITY(pTask->taskPID)
169 #endif
171 mb();
172 NdisAcquireSpinLock(&pAd->CmdQLock);
173 pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
174 NdisReleaseSpinLock(&pAd->CmdQLock);
175 mb();
176 /*RTUSBCMDUp(pAd); */
177 ret = RtmpOSTaskKill(pTask);
178 if (ret == NDIS_STATUS_FAILURE) {
179 DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
180 RTMP_OS_NETDEV_GET_DEVNAME
181 (pAd->net_dev),
182 pTask->taskName));
184 pAd->CmdQ.CmdQState = RTMP_TASK_STAT_UNKNOWN;
187 /* Terminate timer thread */
188 pTask = &pAd->timerTask;
189 ret = RtmpOSTaskKill(pTask);
190 if (ret == NDIS_STATUS_FAILURE) {
191 DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
192 RTMP_OS_NETDEV_GET_DEVNAME(pAd->
193 net_dev),
194 pTask->taskName));
199 static void rtusb_dataout_complete(unsigned long data)
201 struct rt_rtmp_adapter *pAd;
202 struct urb *pUrb;
203 struct os_cookie *pObj;
204 struct rt_ht_tx_context *pHTTXContext;
205 u8 BulkOutPipeId;
206 int Status;
207 unsigned long IrqFlags;
209 pUrb = (struct urb *)data;
210 pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
211 pAd = pHTTXContext->pAd;
212 pObj = (struct os_cookie *)pAd->OS_Cookie;
213 Status = pUrb->status;
215 /* Store BulkOut PipeId */
216 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
217 pAd->BulkOutDataOneSecCount++;
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)); */
222 RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
223 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
224 pHTTXContext->IRPPending = FALSE;
225 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
227 if (Status == USB_ST_NOERROR) {
228 pAd->BulkOutComplete++;
230 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
232 pAd->Counters8023.GoodTransmits++;
233 /*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
234 FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
235 /*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
237 } else { /* STATUS_OTHER */
238 u8 *pBuf;
240 pAd->BulkOutCompleteOther++;
242 pBuf =
243 &pHTTXContext->TransferBuffer->field.
244 WirelessPacket[pHTTXContext->NextBulkOutPosition];
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;
254 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
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)); */
271 /* */
272 /* bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut */
273 /* bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. */
274 /* */
275 /*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
276 if ((pHTTXContext->ENextBulkOutPosition !=
277 pHTTXContext->CurWritePosition)
278 && (pHTTXContext->ENextBulkOutPosition !=
279 (pHTTXContext->CurWritePosition + 8))
280 && !RTUSB_TEST_BULK_FLAG(pAd,
281 (fRTUSB_BULK_OUT_DATA_FRAG <<
282 BulkOutPipeId))) {
283 /* Indicate There is data available */
284 RTUSB_SET_BULK_FLAG(pAd,
285 (fRTUSB_BULK_OUT_DATA_NORMAL <<
286 BulkOutPipeId));
288 /*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
290 /* Always call Bulk routine, even reset bulk. */
291 /* The protection of rest bulk should be in BulkOut routine */
292 RTUSBKickBulkOut(pAd);
295 static void rtusb_null_frame_done_tasklet(unsigned long data)
297 struct rt_rtmp_adapter *pAd;
298 struct rt_tx_context *pNullContext;
299 struct urb *pUrb;
300 int Status;
301 unsigned long irqFlag;
303 pUrb = (struct urb *)data;
304 pNullContext = (struct rt_tx_context *)pUrb->context;
305 pAd = pNullContext->pAd;
306 Status = pUrb->status;
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;
315 if (Status == USB_ST_NOERROR) {
316 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
318 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
319 } else { /* STATUS_OTHER */
320 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
321 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
322 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
323 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
324 DBGPRINT_RAW(RT_DEBUG_ERROR,
325 ("Bulk Out Null Frame Failed, ReasonCode=%d!\n",
326 Status));
327 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
328 pAd->bulkResetPipeid =
329 (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
330 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
331 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
332 NULL, 0);
333 } else {
334 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
338 /* Always call Bulk routine, even reset bulk. */
339 /* The protection of rest bulk should be in BulkOut routine */
340 RTUSBKickBulkOut(pAd);
343 static void rtusb_rts_frame_done_tasklet(unsigned long data)
345 struct rt_rtmp_adapter *pAd;
346 struct rt_tx_context *pRTSContext;
347 struct urb *pUrb;
348 int Status;
349 unsigned long irqFlag;
351 pUrb = (struct urb *)data;
352 pRTSContext = (struct rt_tx_context *)pUrb->context;
353 pAd = pRTSContext->pAd;
354 Status = pUrb->status;
356 /* Reset RTS frame context flags */
357 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
358 pRTSContext->IRPPending = FALSE;
359 pRTSContext->InUse = FALSE;
361 if (Status == USB_ST_NOERROR) {
362 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
363 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
364 } else { /* STATUS_OTHER */
365 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
366 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
367 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
368 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
369 DBGPRINT_RAW(RT_DEBUG_ERROR,
370 ("Bulk Out RTS Frame Failed\n"));
371 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
372 pAd->bulkResetPipeid =
373 (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
374 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
375 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
376 NULL, 0);
377 } else {
378 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
382 RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
383 pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
384 RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
386 /* Always call Bulk routine, even reset bulk. */
387 /* The protection of rest bulk should be in BulkOut routine */
388 RTUSBKickBulkOut(pAd);
392 static void rtusb_pspoll_frame_done_tasklet(unsigned long data)
394 struct rt_rtmp_adapter *pAd;
395 struct rt_tx_context *pPsPollContext;
396 struct urb *pUrb;
397 int Status;
399 pUrb = (struct urb *)data;
400 pPsPollContext = (struct rt_tx_context *)pUrb->context;
401 pAd = pPsPollContext->pAd;
402 Status = pUrb->status;
404 /* Reset PsPoll context flags */
405 pPsPollContext->IRPPending = FALSE;
406 pPsPollContext->InUse = FALSE;
407 pAd->watchDogTxPendingCnt[0] = 0;
409 if (Status == USB_ST_NOERROR) {
410 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
411 } else { /* STATUS_OTHER */
412 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
413 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
414 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
415 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
416 DBGPRINT_RAW(RT_DEBUG_ERROR,
417 ("Bulk Out PSPoll Failed\n"));
418 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
419 pAd->bulkResetPipeid =
420 (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
421 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
422 NULL, 0);
426 RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
427 pAd->BulkOutPending[0] = FALSE;
428 RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
430 /* Always call Bulk routine, even reset bulk. */
431 /* The protection of rest bulk should be in BulkOut routine */
432 RTUSBKickBulkOut(pAd);
437 ========================================================================
438 Routine Description:
439 Handle received packets.
441 Arguments:
442 data - URB information pointer
444 Return Value:
445 None
447 Note:
448 ========================================================================
450 static void rx_done_tasklet(unsigned long data)
452 struct urb *pUrb;
453 struct rt_rx_context *pRxContext;
454 struct rt_rtmp_adapter *pAd;
455 int Status;
456 unsigned int IrqFlags;
458 pUrb = (struct urb *)data;
459 pRxContext = (struct rt_rx_context *)pUrb->context;
460 pAd = pRxContext->pAd;
461 Status = pUrb->status;
463 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
464 pRxContext->InUse = FALSE;
465 pRxContext->IRPPending = FALSE;
466 pRxContext->BulkInOffset += pUrb->actual_length;
467 /*NdisInterlockedDecrement(&pAd->PendingRx); */
468 pAd->PendingRx--;
470 if (Status == USB_ST_NOERROR) {
471 pAd->BulkInComplete++;
472 pAd->NextRxBulkInPosition = 0;
473 if (pRxContext->BulkInOffset) { /* As jan's comment, it may bulk-in success but size is zero. */
474 pRxContext->Readable = TRUE;
475 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
477 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
478 } else { /* STATUS_OTHER */
479 pAd->BulkInCompleteFail++;
480 /* Still read this packet although it may comtain wrong bytes. */
481 pRxContext->Readable = FALSE;
482 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
484 /* Parsing all packets. because after reset, the index will reset to all zero. */
485 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
486 fRTMP_ADAPTER_BULKIN_RESET |
487 fRTMP_ADAPTER_HALT_IN_PROGRESS |
488 fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
490 DBGPRINT_RAW(RT_DEBUG_ERROR,
491 ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
492 Status, pAd->NextRxBulkInIndex,
493 pAd->NextRxBulkInReadIndex,
494 pRxContext->pUrb->actual_length));
496 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
497 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN,
498 NULL, 0);
502 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
504 RTUSBBulkReceive(pAd);
506 return;
510 static void rtusb_mgmt_dma_done_tasklet(unsigned long data)
512 struct rt_rtmp_adapter *pAd;
513 struct rt_tx_context *pMLMEContext;
514 int index;
515 void *pPacket;
516 struct urb *pUrb;
517 int Status;
518 unsigned long IrqFlags;
520 pUrb = (struct urb *)data;
521 pMLMEContext = (struct rt_tx_context *)pUrb->context;
522 pAd = pMLMEContext->pAd;
523 Status = pUrb->status;
524 index = pMLMEContext->SelfIdx;
526 ASSERT((pAd->MgmtRing.TxDmaIdx == index));
528 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
530 if (Status != USB_ST_NOERROR) {
531 /*Bulk-Out fail status handle */
532 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
533 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
534 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
535 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
536 DBGPRINT_RAW(RT_DEBUG_ERROR,
537 ("Bulk Out MLME Failed, Status=%d!\n",
538 Status));
539 /* TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt? */
540 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
541 pAd->bulkResetPipeid =
542 (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
546 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
547 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
549 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
550 /* Reset MLME context flags */
551 pMLMEContext->IRPPending = FALSE;
552 pMLMEContext->InUse = FALSE;
553 pMLMEContext->bWaitingBulkOut = FALSE;
554 pMLMEContext->BulkOutSize = 0;
556 pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
557 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
559 /* Increase MgmtRing Index */
560 INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
561 pAd->MgmtRing.TxSwFreeIdx++;
562 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
564 /* No-matter success or fail, we free the mgmt packet. */
565 if (pPacket)
566 RTMPFreeNdisPacket(pAd, pPacket);
568 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
569 fRTMP_ADAPTER_HALT_IN_PROGRESS |
570 fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
571 /* do nothing and return directly. */
572 } else {
573 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) && ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)) { /* For Mgmt Bulk-Out failed, ignore it now. */
574 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
575 NULL, 0);
576 } else {
578 /* Always call Bulk routine, even reset bulk. */
579 /* The protection of rest bulk should be in BulkOut routine */
580 if (pAd->MgmtRing.TxSwFreeIdx <
581 MGMT_RING_SIZE
582 /* pMLMEContext->bWaitingBulkOut == TRUE */) {
583 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
585 RTUSBKickBulkOut(pAd);
591 static void rtusb_ac3_dma_done_tasklet(unsigned long data)
593 struct rt_rtmp_adapter *pAd;
594 struct rt_ht_tx_context *pHTTXContext;
595 u8 BulkOutPipeId = 3;
596 struct urb *pUrb;
598 pUrb = (struct urb *)data;
599 pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
600 pAd = pHTTXContext->pAd;
602 rtusb_dataout_complete((unsigned long)pUrb);
604 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
605 fRTMP_ADAPTER_HALT_IN_PROGRESS |
606 fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
607 /* do nothing and return directly. */
608 } else {
609 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
610 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
611 NULL, 0);
612 } else {
613 pHTTXContext = &pAd->TxContext[BulkOutPipeId];
614 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
615 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
616 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
617 (pHTTXContext->bCurWriting == FALSE)) {
618 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
619 MAX_TX_PROCESS);
622 RTUSB_SET_BULK_FLAG(pAd,
623 fRTUSB_BULK_OUT_DATA_NORMAL << 3);
624 RTUSBKickBulkOut(pAd);
628 return;
631 static void rtusb_ac2_dma_done_tasklet(unsigned long data)
633 struct rt_rtmp_adapter *pAd;
634 struct rt_ht_tx_context *pHTTXContext;
635 u8 BulkOutPipeId = 2;
636 struct urb *pUrb;
638 pUrb = (struct urb *)data;
639 pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
640 pAd = pHTTXContext->pAd;
642 rtusb_dataout_complete((unsigned long)pUrb);
644 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
645 fRTMP_ADAPTER_HALT_IN_PROGRESS |
646 fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
647 /* do nothing and return directly. */
648 } else {
649 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
650 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
651 NULL, 0);
652 } else {
653 pHTTXContext = &pAd->TxContext[BulkOutPipeId];
654 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
655 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
656 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
657 (pHTTXContext->bCurWriting == FALSE)) {
658 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
659 MAX_TX_PROCESS);
662 RTUSB_SET_BULK_FLAG(pAd,
663 fRTUSB_BULK_OUT_DATA_NORMAL << 2);
664 RTUSBKickBulkOut(pAd);
668 return;
671 static void rtusb_ac1_dma_done_tasklet(unsigned long data)
673 struct rt_rtmp_adapter *pAd;
674 struct rt_ht_tx_context *pHTTXContext;
675 u8 BulkOutPipeId = 1;
676 struct urb *pUrb;
678 pUrb = (struct urb *)data;
679 pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
680 pAd = pHTTXContext->pAd;
682 rtusb_dataout_complete((unsigned long)pUrb);
684 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
685 fRTMP_ADAPTER_HALT_IN_PROGRESS |
686 fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
687 /* do nothing and return directly. */
688 } else {
689 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
690 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
691 NULL, 0);
692 } else {
693 pHTTXContext = &pAd->TxContext[BulkOutPipeId];
694 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
695 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
696 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
697 (pHTTXContext->bCurWriting == FALSE)) {
698 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
699 MAX_TX_PROCESS);
702 RTUSB_SET_BULK_FLAG(pAd,
703 fRTUSB_BULK_OUT_DATA_NORMAL << 1);
704 RTUSBKickBulkOut(pAd);
707 return;
711 static void rtusb_ac0_dma_done_tasklet(unsigned long data)
713 struct rt_rtmp_adapter *pAd;
714 struct rt_ht_tx_context *pHTTXContext;
715 u8 BulkOutPipeId = 0;
716 struct urb *pUrb;
718 pUrb = (struct urb *)data;
719 pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
720 pAd = pHTTXContext->pAd;
722 rtusb_dataout_complete((unsigned long)pUrb);
724 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
725 fRTMP_ADAPTER_HALT_IN_PROGRESS |
726 fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
727 /* do nothing and return directly. */
728 } else {
729 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
730 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
731 NULL, 0);
732 } else {
733 pHTTXContext = &pAd->TxContext[BulkOutPipeId];
734 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
735 /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
736 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
737 (pHTTXContext->bCurWriting == FALSE)) {
738 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
739 MAX_TX_PROCESS);
742 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
743 RTUSBKickBulkOut(pAd);
747 return;
751 int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd)
753 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
755 /* Create receive tasklet */
756 tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
757 tasklet_init(&pObj->mgmt_dma_done_task, rtusb_mgmt_dma_done_tasklet,
758 (unsigned long)pAd);
759 tasklet_init(&pObj->ac0_dma_done_task, rtusb_ac0_dma_done_tasklet,
760 (unsigned long)pAd);
761 tasklet_init(&pObj->ac1_dma_done_task, rtusb_ac1_dma_done_tasklet,
762 (unsigned long)pAd);
763 tasklet_init(&pObj->ac2_dma_done_task, rtusb_ac2_dma_done_tasklet,
764 (unsigned long)pAd);
765 tasklet_init(&pObj->ac3_dma_done_task, rtusb_ac3_dma_done_tasklet,
766 (unsigned long)pAd);
767 tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
768 tasklet_init(&pObj->null_frame_complete_task,
769 rtusb_null_frame_done_tasklet, (unsigned long)pAd);
770 tasklet_init(&pObj->rts_frame_complete_task,
771 rtusb_rts_frame_done_tasklet, (unsigned long)pAd);
772 tasklet_init(&pObj->pspoll_frame_complete_task,
773 rtusb_pspoll_frame_done_tasklet, (unsigned long)pAd);
775 return NDIS_STATUS_SUCCESS;
778 void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd)
780 struct os_cookie *pObj;
782 pObj = (struct os_cookie *)pAd->OS_Cookie;
784 tasklet_kill(&pObj->rx_done_task);
785 tasklet_kill(&pObj->mgmt_dma_done_task);
786 tasklet_kill(&pObj->ac0_dma_done_task);
787 tasklet_kill(&pObj->ac1_dma_done_task);
788 tasklet_kill(&pObj->ac2_dma_done_task);
789 tasklet_kill(&pObj->ac3_dma_done_task);
790 tasklet_kill(&pObj->tbtt_task);
791 tasklet_kill(&pObj->null_frame_complete_task);
792 tasklet_kill(&pObj->rts_frame_complete_task);
793 tasklet_kill(&pObj->pspoll_frame_complete_task);