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 *************************************************************************
31 Miniport generic portion header file
35 -------- ---------- ----------------------------------------------
36 Paul Lin 2002-08-01 created
37 John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme
38 Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
39 Sample Lin 2007-05-31 Merge RT2860 and RT2870 drivers.
42 #include "../rt_config.h"
45 static void rx_done_tasklet(unsigned long data
);
46 static void rt2870_hcca_dma_done_tasklet(unsigned long data
);
47 static void rt2870_ac3_dma_done_tasklet(unsigned long data
);
48 static void rt2870_ac2_dma_done_tasklet(unsigned long data
);
49 static void rt2870_ac1_dma_done_tasklet(unsigned long data
);
50 static void rt2870_ac0_dma_done_tasklet(unsigned long data
);
51 static void rt2870_mgmt_dma_done_tasklet(unsigned long data
);
52 static void rt2870_null_frame_complete_tasklet(unsigned long data
);
53 static void rt2870_rts_frame_complete_tasklet(unsigned long data
);
54 static void rt2870_pspoll_frame_complete_tasklet(unsigned long data
);
55 static void rt2870_dataout_complete_tasklet(unsigned long data
);
59 ========================================================================
61 Initialize receive data structures.
64 pAd Pointer to our adapter
71 Initialize all receive releated private buffer, include those define
72 in RTMP_ADAPTER structure and all private data structures. The mahor
73 work is to allocate buffer for each packet and chain buffer to
74 NDIS packet descriptor.
75 ========================================================================
77 NDIS_STATUS
NICInitRecv(
81 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
82 POS_COOKIE pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
85 DBGPRINT(RT_DEBUG_TRACE
, ("--> NICInitRecv\n"));
88 //InterlockedExchange(&pAd->PendingRx, 0);
90 pAd
->NextRxBulkInReadIndex
= 0; // Next Rx Read index
91 pAd
->NextRxBulkInIndex
= 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
92 pAd
->NextRxBulkInPosition
= 0;
94 for (i
= 0; i
< (RX_RING_SIZE
); i
++)
96 PRX_CONTEXT pRxContext
= &(pAd
->RxContext
[i
]);
99 pRxContext
->pUrb
= RTUSB_ALLOC_URB(0);
100 if (pRxContext
->pUrb
== NULL
)
102 Status
= NDIS_STATUS_RESOURCES
;
106 // Allocate transfer buffer
107 pRxContext
->TransferBuffer
= RTUSB_URB_ALLOC_BUFFER(pObj
->pUsb_Dev
, MAX_RXBULK_SIZE
, &pRxContext
->data_dma
);
108 if (pRxContext
->TransferBuffer
== NULL
)
110 Status
= NDIS_STATUS_RESOURCES
;
114 NdisZeroMemory(pRxContext
->TransferBuffer
, MAX_RXBULK_SIZE
);
116 pRxContext
->pAd
= pAd
;
117 pRxContext
->pIrp
= NULL
;
118 pRxContext
->InUse
= FALSE
;
119 pRxContext
->IRPPending
= FALSE
;
120 pRxContext
->Readable
= FALSE
;
121 //pRxContext->ReorderInUse = FALSE;
122 pRxContext
->bRxHandling
= FALSE
;
123 pRxContext
->BulkInOffset
= 0;
126 DBGPRINT(RT_DEBUG_TRACE
, ("<-- NICInitRecv\n"));
130 for (i
= 0; i
< (RX_RING_SIZE
); i
++)
132 PRX_CONTEXT pRxContext
= &(pAd
->RxContext
[i
]);
134 if (NULL
!= pRxContext
->TransferBuffer
)
136 RTUSB_URB_FREE_BUFFER(pObj
->pUsb_Dev
, MAX_RXBULK_SIZE
,
137 pRxContext
->TransferBuffer
, pRxContext
->data_dma
);
138 pRxContext
->TransferBuffer
= NULL
;
141 if (NULL
!= pRxContext
->pUrb
)
143 RTUSB_UNLINK_URB(pRxContext
->pUrb
);
144 RTUSB_FREE_URB(pRxContext
->pUrb
);
145 pRxContext
->pUrb
= NULL
;
154 ========================================================================
156 Initialize transmit data structures.
159 pAd Pointer to our adapter
163 NDIS_STATUS_RESOURCES
166 ========================================================================
168 NDIS_STATUS
NICInitTransmit(
169 IN PRTMP_ADAPTER pAd
)
171 #define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \
172 Context->pUrb = RTUSB_ALLOC_URB(0); \
173 if (Context->pUrb == NULL) { \
174 DBGPRINT(RT_DEBUG_ERROR, msg1); \
175 Status = NDIS_STATUS_RESOURCES; \
178 Context->TransferBuffer = \
179 (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \
180 if (Context->TransferBuffer == NULL) { \
181 DBGPRINT(RT_DEBUG_ERROR, msg2); \
182 Status = NDIS_STATUS_RESOURCES; \
185 #define LM_URB_FREE(pObj, Context, BufferSize) \
186 if (NULL != Context->pUrb) { \
187 RTUSB_UNLINK_URB(Context->pUrb); \
188 RTUSB_FREE_URB(Context->pUrb); \
189 Context->pUrb = NULL; } \
190 if (NULL != Context->TransferBuffer) { \
191 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
192 Context->TransferBuffer, \
193 Context->data_dma); \
194 Context->TransferBuffer = NULL; }
197 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
198 PTX_CONTEXT pNullContext
= &(pAd
->NullContext
);
199 PTX_CONTEXT pPsPollContext
= &(pAd
->PsPollContext
);
200 PTX_CONTEXT pRTSContext
= &(pAd
->RTSContext
);
201 PTX_CONTEXT pMLMEContext
= NULL
;
202 // PHT_TX_CONTEXT pHTTXContext = NULL;
203 POS_COOKIE pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
205 // RTMP_TX_RING *pTxRing;
206 RTMP_MGMT_RING
*pMgmtRing
;
208 DBGPRINT(RT_DEBUG_TRACE
, ("--> NICInitTransmit\n"));
211 // Init 4 set of Tx parameters
212 for(acidx
= 0; acidx
< NUM_OF_TX_RING
; acidx
++)
214 // Initialize all Transmit releated queues
215 InitializeQueueHeader(&pAd
->TxSwQueue
[acidx
]);
217 // Next Local tx ring pointer waiting for buck out
218 pAd
->NextBulkOutIndex
[acidx
] = acidx
;
219 pAd
->BulkOutPending
[acidx
] = FALSE
; // Buck Out control flag
220 //pAd->DataBulkDoneIdx[acidx] = 0;
223 //pAd->NextMLMEIndex = 0;
224 //pAd->PushMgmtIndex = 0;
225 //pAd->PopMgmtIndex = 0;
226 //InterlockedExchange(&pAd->MgmtQueueSize, 0);
227 //InterlockedExchange(&pAd->TxCount, 0);
229 //pAd->PrioRingFirstIndex = 0;
230 //pAd->PrioRingTxCnt = 0;
235 // TX_RING_SIZE, 4 ACs
237 for(acidx
=0; acidx
<4; acidx
++)
239 PHT_TX_CONTEXT pHTTXContext
= &(pAd
->TxContext
[acidx
]);
241 NdisZeroMemory(pHTTXContext
, sizeof(HT_TX_CONTEXT
));
243 LM_USB_ALLOC(pObj
, pHTTXContext
, PHTTX_BUFFER
, sizeof(HTTX_BUFFER
), Status
,
244 ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx
),
246 ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx
),
249 NdisZeroMemory(pHTTXContext
->TransferBuffer
->Aggregation
, 4);
250 pHTTXContext
->pAd
= pAd
;
251 pHTTXContext
->pIrp
= NULL
;
252 pHTTXContext
->IRPPending
= FALSE
;
253 pHTTXContext
->NextBulkOutPosition
= 0;
254 pHTTXContext
->ENextBulkOutPosition
= 0;
255 pHTTXContext
->CurWritePosition
= 0;
256 pHTTXContext
->CurWriteRealPos
= 0;
257 pHTTXContext
->BulkOutSize
= 0;
258 pHTTXContext
->BulkOutPipeId
= acidx
;
259 pHTTXContext
->bRingEmpty
= TRUE
;
260 pHTTXContext
->bCopySavePad
= FALSE
;
262 pAd
->BulkOutPending
[acidx
] = FALSE
;
269 // Allocate MGMT ring descriptor's memory
270 pAd
->MgmtDescRing
.AllocSize
= MGMT_RING_SIZE
* sizeof(TX_CONTEXT
);
271 RTMPAllocateMemory(&pAd
->MgmtDescRing
.AllocVa
, pAd
->MgmtDescRing
.AllocSize
);
272 if (pAd
->MgmtDescRing
.AllocVa
== NULL
)
274 DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
275 Status
= NDIS_STATUS_RESOURCES
;
278 NdisZeroMemory(pAd
->MgmtDescRing
.AllocVa
, pAd
->MgmtDescRing
.AllocSize
);
279 RingBaseVa
= pAd
->MgmtDescRing
.AllocVa
;
281 // Initialize MGMT Ring and associated buffer memory
282 pMgmtRing
= &pAd
->MgmtRing
;
283 for (i
= 0; i
< MGMT_RING_SIZE
; i
++)
285 // link the pre-allocated Mgmt buffer to MgmtRing.Cell
286 pMgmtRing
->Cell
[i
].AllocSize
= sizeof(TX_CONTEXT
);
287 pMgmtRing
->Cell
[i
].AllocVa
= RingBaseVa
;
288 pMgmtRing
->Cell
[i
].pNdisPacket
= NULL
;
289 pMgmtRing
->Cell
[i
].pNextNdisPacket
= NULL
;
291 //Allocate URB for MLMEContext
292 pMLMEContext
= (PTX_CONTEXT
) pAd
->MgmtRing
.Cell
[i
].AllocVa
;
293 pMLMEContext
->pUrb
= RTUSB_ALLOC_URB(0);
294 if (pMLMEContext
->pUrb
== NULL
)
296 DBGPRINT(RT_DEBUG_ERROR
, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i
));
297 Status
= NDIS_STATUS_RESOURCES
;
300 pMLMEContext
->pAd
= pAd
;
301 pMLMEContext
->pIrp
= NULL
;
302 pMLMEContext
->TransferBuffer
= NULL
;
303 pMLMEContext
->InUse
= FALSE
;
304 pMLMEContext
->IRPPending
= FALSE
;
305 pMLMEContext
->bWaitingBulkOut
= FALSE
;
306 pMLMEContext
->BulkOutSize
= 0;
307 pMLMEContext
->SelfIdx
= i
;
309 // Offset to next ring descriptor address
310 RingBaseVa
= (PUCHAR
) RingBaseVa
+ sizeof(TX_CONTEXT
);
312 DBGPRINT(RT_DEBUG_TRACE
, ("MGMT Ring: total %d entry allocated\n", i
));
314 //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
315 pAd
->MgmtRing
.TxSwFreeIdx
= MGMT_RING_SIZE
;
316 pAd
->MgmtRing
.TxCpuIdx
= 0;
317 pAd
->MgmtRing
.TxDmaIdx
= 0;
322 for(i
=0; i
<BEACON_RING_SIZE
; i
++) // 2
324 PTX_CONTEXT pBeaconContext
= &(pAd
->BeaconContext
[i
]);
327 NdisZeroMemory(pBeaconContext
, sizeof(TX_CONTEXT
));
330 LM_USB_ALLOC(pObj
, pBeaconContext
, PTX_BUFFER
, sizeof(TX_BUFFER
), Status
,
331 ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i
),
333 ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i
),
336 pBeaconContext
->pAd
= pAd
;
337 pBeaconContext
->pIrp
= NULL
;
338 pBeaconContext
->InUse
= FALSE
;
339 pBeaconContext
->IRPPending
= FALSE
;
345 NdisZeroMemory(pNullContext
, sizeof(TX_CONTEXT
));
348 LM_USB_ALLOC(pObj
, pNullContext
, PTX_BUFFER
, sizeof(TX_BUFFER
), Status
,
349 ("<-- ERROR in Alloc TX NullContext urb!! \n"),
351 ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
354 pNullContext
->pAd
= pAd
;
355 pNullContext
->pIrp
= NULL
;
356 pNullContext
->InUse
= FALSE
;
357 pNullContext
->IRPPending
= FALSE
;
362 NdisZeroMemory(pRTSContext
, sizeof(TX_CONTEXT
));
365 LM_USB_ALLOC(pObj
, pRTSContext
, PTX_BUFFER
, sizeof(TX_BUFFER
), Status
,
366 ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
368 ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
371 pRTSContext
->pAd
= pAd
;
372 pRTSContext
->pIrp
= NULL
;
373 pRTSContext
->InUse
= FALSE
;
374 pRTSContext
->IRPPending
= FALSE
;
379 //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
381 LM_USB_ALLOC(pObj
, pPsPollContext
, PTX_BUFFER
, sizeof(TX_BUFFER
), Status
,
382 ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
384 ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
387 pPsPollContext
->pAd
= pAd
;
388 pPsPollContext
->pIrp
= NULL
;
389 pPsPollContext
->InUse
= FALSE
;
390 pPsPollContext
->IRPPending
= FALSE
;
391 pPsPollContext
->bAggregatible
= FALSE
;
392 pPsPollContext
->LastOne
= TRUE
;
398 DBGPRINT(RT_DEBUG_TRACE
, ("<-- NICInitTransmit\n"));
402 /* --------------------------- ERROR HANDLE --------------------------- */
404 LM_URB_FREE(pObj
, pPsPollContext
, sizeof(TX_BUFFER
));
407 LM_URB_FREE(pObj
, pRTSContext
, sizeof(TX_BUFFER
));
410 LM_URB_FREE(pObj
, pNullContext
, sizeof(TX_BUFFER
));
413 for(i
=0; i
<BEACON_RING_SIZE
; i
++)
415 PTX_CONTEXT pBeaconContext
= &(pAd
->BeaconContext
[i
]);
417 LM_URB_FREE(pObj
, pBeaconContext
, sizeof(TX_BUFFER
));
421 if (pAd
->MgmtDescRing
.AllocVa
)
423 pMgmtRing
= &pAd
->MgmtRing
;
424 for(i
=0; i
<MGMT_RING_SIZE
; i
++)
426 pMLMEContext
= (PTX_CONTEXT
) pAd
->MgmtRing
.Cell
[i
].AllocVa
;
428 LM_URB_FREE(pObj
, pMLMEContext
, sizeof(TX_BUFFER
));
430 NdisFreeMemory(pAd
->MgmtDescRing
.AllocVa
, pAd
->MgmtDescRing
.AllocSize
, 0);
431 pAd
->MgmtDescRing
.AllocVa
= NULL
;
435 for (acidx
= 0; acidx
< 4; acidx
++)
437 PHT_TX_CONTEXT pTxContext
= &(pAd
->TxContext
[acidx
]);
439 LM_URB_FREE(pObj
, pTxContext
, sizeof(HTTX_BUFFER
));
442 // Here we didn't have any pre-allocated memory need to free.
449 ========================================================================
451 Allocate DMA memory blocks for send, receive.
454 pAd Pointer to our adapter
459 NDIS_STATUS_RESOURCES
462 ========================================================================
464 NDIS_STATUS
RTMPAllocTxRxRingMemory(
465 IN PRTMP_ADAPTER pAd
)
467 // COUNTER_802_11 pCounter = &pAd->WlanCounters;
472 DBGPRINT(RT_DEBUG_TRACE
, ("--> RTMPAllocTxRxRingMemory\n"));
477 // Init the CmdQ and CmdQLock
478 NdisAllocateSpinLock(&pAd
->CmdQLock
);
479 NdisAcquireSpinLock(&pAd
->CmdQLock
);
480 RTUSBInitializeCmdQ(&pAd
->CmdQ
);
481 NdisReleaseSpinLock(&pAd
->CmdQLock
);
484 NdisAllocateSpinLock(&pAd
->MLMEBulkOutLock
);
485 //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
486 NdisAllocateSpinLock(&pAd
->BulkOutLock
[0]);
487 NdisAllocateSpinLock(&pAd
->BulkOutLock
[1]);
488 NdisAllocateSpinLock(&pAd
->BulkOutLock
[2]);
489 NdisAllocateSpinLock(&pAd
->BulkOutLock
[3]);
490 NdisAllocateSpinLock(&pAd
->BulkOutLock
[4]);
491 NdisAllocateSpinLock(&pAd
->BulkOutLock
[5]);
492 NdisAllocateSpinLock(&pAd
->BulkInLock
);
494 for (num
= 0; num
< NUM_OF_TX_RING
; num
++)
496 NdisAllocateSpinLock(&pAd
->TxContextQueueLock
[num
]);
499 // NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX
501 // NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
502 // NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
504 // for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
506 // NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
512 // MacTableInitialize(pAd);
515 // Init send data structures and related parameters
517 Status
= NICInitTransmit(pAd
);
518 if (Status
!= NDIS_STATUS_SUCCESS
)
522 // Init receive data structures and related parameters
524 Status
= NICInitRecv(pAd
);
525 if (Status
!= NDIS_STATUS_SUCCESS
)
528 pAd
->PendingIoCount
= 1;
532 NdisZeroMemory(&pAd
->FragFrame
, sizeof(FRAGMENT_FRAME
));
533 pAd
->FragFrame
.pFragPacket
= RTMP_AllocateFragPacketBuffer(pAd
, RX_BUFFER_NORMSIZE
);
535 if (pAd
->FragFrame
.pFragPacket
== NULL
)
537 Status
= NDIS_STATUS_RESOURCES
;
540 DBGPRINT_S(Status
, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status
));
546 ========================================================================
548 Calls USB_InterfaceStop and frees memory allocated for the URBs
549 calls NdisMDeregisterDevice and frees the memory
550 allocated in VNetInitialize for the Adapter Object
553 *pAd the raxx interface data pointer
559 ========================================================================
561 VOID
RTMPFreeTxRxRingMemory(
562 IN PRTMP_ADAPTER pAd
)
564 #define LM_URB_FREE(pObj, Context, BufferSize) \
565 if (NULL != Context->pUrb) { \
566 RTUSB_UNLINK_URB(Context->pUrb); \
567 RTUSB_FREE_URB(Context->pUrb); \
568 Context->pUrb = NULL; } \
569 if (NULL != Context->TransferBuffer) { \
570 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
571 Context->TransferBuffer, \
572 Context->data_dma); \
573 Context->TransferBuffer = NULL; }
577 PTX_CONTEXT pNullContext
= &pAd
->NullContext
;
578 PTX_CONTEXT pPsPollContext
= &pAd
->PsPollContext
;
579 PTX_CONTEXT pRTSContext
= &pAd
->RTSContext
;
580 // PHT_TX_CONTEXT pHTTXContext;
581 //PRTMP_REORDERBUF pReorderBuf;
582 POS_COOKIE pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
583 // RTMP_TX_RING *pTxRing;
585 DBGPRINT(RT_DEBUG_ERROR
, ("---> RTMPFreeTxRxRingMemory\n"));
588 // Free all resources for the RECEIVE buffer queue.
589 for(i
=0; i
<(RX_RING_SIZE
); i
++)
591 PRX_CONTEXT pRxContext
= &(pAd
->RxContext
[i
]);
593 LM_URB_FREE(pObj
, pRxContext
, MAX_RXBULK_SIZE
);
596 // Free PsPoll frame resource
597 LM_URB_FREE(pObj
, pPsPollContext
, sizeof(TX_BUFFER
));
599 // Free NULL frame resource
600 LM_URB_FREE(pObj
, pNullContext
, sizeof(TX_BUFFER
));
602 // Free RTS frame resource
603 LM_URB_FREE(pObj
, pRTSContext
, sizeof(TX_BUFFER
));
606 // Free beacon frame resource
607 for(i
=0; i
<BEACON_RING_SIZE
; i
++)
609 PTX_CONTEXT pBeaconContext
= &(pAd
->BeaconContext
[i
]);
611 LM_URB_FREE(pObj
, pBeaconContext
, sizeof(TX_BUFFER
));
615 // Free mgmt frame resource
616 for(i
= 0; i
< MGMT_RING_SIZE
; i
++)
618 PTX_CONTEXT pMLMEContext
= (PTX_CONTEXT
)pAd
->MgmtRing
.Cell
[i
].AllocVa
;
619 //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
620 if (NULL
!= pAd
->MgmtRing
.Cell
[i
].pNdisPacket
)
622 RTMPFreeNdisPacket(pAd
, pAd
->MgmtRing
.Cell
[i
].pNdisPacket
);
623 pAd
->MgmtRing
.Cell
[i
].pNdisPacket
= NULL
;
624 pMLMEContext
->TransferBuffer
= NULL
;
629 if (NULL
!= pMLMEContext
->pUrb
)
631 RTUSB_UNLINK_URB(pMLMEContext
->pUrb
);
632 RTUSB_FREE_URB(pMLMEContext
->pUrb
);
633 pMLMEContext
->pUrb
= NULL
;
637 if (pAd
->MgmtDescRing
.AllocVa
)
638 NdisFreeMemory(pAd
->MgmtDescRing
.AllocVa
, pAd
->MgmtDescRing
.AllocSize
, 0);
641 // Free Tx frame resource
642 for(acidx
=0; acidx
<4; acidx
++)
644 PHT_TX_CONTEXT pHTTXContext
= &(pAd
->TxContext
[acidx
]);
646 LM_URB_FREE(pObj
, pHTTXContext
, sizeof(HTTX_BUFFER
));
649 if (pAd
->FragFrame
.pFragPacket
)
650 RELEASE_NDIS_PACKET(pAd
, pAd
->FragFrame
.pFragPacket
, NDIS_STATUS_SUCCESS
);
654 NdisFreeSpinLock(&pAd
->BulkOutLock
[i
]);
657 NdisFreeSpinLock(&pAd
->BulkInLock
);
658 NdisFreeSpinLock(&pAd
->MLMEBulkOutLock
);
660 NdisFreeSpinLock(&pAd
->CmdQLock
);
662 // Clear all pending bulk-out request flags.
663 RTUSB_CLEAR_BULK_FLAG(pAd
, 0xffffffff);
665 // NdisFreeSpinLock(&pAd->MacTabLock);
667 // for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
669 // NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
672 DBGPRINT(RT_DEBUG_ERROR
, ("<--- ReleaseAdapter\n"));
677 ========================================================================
679 Allocate memory for adapter control block.
682 pAd Pointer to our adapter
687 NDIS_STATUS_RESOURCES
690 ========================================================================
692 NDIS_STATUS
AdapterBlockAllocateMemory(
697 POS_COOKIE pObj
= (POS_COOKIE
) handle
;
700 usb_dev
= pObj
->pUsb_Dev
;
702 pObj
->MLMEThr_pid
= NULL
;
703 pObj
->RTUSBCmdThr_pid
= NULL
;
705 *ppAd
= (PVOID
)vmalloc(sizeof(RTMP_ADAPTER
));
709 NdisZeroMemory(*ppAd
, sizeof(RTMP_ADAPTER
));
710 ((PRTMP_ADAPTER
)*ppAd
)->OS_Cookie
= handle
;
711 return (NDIS_STATUS_SUCCESS
);
715 return (NDIS_STATUS_FAILURE
);
721 ========================================================================
723 Create kernel threads & tasklets.
726 *net_dev Pointer to wireless net device interface
733 ========================================================================
735 NDIS_STATUS
CreateThreads(
736 IN
struct net_device
*net_dev
)
738 PRTMP_ADAPTER pAd
= net_dev
->ml_priv
;
739 POS_COOKIE pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
742 //init_MUTEX(&(pAd->usbdev_semaphore));
744 init_MUTEX_LOCKED(&(pAd
->mlme_semaphore
));
745 init_completion (&pAd
->mlmeComplete
);
747 init_MUTEX_LOCKED(&(pAd
->RTUSBCmd_semaphore
));
748 init_completion (&pAd
->CmdQComplete
);
750 init_MUTEX_LOCKED(&(pAd
->RTUSBTimer_semaphore
));
751 init_completion (&pAd
->TimerQComplete
);
754 pObj
->MLMEThr_pid
= NULL
;
755 pid_number
= kernel_thread(MlmeThread
, pAd
, CLONE_VM
);
758 printk (KERN_WARNING
"%s: unable to start Mlme thread\n",pAd
->net_dev
->name
);
759 return NDIS_STATUS_FAILURE
;
762 pObj
->MLMEThr_pid
= find_get_pid(pid_number
);
764 // Wait for the thread to start
765 wait_for_completion(&(pAd
->mlmeComplete
));
767 // Creat Command Thread
768 pObj
->RTUSBCmdThr_pid
= NULL
;
769 pid_number
= kernel_thread(RTUSBCmdThread
, pAd
, CLONE_VM
);
772 printk (KERN_WARNING
"%s: unable to start RTUSBCmd thread\n",pAd
->net_dev
->name
);
773 return NDIS_STATUS_FAILURE
;
776 pObj
->RTUSBCmdThr_pid
= find_get_pid(pid_number
);
778 wait_for_completion(&(pAd
->CmdQComplete
));
780 pObj
->TimerQThr_pid
= NULL
;
781 pid_number
= kernel_thread(TimerQThread
, pAd
, CLONE_VM
);
784 printk (KERN_WARNING
"%s: unable to start TimerQThread\n",pAd
->net_dev
->name
);
785 return NDIS_STATUS_FAILURE
;
788 pObj
->TimerQThr_pid
= find_get_pid(pid_number
);
790 // Wait for the thread to start
791 wait_for_completion(&(pAd
->TimerQComplete
));
793 // Create receive tasklet
794 tasklet_init(&pObj
->rx_done_task
, rx_done_tasklet
, (ULONG
)pAd
);
795 tasklet_init(&pObj
->mgmt_dma_done_task
, rt2870_mgmt_dma_done_tasklet
, (unsigned long)pAd
);
796 tasklet_init(&pObj
->ac0_dma_done_task
, rt2870_ac0_dma_done_tasklet
, (unsigned long)pAd
);
797 tasklet_init(&pObj
->ac1_dma_done_task
, rt2870_ac1_dma_done_tasklet
, (unsigned long)pAd
);
798 tasklet_init(&pObj
->ac2_dma_done_task
, rt2870_ac2_dma_done_tasklet
, (unsigned long)pAd
);
799 tasklet_init(&pObj
->ac3_dma_done_task
, rt2870_ac3_dma_done_tasklet
, (unsigned long)pAd
);
800 tasklet_init(&pObj
->hcca_dma_done_task
, rt2870_hcca_dma_done_tasklet
, (unsigned long)pAd
);
801 tasklet_init(&pObj
->tbtt_task
, tbtt_tasklet
, (unsigned long)pAd
);
802 tasklet_init(&pObj
->null_frame_complete_task
, rt2870_null_frame_complete_tasklet
, (unsigned long)pAd
);
803 tasklet_init(&pObj
->rts_frame_complete_task
, rt2870_rts_frame_complete_tasklet
, (unsigned long)pAd
);
804 tasklet_init(&pObj
->pspoll_frame_complete_task
, rt2870_pspoll_frame_complete_tasklet
, (unsigned long)pAd
);
806 return NDIS_STATUS_SUCCESS
;
810 ========================================================================
812 As STA's BSSID is a WC too, it uses shared key table.
813 This function write correct unicast TX key to ASIC WCID.
814 And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
815 Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
816 Caller guarantee WEP calls this function when set Txkey, default key index=0~3.
819 pAd Pointer to our adapter
820 pKey Pointer to the where the key stored
823 NDIS_SUCCESS Add key successfully
826 ========================================================================
828 VOID
RTMPAddBSSIDCipher(
829 IN PRTMP_ADAPTER pAd
,
831 IN PNDIS_802_11_KEY pKey
,
834 PUCHAR pTxMic
, pRxMic
;
835 BOOLEAN bKeyRSC
, bAuthenticator
; // indicate the receive SC set by KeyRSC value
840 UCHAR KeyIdx
, IVEIV
[8];
843 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid
));
845 // Bit 29 of Add-key KeyRSC
846 bKeyRSC
= (pKey
->KeyIndex
& 0x20000000) ? TRUE
: FALSE
;
848 // Bit 28 of Add-key Authenticator
849 bAuthenticator
= (pKey
->KeyIndex
& 0x10000000) ? TRUE
: FALSE
;
850 KeyIdx
= (UCHAR
)pKey
->KeyIndex
&0xff;
856 if (pAd
->MacTab
.Content
[Aid
].PairwiseKey
.CipherAlg
== CIPHER_TKIP
)
857 { if (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPANone
)
859 // for WPA-None Tx, Rx MIC is the same
860 pTxMic
= (PUCHAR
) (&pKey
->KeyMaterial
) + 16;
863 else if (bAuthenticator
== TRUE
)
865 pTxMic
= (PUCHAR
) (&pKey
->KeyMaterial
) + 16;
866 pRxMic
= (PUCHAR
) (&pKey
->KeyMaterial
) + 24;
870 pRxMic
= (PUCHAR
) (&pKey
->KeyMaterial
) + 16;
871 pTxMic
= (PUCHAR
) (&pKey
->KeyMaterial
) + 24;
874 offset
= PAIRWISE_KEY_TABLE_BASE
+ (Aid
* HW_KEY_ENTRY_SIZE
) + 0x10;
878 Value
+= (*(pTxMic
+i
+1)<<8);
879 Value
+= (*(pTxMic
+i
+2)<<16);
880 Value
+= (*(pTxMic
+i
+3)<<24);
881 RTUSBWriteMACRegister(pAd
, offset
+i
, Value
);
885 offset
= PAIRWISE_KEY_TABLE_BASE
+ (Aid
* HW_KEY_ENTRY_SIZE
) + 0x18;
889 Value
+= (*(pRxMic
+i
+1)<<8);
890 Value
+= (*(pRxMic
+i
+2)<<16);
891 Value
+= (*(pRxMic
+i
+3)<<24);
892 RTUSBWriteMACRegister(pAd
, offset
+i
, Value
);
896 // Only Key lenth equal to TKIP key have these
897 NdisMoveMemory(pAd
->MacTab
.Content
[Aid
].PairwiseKey
.RxMic
, pRxMic
, 8);
898 NdisMoveMemory(pAd
->MacTab
.Content
[Aid
].PairwiseKey
.TxMic
, pTxMic
, 8);
900 DBGPRINT(RT_DEBUG_TRACE
,
901 (" TxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
902 pTxMic
[0],pTxMic
[1],pTxMic
[2],pTxMic
[3],
903 pTxMic
[4],pTxMic
[5],pTxMic
[6],pTxMic
[7]));
904 DBGPRINT(RT_DEBUG_TRACE
,
905 (" RxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
906 pRxMic
[0],pRxMic
[1],pRxMic
[2],pRxMic
[3],
907 pRxMic
[4],pRxMic
[5],pRxMic
[6],pRxMic
[7]));
910 // 2. Record Security Key.
911 pAd
->MacTab
.Content
[BSSID_WCID
].PairwiseKey
.KeyLen
= (UCHAR
)pKey
->KeyLength
;
912 NdisMoveMemory(pAd
->MacTab
.Content
[Aid
].PairwiseKey
.Key
, &pKey
->KeyMaterial
, pKey
->KeyLength
);
914 // 3. Check RxTsc. And used to init to ASIC IV.
916 NdisMoveMemory(pAd
->MacTab
.Content
[Aid
].PairwiseKey
.RxTsc
, &pKey
->KeyRSC
, 6);
918 NdisZeroMemory(pAd
->MacTab
.Content
[Aid
].PairwiseKey
.RxTsc
, 6);
920 // 4. Init TxTsc to one based on WiFi WPA specs
921 pAd
->MacTab
.Content
[Aid
].PairwiseKey
.TxTsc
[0] = 1;
922 pAd
->MacTab
.Content
[Aid
].PairwiseKey
.TxTsc
[1] = 0;
923 pAd
->MacTab
.Content
[Aid
].PairwiseKey
.TxTsc
[2] = 0;
924 pAd
->MacTab
.Content
[Aid
].PairwiseKey
.TxTsc
[3] = 0;
925 pAd
->MacTab
.Content
[Aid
].PairwiseKey
.TxTsc
[4] = 0;
926 pAd
->MacTab
.Content
[Aid
].PairwiseKey
.TxTsc
[5] = 0;
928 CipherAlg
= pAd
->MacTab
.Content
[Aid
].PairwiseKey
.CipherAlg
;
930 offset
= PAIRWISE_KEY_TABLE_BASE
+ (Aid
* HW_KEY_ENTRY_SIZE
);
931 RTUSBMultiWrite(pAd
, (USHORT
) offset
, pKey
->KeyMaterial
,
932 ((pKey
->KeyLength
== LEN_TKIP_KEY
) ? 16 : (USHORT
)pKey
->KeyLength
));
934 offset
= SHARED_KEY_TABLE_BASE
+ (KeyIdx
* HW_KEY_ENTRY_SIZE
);
935 RTUSBMultiWrite(pAd
, (USHORT
) offset
, pKey
->KeyMaterial
, (USHORT
)pKey
->KeyLength
);
937 offset
= PAIRWISE_IVEIV_TABLE_BASE
+ (Aid
* HW_IVEIV_ENTRY_SIZE
);
938 NdisZeroMemory(IVEIV
, 8);
941 if ((CipherAlg
== CIPHER_TKIP
) ||
942 (CipherAlg
== CIPHER_TKIP_NO_MIC
) ||
943 (CipherAlg
== CIPHER_AES
))
945 IVEIV
[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
947 // default key idx needs to set.
948 // in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key.
951 IVEIV
[3] |= (KeyIdx
<< 6);
953 RTUSBMultiWrite(pAd
, (USHORT
) offset
, IVEIV
, 8);
955 // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
956 if ((CipherAlg
== CIPHER_TKIP
) ||
957 (CipherAlg
== CIPHER_TKIP_NO_MIC
) ||
958 (CipherAlg
== CIPHER_AES
))
960 WCIDAttri
= (CipherAlg
<<1)|SHAREDKEYTABLE
;
963 WCIDAttri
= (CipherAlg
<<1)|SHAREDKEYTABLE
;
965 offset
= MAC_WCID_ATTRIBUTE_BASE
+ (Aid
* HW_WCID_ATTRI_SIZE
);
966 RTUSBWriteMACRegister(pAd
, offset
, WCIDAttri
);
967 RTUSBReadMACRegister(pAd
, offset
, &Value
);
969 DBGPRINT(RT_DEBUG_TRACE
, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n",
973 // Add Bssid mac address at linkup. not here. check!
974 /*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE);
975 *for (i=0; i<MAC_ADDR_LEN; i++)
977 RTMP_IO_WRITE8(pAd, offset+i, pKey->BSSID[i]);
981 DBGPRINT(RT_DEBUG_ERROR
, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n",
982 CipherName
[CipherAlg
], pKey
->KeyLength
));
983 DBGPRINT(RT_DEBUG_TRACE
, ("Key [idx=%x] [KeyLen = %d]\n",
984 pKey
->KeyIndex
, pKey
->KeyLength
));
985 for(i
=0; i
<pKey
->KeyLength
; i
++)
986 DBGPRINT_RAW(RT_DEBUG_TRACE
,(" %x:", pKey
->KeyMaterial
[i
]));
987 DBGPRINT(RT_DEBUG_TRACE
,(" \n"));
991 ========================================================================
993 Get a received packet.
996 pAd device control block
997 pSaveRxD receive descriptor information
998 *pbReschedule need reschedule flag
999 *pRxPending pending received packet flag
1005 ========================================================================
1007 #define RT2870_RXDMALEN_FIELD_SIZE 4
1008 PNDIS_PACKET
GetPacketFromRxRing(
1009 IN PRTMP_ADAPTER pAd
,
1010 OUT PRT28XX_RXD_STRUC pSaveRxD
,
1011 OUT BOOLEAN
*pbReschedule
,
1012 IN OUT UINT32
*pRxPending
)
1014 PRX_CONTEXT pRxContext
;
1018 ULONG RxBufferLength
;
1021 pRxContext
= &pAd
->RxContext
[pAd
->NextRxBulkInReadIndex
];
1022 if ((pRxContext
->Readable
== FALSE
) || (pRxContext
->InUse
== TRUE
))
1025 RxBufferLength
= pRxContext
->BulkInOffset
- pAd
->ReadPosition
;
1026 if (RxBufferLength
< (RT2870_RXDMALEN_FIELD_SIZE
+ sizeof(RXWI_STRUC
) + sizeof(RXINFO_STRUC
)))
1031 pData
= &pRxContext
->TransferBuffer
[pAd
->ReadPosition
]; /* 4KB */
1032 // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
1033 ThisFrameLen
= *pData
+ (*(pData
+1)<<8);
1034 if (ThisFrameLen
== 0)
1036 DBGPRINT(RT_DEBUG_TRACE
, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
1037 pAd
->NextRxBulkInReadIndex
, ThisFrameLen
, pRxContext
->BulkInOffset
));
1040 if ((ThisFrameLen
&0x3) != 0)
1042 DBGPRINT(RT_DEBUG_ERROR
, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
1043 pAd
->NextRxBulkInReadIndex
, ThisFrameLen
, pRxContext
->BulkInOffset
));
1047 if ((ThisFrameLen
+ 8)> RxBufferLength
) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
1049 DBGPRINT(RT_DEBUG_TRACE
,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
1050 pAd
->NextRxBulkInReadIndex
, ThisFrameLen
, pRxContext
->BulkInOffset
, RxBufferLength
, pAd
->ReadPosition
));
1052 // error frame. finish this loop
1056 // skip USB frame length field
1057 pData
+= RT2870_RXDMALEN_FIELD_SIZE
;
1058 pRxWI
= (PRXWI_STRUC
)pData
;
1060 if (pRxWI
->MPDUtotalByteCount
> ThisFrameLen
)
1062 DBGPRINT(RT_DEBUG_ERROR
, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
1063 __func__
, pRxWI
->MPDUtotalByteCount
, ThisFrameLen
));
1067 // allocate a rx packet
1068 pSkb
= dev_alloc_skb(ThisFrameLen
);
1071 DBGPRINT(RT_DEBUG_ERROR
,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __func__
));
1075 // copy the rx packet
1076 memcpy(skb_put(pSkb
, ThisFrameLen
), pData
, ThisFrameLen
);
1077 RTPKT_TO_OSPKT(pSkb
)->dev
= get_netdev_from_bssid(pAd
, BSS0
);
1078 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb
), PKTSRC_NDIS
);
1081 *pSaveRxD
= *(PRXINFO_STRUC
)(pData
+ ThisFrameLen
);
1083 // update next packet read position.
1084 pAd
->ReadPosition
+= (ThisFrameLen
+ RT2870_RXDMALEN_FIELD_SIZE
+ RXINFO_SIZE
); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
1095 ========================================================================
1096 Routine Description:
1097 Handle received packets.
1100 data - URB information pointer
1106 ========================================================================
1108 static void rx_done_tasklet(unsigned long data
)
1111 PRX_CONTEXT pRxContext
;
1114 unsigned int IrqFlags
;
1116 pUrb
= (purbb_t
)data
;
1117 pRxContext
= (PRX_CONTEXT
)pUrb
->context
;
1118 pAd
= pRxContext
->pAd
;
1119 Status
= pUrb
->status
;
1122 RTMP_IRQ_LOCK(&pAd
->BulkInLock
, IrqFlags
);
1123 pRxContext
->InUse
= FALSE
;
1124 pRxContext
->IRPPending
= FALSE
;
1125 pRxContext
->BulkInOffset
+= pUrb
->actual_length
;
1126 //NdisInterlockedDecrement(&pAd->PendingRx);
1129 if (Status
== USB_ST_NOERROR
)
1131 pAd
->BulkInComplete
++;
1132 pAd
->NextRxBulkInPosition
= 0;
1133 if (pRxContext
->BulkInOffset
) // As jan's comment, it may bulk-in success but size is zero.
1135 pRxContext
->Readable
= TRUE
;
1136 INC_RING_INDEX(pAd
->NextRxBulkInIndex
, RX_RING_SIZE
);
1138 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
1140 else // STATUS_OTHER
1142 pAd
->BulkInCompleteFail
++;
1143 // Still read this packet although it may comtain wrong bytes.
1144 pRxContext
->Readable
= FALSE
;
1145 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
1147 // Parsing all packets. because after reset, the index will reset to all zero.
1148 if ((!RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_RESET_IN_PROGRESS
|
1149 fRTMP_ADAPTER_BULKIN_RESET
|
1150 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
1151 fRTMP_ADAPTER_NIC_NOT_EXIST
))))
1154 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
1155 Status
, pAd
->NextRxBulkInIndex
, pAd
->NextRxBulkInReadIndex
, pRxContext
->pUrb
->actual_length
));
1157 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKIN_RESET
);
1158 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_IN
, NULL
, 0);
1162 ASSERT((pRxContext
->InUse
== pRxContext
->IRPPending
));
1164 RTUSBBulkReceive(pAd
);
1171 static void rt2870_mgmt_dma_done_tasklet(unsigned long data
)
1174 PTX_CONTEXT pMLMEContext
;
1176 PNDIS_PACKET pPacket
;
1179 unsigned long IrqFlags
;
1182 pUrb
= (purbb_t
)data
;
1183 pMLMEContext
= (PTX_CONTEXT
)pUrb
->context
;
1184 pAd
= pMLMEContext
->pAd
;
1185 Status
= pUrb
->status
;
1186 index
= pMLMEContext
->SelfIdx
;
1188 ASSERT((pAd
->MgmtRing
.TxDmaIdx
== index
));
1190 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[MGMTPIPEIDX
], IrqFlags
);
1193 if (Status
!= USB_ST_NOERROR
)
1195 //Bulk-Out fail status handle
1196 if ((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) &&
1197 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) &&
1198 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)) &&
1199 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)))
1201 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("Bulk Out MLME Failed, Status=%d!\n", Status
));
1202 // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
1203 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
);
1204 pAd
->bulkResetPipeid
= (MGMTPIPEIDX
| BULKOUT_MGMT_RESET_FLAG
);
1208 pAd
->BulkOutPending
[MGMTPIPEIDX
] = FALSE
;
1209 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[MGMTPIPEIDX
], IrqFlags
);
1211 RTMP_IRQ_LOCK(&pAd
->MLMEBulkOutLock
, IrqFlags
);
1212 // Reset MLME context flags
1213 pMLMEContext
->IRPPending
= FALSE
;
1214 pMLMEContext
->InUse
= FALSE
;
1215 pMLMEContext
->bWaitingBulkOut
= FALSE
;
1216 pMLMEContext
->BulkOutSize
= 0;
1218 pPacket
= pAd
->MgmtRing
.Cell
[index
].pNdisPacket
;
1219 pAd
->MgmtRing
.Cell
[index
].pNdisPacket
= NULL
;
1221 // Increase MgmtRing Index
1222 INC_RING_INDEX(pAd
->MgmtRing
.TxDmaIdx
, MGMT_RING_SIZE
);
1223 pAd
->MgmtRing
.TxSwFreeIdx
++;
1224 RTMP_IRQ_UNLOCK(&pAd
->MLMEBulkOutLock
, IrqFlags
);
1226 // No-matter success or fail, we free the mgmt packet.
1228 RTMPFreeNdisPacket(pAd
, pPacket
);
1230 if ((RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_RESET_IN_PROGRESS
|
1231 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
1232 fRTMP_ADAPTER_NIC_NOT_EXIST
))))
1234 // do nothing and return directly.
1238 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
) &&
1239 ((pAd
->bulkResetPipeid
& BULKOUT_MGMT_RESET_FLAG
) == BULKOUT_MGMT_RESET_FLAG
))
1240 { // For Mgmt Bulk-Out failed, ignore it now.
1241 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
1246 // Always call Bulk routine, even reset bulk.
1247 // The protectioon of rest bulk should be in BulkOut routine
1248 if (pAd
->MgmtRing
.TxSwFreeIdx
< MGMT_RING_SIZE
/* pMLMEContext->bWaitingBulkOut == TRUE */)
1250 RTUSB_SET_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_MLME
);
1252 RTUSBKickBulkOut(pAd
);
1259 static void rt2870_hcca_dma_done_tasklet(unsigned long data
)
1262 PHT_TX_CONTEXT pHTTXContext
;
1263 UCHAR BulkOutPipeId
= 4;
1266 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("--->hcca_dma_done_tasklet\n"));
1268 pUrb
= (purbb_t
)data
;
1269 pHTTXContext
= (PHT_TX_CONTEXT
)pUrb
->context
;
1270 pAd
= pHTTXContext
->pAd
;
1272 rt2870_dataout_complete_tasklet((unsigned long)pUrb
);
1274 if ((RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_RESET_IN_PROGRESS
|
1275 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
1276 fRTMP_ADAPTER_NIC_NOT_EXIST
))))
1278 // do nothing and return directly.
1282 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
))
1284 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
1287 { pHTTXContext
= &pAd
->TxContext
[BulkOutPipeId
];
1288 if ((pAd
->TxSwQueue
[BulkOutPipeId
].Number
> 0) &&
1289 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1290 (pAd
->DeQueueRunning
[BulkOutPipeId
] == FALSE
) &&
1291 (pHTTXContext
->bCurWriting
== FALSE
))
1293 RTMPDeQueuePacket(pAd
, FALSE
, BulkOutPipeId
, MAX_TX_PROCESS
);
1296 RTUSB_SET_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL
<<4);
1297 RTUSBKickBulkOut(pAd
);
1301 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("<---hcca_dma_done_tasklet\n"));
1305 static void rt2870_ac3_dma_done_tasklet(unsigned long data
)
1308 PHT_TX_CONTEXT pHTTXContext
;
1309 UCHAR BulkOutPipeId
= 3;
1313 pUrb
= (purbb_t
)data
;
1314 pHTTXContext
= (PHT_TX_CONTEXT
)pUrb
->context
;
1315 pAd
= pHTTXContext
->pAd
;
1317 rt2870_dataout_complete_tasklet((unsigned long)pUrb
);
1319 if ((RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_RESET_IN_PROGRESS
|
1320 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
1321 fRTMP_ADAPTER_NIC_NOT_EXIST
))))
1323 // do nothing and return directly.
1327 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
))
1329 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
1332 { pHTTXContext
= &pAd
->TxContext
[BulkOutPipeId
];
1333 if ((pAd
->TxSwQueue
[BulkOutPipeId
].Number
> 0) &&
1334 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1335 (pAd
->DeQueueRunning
[BulkOutPipeId
] == FALSE
) &&
1336 (pHTTXContext
->bCurWriting
== FALSE
))
1338 RTMPDeQueuePacket(pAd
, FALSE
, BulkOutPipeId
, MAX_TX_PROCESS
);
1341 RTUSB_SET_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL
<<3);
1342 RTUSBKickBulkOut(pAd
);
1351 static void rt2870_ac2_dma_done_tasklet(unsigned long data
)
1354 PHT_TX_CONTEXT pHTTXContext
;
1355 UCHAR BulkOutPipeId
= 2;
1359 pUrb
= (purbb_t
)data
;
1360 pHTTXContext
= (PHT_TX_CONTEXT
)pUrb
->context
;
1361 pAd
= pHTTXContext
->pAd
;
1363 rt2870_dataout_complete_tasklet((unsigned long)pUrb
);
1365 if ((RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_RESET_IN_PROGRESS
|
1366 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
1367 fRTMP_ADAPTER_NIC_NOT_EXIST
))))
1369 // do nothing and return directly.
1373 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
))
1375 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
1378 { pHTTXContext
= &pAd
->TxContext
[BulkOutPipeId
];
1379 if ((pAd
->TxSwQueue
[BulkOutPipeId
].Number
> 0) &&
1380 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1381 (pAd
->DeQueueRunning
[BulkOutPipeId
] == FALSE
) &&
1382 (pHTTXContext
->bCurWriting
== FALSE
))
1384 RTMPDeQueuePacket(pAd
, FALSE
, BulkOutPipeId
, MAX_TX_PROCESS
);
1387 RTUSB_SET_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL
<<2);
1388 RTUSBKickBulkOut(pAd
);
1396 static void rt2870_ac1_dma_done_tasklet(unsigned long data
)
1399 PHT_TX_CONTEXT pHTTXContext
;
1400 UCHAR BulkOutPipeId
= 1;
1404 pUrb
= (purbb_t
)data
;
1405 pHTTXContext
= (PHT_TX_CONTEXT
)pUrb
->context
;
1406 pAd
= pHTTXContext
->pAd
;
1408 rt2870_dataout_complete_tasklet((unsigned long)pUrb
);
1410 if ((RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_RESET_IN_PROGRESS
|
1411 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
1412 fRTMP_ADAPTER_NIC_NOT_EXIST
))))
1414 // do nothing and return directly.
1418 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
))
1420 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
1423 { pHTTXContext
= &pAd
->TxContext
[BulkOutPipeId
];
1424 if ((pAd
->TxSwQueue
[BulkOutPipeId
].Number
> 0) &&
1425 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1426 (pAd
->DeQueueRunning
[BulkOutPipeId
] == FALSE
) &&
1427 (pHTTXContext
->bCurWriting
== FALSE
))
1429 RTMPDeQueuePacket(pAd
, FALSE
, BulkOutPipeId
, MAX_TX_PROCESS
);
1432 RTUSB_SET_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL
<<1);
1433 RTUSBKickBulkOut(pAd
);
1442 static void rt2870_ac0_dma_done_tasklet(unsigned long data
)
1445 PHT_TX_CONTEXT pHTTXContext
;
1446 UCHAR BulkOutPipeId
= 0;
1450 pUrb
= (purbb_t
)data
;
1451 pHTTXContext
= (PHT_TX_CONTEXT
)pUrb
->context
;
1452 pAd
= pHTTXContext
->pAd
;
1454 rt2870_dataout_complete_tasklet((unsigned long)pUrb
);
1456 if ((RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_RESET_IN_PROGRESS
|
1457 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
1458 fRTMP_ADAPTER_NIC_NOT_EXIST
))))
1460 // do nothing and return directly.
1464 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
))
1466 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
1469 { pHTTXContext
= &pAd
->TxContext
[BulkOutPipeId
];
1470 if ((pAd
->TxSwQueue
[BulkOutPipeId
].Number
> 0) &&
1471 /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1472 (pAd
->DeQueueRunning
[BulkOutPipeId
] == FALSE
) &&
1473 (pHTTXContext
->bCurWriting
== FALSE
))
1475 RTMPDeQueuePacket(pAd
, FALSE
, BulkOutPipeId
, MAX_TX_PROCESS
);
1478 RTUSB_SET_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL
);
1479 RTUSBKickBulkOut(pAd
);
1489 static void rt2870_null_frame_complete_tasklet(unsigned long data
)
1492 PTX_CONTEXT pNullContext
;
1495 unsigned long irqFlag
;
1498 pUrb
= (purbb_t
)data
;
1499 pNullContext
= (PTX_CONTEXT
)pUrb
->context
;
1500 pAd
= pNullContext
->pAd
;
1501 Status
= pUrb
->status
;
1503 // Reset Null frame context flags
1504 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[0], irqFlag
);
1505 pNullContext
->IRPPending
= FALSE
;
1506 pNullContext
->InUse
= FALSE
;
1507 pAd
->BulkOutPending
[0] = FALSE
;
1508 pAd
->watchDogTxPendingCnt
[0] = 0;
1510 if (Status
== USB_ST_NOERROR
)
1512 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], irqFlag
);
1514 RTMPDeQueuePacket(pAd
, FALSE
, NUM_OF_TX_RING
, MAX_TX_PROCESS
);
1516 else // STATUS_OTHER
1518 if ((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) &&
1519 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) &&
1520 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)) &&
1521 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)))
1523 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status
));
1524 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
);
1525 pAd
->bulkResetPipeid
= (MGMTPIPEIDX
| BULKOUT_MGMT_RESET_FLAG
);
1526 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], irqFlag
);
1527 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
1531 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], irqFlag
);
1535 // Always call Bulk routine, even reset bulk.
1536 // The protectioon of rest bulk should be in BulkOut routine
1537 RTUSBKickBulkOut(pAd
);
1542 static void rt2870_rts_frame_complete_tasklet(unsigned long data
)
1545 PTX_CONTEXT pRTSContext
;
1548 unsigned long irqFlag
;
1551 pUrb
= (purbb_t
)data
;
1552 pRTSContext
= (PTX_CONTEXT
)pUrb
->context
;
1553 pAd
= pRTSContext
->pAd
;
1554 Status
= pUrb
->status
;
1556 // Reset RTS frame context flags
1557 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[0], irqFlag
);
1558 pRTSContext
->IRPPending
= FALSE
;
1559 pRTSContext
->InUse
= FALSE
;
1561 if (Status
== USB_ST_NOERROR
)
1563 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], irqFlag
);
1564 RTMPDeQueuePacket(pAd
, FALSE
, NUM_OF_TX_RING
, MAX_TX_PROCESS
);
1566 else // STATUS_OTHER
1568 if ((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) &&
1569 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) &&
1570 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)) &&
1571 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)))
1573 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("Bulk Out RTS Frame Failed\n"));
1574 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
);
1575 pAd
->bulkResetPipeid
= (MGMTPIPEIDX
| BULKOUT_MGMT_RESET_FLAG
);
1576 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], irqFlag
);
1577 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
1581 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], irqFlag
);
1585 RTMP_SEM_LOCK(&pAd
->BulkOutLock
[pRTSContext
->BulkOutPipeId
]);
1586 pAd
->BulkOutPending
[pRTSContext
->BulkOutPipeId
] = FALSE
;
1587 RTMP_SEM_UNLOCK(&pAd
->BulkOutLock
[pRTSContext
->BulkOutPipeId
]);
1589 // Always call Bulk routine, even reset bulk.
1590 // The protectioon of rest bulk should be in BulkOut routine
1591 RTUSBKickBulkOut(pAd
);
1596 static void rt2870_pspoll_frame_complete_tasklet(unsigned long data
)
1599 PTX_CONTEXT pPsPollContext
;
1604 pUrb
= (purbb_t
)data
;
1605 pPsPollContext
= (PTX_CONTEXT
)pUrb
->context
;
1606 pAd
= pPsPollContext
->pAd
;
1607 Status
= pUrb
->status
;
1609 // Reset PsPoll context flags
1610 pPsPollContext
->IRPPending
= FALSE
;
1611 pPsPollContext
->InUse
= FALSE
;
1612 pAd
->watchDogTxPendingCnt
[0] = 0;
1614 if (Status
== USB_ST_NOERROR
)
1616 RTMPDeQueuePacket(pAd
, FALSE
, NUM_OF_TX_RING
, MAX_TX_PROCESS
);
1618 else // STATUS_OTHER
1620 if ((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) &&
1621 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) &&
1622 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)) &&
1623 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)))
1625 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("Bulk Out PSPoll Failed\n"));
1626 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
);
1627 pAd
->bulkResetPipeid
= (MGMTPIPEIDX
| BULKOUT_MGMT_RESET_FLAG
);
1628 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
1632 RTMP_SEM_LOCK(&pAd
->BulkOutLock
[0]);
1633 pAd
->BulkOutPending
[0] = FALSE
;
1634 RTMP_SEM_UNLOCK(&pAd
->BulkOutLock
[0]);
1636 // Always call Bulk routine, even reset bulk.
1637 // The protectioon of rest bulk should be in BulkOut routine
1638 RTUSBKickBulkOut(pAd
);
1643 static void rt2870_dataout_complete_tasklet(unsigned long data
)
1648 PHT_TX_CONTEXT pHTTXContext
;
1649 UCHAR BulkOutPipeId
;
1651 unsigned long IrqFlags
;
1654 pUrb
= (purbb_t
)data
;
1655 pHTTXContext
= (PHT_TX_CONTEXT
)pUrb
->context
;
1656 pAd
= pHTTXContext
->pAd
;
1657 pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
1658 Status
= pUrb
->status
;
1660 // Store BulkOut PipeId
1661 BulkOutPipeId
= pHTTXContext
->BulkOutPipeId
;
1662 pAd
->BulkOutDataOneSecCount
++;
1664 //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
1665 // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
1667 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
1668 pAd
->BulkOutPending
[BulkOutPipeId
] = FALSE
;
1669 pHTTXContext
->IRPPending
= FALSE
;
1670 pAd
->watchDogTxPendingCnt
[BulkOutPipeId
] = 0;
1672 if (Status
== USB_ST_NOERROR
)
1674 pAd
->BulkOutComplete
++;
1676 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
1678 pAd
->Counters8023
.GoodTransmits
++;
1679 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1680 FREE_HTTX_RING(pAd
, BulkOutPipeId
, pHTTXContext
);
1681 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1685 else // STATUS_OTHER
1689 pAd
->BulkOutCompleteOther
++;
1691 pBuf
= &pHTTXContext
->TransferBuffer
->field
.WirelessPacket
[pHTTXContext
->NextBulkOutPosition
];
1693 if (!RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_RESET_IN_PROGRESS
|
1694 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
1695 fRTMP_ADAPTER_NIC_NOT_EXIST
|
1696 fRTMP_ADAPTER_BULKOUT_RESET
)))
1698 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
);
1699 pAd
->bulkResetPipeid
= BulkOutPipeId
;
1700 pAd
->bulkResetReq
[BulkOutPipeId
] = pAd
->BulkOutReq
;
1702 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
1704 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status
));
1705 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd
->BulkOutReq
, pAd
->BulkOutComplete
, pAd
->BulkOutCompleteOther
));
1706 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf
[0], pBuf
[1], pBuf
[2], pBuf
[3], pBuf
[4], pBuf
[5], pBuf
[6], pBuf
[7]));
1707 //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
1712 // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
1713 // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
1715 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1716 if ((pHTTXContext
->ENextBulkOutPosition
!= pHTTXContext
->CurWritePosition
) &&
1717 (pHTTXContext
->ENextBulkOutPosition
!= (pHTTXContext
->CurWritePosition
+8)) &&
1718 !RTUSB_TEST_BULK_FLAG(pAd
, (fRTUSB_BULK_OUT_DATA_FRAG
<< BulkOutPipeId
)))
1720 // Indicate There is data avaliable
1721 RTUSB_SET_BULK_FLAG(pAd
, (fRTUSB_BULK_OUT_DATA_NORMAL
<< BulkOutPipeId
));
1723 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1725 // Always call Bulk routine, even reset bulk.
1726 // The protection of rest bulk should be in BulkOut routine
1727 RTUSBKickBulkOut(pAd
);
1730 /* End of 2870_rtmp_init.c */