RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / rt2860 / rt_usb.c
blobbcfc0f54d2aa01001d6ab86044fab726f54a4569
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
39 #include "rt_config.h"
41 void dump_urb(struct urb *purb)
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);
66 ========================================================================
67 Routine Description:
68 Create kernel threads & tasklets.
70 Arguments:
71 *net_dev Pointer to wireless net device interface
73 Return Value:
74 NDIS_STATUS_SUCCESS
75 NDIS_STATUS_FAILURE
77 Note:
78 ========================================================================
80 int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd)
82 struct rt_rtmp_os_task *pTask;
83 int status;
86 Creat TimerQ Thread, We need init timerQ related structure before create the timer thread.
88 RtmpTimerQInit(pAd);
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;
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;
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;
119 return NDIS_STATUS_SUCCESS;
123 ========================================================================
124 Routine Description:
125 Close kernel threads.
127 Arguments:
128 *pAd the raxx interface data pointer
130 Return Value:
131 NONE
133 Note:
134 ========================================================================
136 void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd)
138 int ret;
139 struct rt_rtmp_os_task *pTask;
141 /* Sleep 50 milliseconds so pending io might finish normally */
142 RTMPusecDelay(50000);
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);
149 /* We need clear timerQ related structure before exits of the timer thread. */
150 RtmpTimerQExit(pAd);
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));
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
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));
183 pAd->CmdQ.CmdQState = RTMP_TASK_STAT_UNKNOWN;
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));
198 static void rtusb_dataout_complete(unsigned long data)
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;
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;
214 /* Store BulkOut PipeId */
215 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
216 pAd->BulkOutDataOneSecCount++;
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)); */
221 RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
222 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
223 pHTTXContext->IRPPending = FALSE;
224 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
226 if (Status == USB_ST_NOERROR) {
227 pAd->BulkOutComplete++;
229 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
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); */
236 } else { /* STATUS_OTHER */
237 u8 *pBuf;
239 pAd->BulkOutCompleteOther++;
241 pBuf =
242 &pHTTXContext->TransferBuffer->field.
243 WirelessPacket[pHTTXContext->NextBulkOutPosition];
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;
253 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
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)); */
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));
287 /*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
289 /* Always call Bulk routine, even reset bulk. */
290 /* The protection of rest bulk should be in BulkOut routine */
291 RTUSBKickBulkOut(pAd);
294 static void rtusb_null_frame_done_tasklet(unsigned long data)
296 struct rt_rtmp_adapter *pAd;
297 struct rt_tx_context *pNullContext;
298 struct urb *pUrb;
299 int Status;
300 unsigned long irqFlag;
302 pUrb = (struct urb *)data;
303 pNullContext = (struct rt_tx_context *)pUrb->context;
304 pAd = pNullContext->pAd;
305 Status = pUrb->status;
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;
314 if (Status == USB_ST_NOERROR) {
315 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
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);
337 /* Always call Bulk routine, even reset bulk. */
338 /* The protectioon of rest bulk should be in BulkOut routine */
339 RTUSBKickBulkOut(pAd);
342 static void rtusb_rts_frame_done_tasklet(unsigned long data)
344 struct rt_rtmp_adapter *pAd;
345 struct rt_tx_context *pRTSContext;
346 struct urb *pUrb;
347 int Status;
348 unsigned long irqFlag;
350 pUrb = (struct urb *)data;
351 pRTSContext = (struct rt_tx_context *)pUrb->context;
352 pAd = pRTSContext->pAd;
353 Status = pUrb->status;
355 /* Reset RTS frame context flags */
356 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
357 pRTSContext->IRPPending = FALSE;
358 pRTSContext->InUse = FALSE;
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);
381 RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
382 pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
383 RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
385 /* Always call Bulk routine, even reset bulk. */
386 /* The protectioon of rest bulk should be in BulkOut routine */
387 RTUSBKickBulkOut(pAd);
391 static void rtusb_pspoll_frame_done_tasklet(unsigned long data)
393 struct rt_rtmp_adapter *pAd;
394 struct rt_tx_context *pPsPollContext;
395 struct urb *pUrb;
396 int Status;
398 pUrb = (struct urb *)data;
399 pPsPollContext = (struct rt_tx_context *)pUrb->context;
400 pAd = pPsPollContext->pAd;
401 Status = pUrb->status;
403 /* Reset PsPoll context flags */
404 pPsPollContext->IRPPending = FALSE;
405 pPsPollContext->InUse = FALSE;
406 pAd->watchDogTxPendingCnt[0] = 0;
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);
425 RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
426 pAd->BulkOutPending[0] = FALSE;
427 RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
429 /* Always call Bulk routine, even reset bulk. */
430 /* The protectioon of rest bulk should be in BulkOut routine */
431 RTUSBKickBulkOut(pAd);
436 ========================================================================
437 Routine Description:
438 Handle received packets.
440 Arguments:
441 data - URB information pointer
443 Return Value:
444 None
446 Note:
447 ========================================================================
449 static void rx_done_tasklet(unsigned long data)
451 struct urb *pUrb;
452 struct rt_rx_context *pRxContext;
453 struct rt_rtmp_adapter *pAd;
454 int Status;
455 unsigned int IrqFlags;
457 pUrb = (struct urb *)data;
458 pRxContext = (struct rt_rx_context *)pUrb->context;
459 pAd = pRxContext->pAd;
460 Status = pUrb->status;
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--;
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);
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);
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)))) {
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));
495 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
496 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN,
497 NULL, 0);
501 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
503 RTUSBBulkReceive(pAd);
505 return;
509 static void rtusb_mgmt_dma_done_tasklet(unsigned long data)
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;
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;
525 ASSERT((pAd->MgmtRing.TxDmaIdx == index));
527 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
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);
545 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
546 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
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;
555 pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
556 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
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);
563 /* No-matter success or fail, we free the mgmt packet. */
564 if (pPacket)
565 RTMPFreeNdisPacket(pAd, pPacket);
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 {
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);
584 RTUSBKickBulkOut(pAd);
590 static void rtusb_ac3_dma_done_tasklet(unsigned long data)
592 struct rt_rtmp_adapter *pAd;
593 struct rt_ht_tx_context *pHTTXContext;
594 u8 BulkOutPipeId = 3;
595 struct urb *pUrb;
597 pUrb = (struct urb *)data;
598 pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
599 pAd = pHTTXContext->pAd;
601 rtusb_dataout_complete((unsigned long)pUrb);
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);
621 RTUSB_SET_BULK_FLAG(pAd,
622 fRTUSB_BULK_OUT_DATA_NORMAL << 3);
623 RTUSBKickBulkOut(pAd);
627 return;
630 static void rtusb_ac2_dma_done_tasklet(unsigned long data)
632 struct rt_rtmp_adapter *pAd;
633 struct rt_ht_tx_context *pHTTXContext;
634 u8 BulkOutPipeId = 2;
635 struct urb *pUrb;
637 pUrb = (struct urb *)data;
638 pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
639 pAd = pHTTXContext->pAd;
641 rtusb_dataout_complete((unsigned long)pUrb);
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);
661 RTUSB_SET_BULK_FLAG(pAd,
662 fRTUSB_BULK_OUT_DATA_NORMAL << 2);
663 RTUSBKickBulkOut(pAd);
667 return;
670 static void rtusb_ac1_dma_done_tasklet(unsigned long data)
672 struct rt_rtmp_adapter *pAd;
673 struct rt_ht_tx_context *pHTTXContext;
674 u8 BulkOutPipeId = 1;
675 struct urb *pUrb;
677 pUrb = (struct urb *)data;
678 pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
679 pAd = pHTTXContext->pAd;
681 rtusb_dataout_complete((unsigned long)pUrb);
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);
701 RTUSB_SET_BULK_FLAG(pAd,
702 fRTUSB_BULK_OUT_DATA_NORMAL << 1);
703 RTUSBKickBulkOut(pAd);
706 return;
710 static void rtusb_ac0_dma_done_tasklet(unsigned long data)
712 struct rt_rtmp_adapter *pAd;
713 struct rt_ht_tx_context *pHTTXContext;
714 u8 BulkOutPipeId = 0;
715 struct urb *pUrb;
717 pUrb = (struct urb *)data;
718 pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
719 pAd = pHTTXContext->pAd;
721 rtusb_dataout_complete((unsigned long)pUrb);
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);
741 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
742 RTUSBKickBulkOut(pAd);
746 return;
750 int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd)
752 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
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);
774 return NDIS_STATUS_SUCCESS;
777 void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd)
779 struct os_cookie *pObj;
781 pObj = (struct os_cookie *)pAd->OS_Cookie;
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);