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
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 ========================================================================
69 Create kernel threads & tasklets.
72 *net_dev Pointer to wireless net device interface
79 ========================================================================
81 int RtmpMgmtTaskInit(struct rt_rtmp_adapter
*pAd
)
83 struct rt_rtmp_os_task
*pTask
;
87 Creat TimerQ Thread, We need init timerQ related structure before create the timer thread.
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 ========================================================================
126 Close kernel threads.
129 *pAd the raxx interface data pointer
135 ========================================================================
137 void RtmpMgmtTaskExit(struct rt_rtmp_adapter
*pAd
)
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. */
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
->
163 /* Terminate cmdQ thread */
164 pTask
= &pAd
->cmdQTask
;
165 #ifdef KTHREAD_SUPPORT
166 if (pTask
->kthread_task
)
168 CHECK_PID_LEGALITY(pTask
->taskPID
)
172 NdisAcquireSpinLock(&pAd
->CmdQLock
);
173 pAd
->CmdQ
.CmdQState
= RTMP_TASK_STAT_STOPED
;
174 NdisReleaseSpinLock(&pAd
->CmdQLock
);
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
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
->
199 static void rtusb_dataout_complete(unsigned long data
)
201 struct rt_rtmp_adapter
*pAd
;
203 struct os_cookie
*pObj
;
204 struct rt_ht_tx_context
*pHTTXContext
;
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 */
240 pAd
->BulkOutCompleteOther
++;
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",
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)); */
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. */
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
<<
283 /* Indicate There is data available */
284 RTUSB_SET_BULK_FLAG(pAd
,
285 (fRTUSB_BULK_OUT_DATA_NORMAL
<<
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
;
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",
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
,
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
;
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
,
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
;
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
,
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 ========================================================================
439 Handle received packets.
442 data - URB information pointer
448 ========================================================================
450 static void rx_done_tasklet(unsigned long data
)
453 struct rt_rx_context
*pRxContext
;
454 struct rt_rtmp_adapter
*pAd
;
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); */
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
,
502 ASSERT((pRxContext
->InUse
== pRxContext
->IRPPending
));
504 RTUSBBulkReceive(pAd
);
510 static void rtusb_mgmt_dma_done_tasklet(unsigned long data
)
512 struct rt_rtmp_adapter
*pAd
;
513 struct rt_tx_context
*pMLMEContext
;
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",
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. */
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. */
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
,
578 /* Always call Bulk routine, even reset bulk. */
579 /* The protection of rest bulk should be in BulkOut routine */
580 if (pAd
->MgmtRing
.TxSwFreeIdx
<
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;
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. */
609 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)) {
610 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
,
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
,
622 RTUSB_SET_BULK_FLAG(pAd
,
623 fRTUSB_BULK_OUT_DATA_NORMAL
<< 3);
624 RTUSBKickBulkOut(pAd
);
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;
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. */
649 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)) {
650 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
,
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
,
662 RTUSB_SET_BULK_FLAG(pAd
,
663 fRTUSB_BULK_OUT_DATA_NORMAL
<< 2);
664 RTUSBKickBulkOut(pAd
);
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;
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. */
689 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)) {
690 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
,
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
,
702 RTUSB_SET_BULK_FLAG(pAd
,
703 fRTUSB_BULK_OUT_DATA_NORMAL
<< 1);
704 RTUSBKickBulkOut(pAd
);
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;
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. */
729 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)) {
730 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
,
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
,
742 RTUSB_SET_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL
);
743 RTUSBKickBulkOut(pAd
);
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
,
759 tasklet_init(&pObj
->ac0_dma_done_task
, rtusb_ac0_dma_done_tasklet
,
761 tasklet_init(&pObj
->ac1_dma_done_task
, rtusb_ac1_dma_done_tasklet
,
763 tasklet_init(&pObj
->ac2_dma_done_task
, rtusb_ac2_dma_done_tasklet
,
765 tasklet_init(&pObj
->ac3_dma_done_task
, rtusb_ac3_dma_done_tasklet
,
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
);