2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
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. *
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. *
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. *
25 *************************************************************************
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 ========================================================================
68 Create kernel threads & tasklets.
71 *net_dev Pointer to wireless net device interface
78 ========================================================================
80 int RtmpMgmtTaskInit(struct rt_rtmp_adapter
*pAd
)
82 struct rt_rtmp_os_task
*pTask
;
86 Creat TimerQ Thread, We need init timerQ related structure before create the timer thread.
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 ========================================================================
125 Close kernel threads.
128 *pAd the raxx interface data pointer
134 ========================================================================
136 void RtmpMgmtTaskExit(struct rt_rtmp_adapter
*pAd
)
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. */
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
->
162 /* Terminate cmdQ thread */
163 pTask
= &pAd
->cmdQTask
;
164 #ifdef KTHREAD_SUPPORT
165 if (pTask
->kthread_task
)
167 CHECK_PID_LEGALITY(pTask
->taskPID
)
171 NdisAcquireSpinLock(&pAd
->CmdQLock
);
172 pAd
->CmdQ
.CmdQState
= RTMP_TASK_STAT_STOPED
;
173 NdisReleaseSpinLock(&pAd
->CmdQLock
);
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
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
->
198 static void rtusb_dataout_complete(unsigned long data
)
200 struct rt_rtmp_adapter
*pAd
;
202 struct os_cookie
*pObj
;
203 struct rt_ht_tx_context
*pHTTXContext
;
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 */
239 pAd
->BulkOutCompleteOther
++;
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",
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)); */
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. */
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
<<
282 /* Indicate There is data avaliable */
283 RTUSB_SET_BULK_FLAG(pAd
,
284 (fRTUSB_BULK_OUT_DATA_NORMAL
<<
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
;
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",
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
,
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
;
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
,
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
;
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
,
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 ========================================================================
438 Handle received packets.
441 data - URB information pointer
447 ========================================================================
449 static void rx_done_tasklet(unsigned long data
)
452 struct rt_rx_context
*pRxContext
;
453 struct rt_rtmp_adapter
*pAd
;
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); */
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
,
501 ASSERT((pRxContext
->InUse
== pRxContext
->IRPPending
));
503 RTUSBBulkReceive(pAd
);
509 static void rtusb_mgmt_dma_done_tasklet(unsigned long data
)
511 struct rt_rtmp_adapter
*pAd
;
512 struct rt_tx_context
*pMLMEContext
;
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",
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. */
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. */
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
,
577 /* Always call Bulk routine, even reset bulk. */
578 /* The protectioon of rest bulk should be in BulkOut routine */
579 if (pAd
->MgmtRing
.TxSwFreeIdx
<
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;
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. */
608 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)) {
609 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
,
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
,
621 RTUSB_SET_BULK_FLAG(pAd
,
622 fRTUSB_BULK_OUT_DATA_NORMAL
<< 3);
623 RTUSBKickBulkOut(pAd
);
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;
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. */
648 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)) {
649 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
,
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
,
661 RTUSB_SET_BULK_FLAG(pAd
,
662 fRTUSB_BULK_OUT_DATA_NORMAL
<< 2);
663 RTUSBKickBulkOut(pAd
);
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;
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. */
688 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)) {
689 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
,
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
,
701 RTUSB_SET_BULK_FLAG(pAd
,
702 fRTUSB_BULK_OUT_DATA_NORMAL
<< 1);
703 RTUSBKickBulkOut(pAd
);
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;
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. */
728 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)) {
729 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
,
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
,
741 RTUSB_SET_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL
);
742 RTUSBKickBulkOut(pAd
);
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
,
758 tasklet_init(&pObj
->ac0_dma_done_task
, rtusb_ac0_dma_done_tasklet
,
760 tasklet_init(&pObj
->ac1_dma_done_task
, rtusb_ac1_dma_done_tasklet
,
762 tasklet_init(&pObj
->ac2_dma_done_task
, rtusb_ac2_dma_done_tasklet
,
764 tasklet_init(&pObj
->ac3_dma_done_task
, rtusb_ac3_dma_done_tasklet
,
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
);