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;
270 for(i=0; i<MGMT_RING_SIZE; i++) // 8
272 PTX_CONTEXT pMLMEContext = &(pAd->MLMEContext[i]);
275 NdisZeroMemory(pMLMEContext, sizeof(TX_CONTEXT));
278 LM_USB_ALLOC(pObj, pMLMEContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
279 ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i),
281 ("<-- ERROR in Alloc TX MLMEContext[%d] TX_BUFFER !! \n", i),
284 pMLMEContext->pAd = pAd;
285 pMLMEContext->pIrp = NULL;
286 pMLMEContext->InUse = FALSE;
287 pMLMEContext->IRPPending = FALSE;
290 // Allocate MGMT ring descriptor's memory
291 pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
292 RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
293 if (pAd->MgmtDescRing.AllocVa == NULL)
295 DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
296 Status = NDIS_STATUS_RESOURCES;
299 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
300 RingBaseVa = pAd->MgmtDescRing.AllocVa;
302 // Initialize MGMT Ring and associated buffer memory
303 pMgmtRing = &pAd->MgmtRing;
304 for (i = 0; i < MGMT_RING_SIZE; i++)
306 // link the pre-allocated Mgmt buffer to MgmtRing.Cell
307 pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
308 pMgmtRing->Cell[i].AllocVa = RingBaseVa;
309 pMgmtRing->Cell[i].pNdisPacket = NULL;
310 pMgmtRing->Cell[i].pNextNdisPacket = NULL;
312 //Allocate URB for MLMEContext
313 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
314 pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
315 if (pMLMEContext->pUrb == NULL)
317 DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
318 Status = NDIS_STATUS_RESOURCES;
321 pMLMEContext->pAd = pAd;
322 pMLMEContext->pIrp = NULL;
323 pMLMEContext->TransferBuffer = NULL;
324 pMLMEContext->InUse = FALSE;
325 pMLMEContext->IRPPending = FALSE;
326 pMLMEContext->bWaitingBulkOut = FALSE;
327 pMLMEContext->BulkOutSize = 0;
328 pMLMEContext->SelfIdx = i;
330 // Offset to next ring descriptor address
331 RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
333 DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
335 //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
336 pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
337 pAd->MgmtRing.TxCpuIdx = 0;
338 pAd->MgmtRing.TxDmaIdx = 0;
344 for(i=0; i<BEACON_RING_SIZE; i++) // 2
346 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
349 NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
352 LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
353 ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
355 ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
358 pBeaconContext->pAd = pAd;
359 pBeaconContext->pIrp = NULL;
360 pBeaconContext->InUse = FALSE;
361 pBeaconContext->IRPPending = FALSE;
367 NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
370 LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
371 ("<-- ERROR in Alloc TX NullContext urb!! \n"),
373 ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
376 pNullContext->pAd = pAd;
377 pNullContext->pIrp = NULL;
378 pNullContext->InUse = FALSE;
379 pNullContext->IRPPending = FALSE;
384 NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
387 LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
388 ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
390 ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
393 pRTSContext->pAd = pAd;
394 pRTSContext->pIrp = NULL;
395 pRTSContext->InUse = FALSE;
396 pRTSContext->IRPPending = FALSE;
401 //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
403 LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
404 ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
406 ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
409 pPsPollContext->pAd = pAd;
410 pPsPollContext->pIrp = NULL;
411 pPsPollContext->InUse = FALSE;
412 pPsPollContext->IRPPending = FALSE;
413 pPsPollContext->bAggregatible = FALSE;
414 pPsPollContext->LastOne = TRUE;
420 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n"));
424 /* --------------------------- ERROR HANDLE --------------------------- */
426 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
429 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
432 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
435 for(i=0; i<BEACON_RING_SIZE; i++)
437 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
439 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
443 if (pAd->MgmtDescRing.AllocVa)
445 pMgmtRing = &pAd->MgmtRing;
446 for(i=0; i<MGMT_RING_SIZE; i++)
448 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
450 LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
452 NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
453 pAd->MgmtDescRing.AllocVa = NULL;
457 for (acidx = 0; acidx < 4; acidx++)
459 PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
461 LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
464 // Here we didn't have any pre-allocated memory need to free.
471 ========================================================================
473 Allocate DMA memory blocks for send, receive.
476 pAd Pointer to our adapter
481 NDIS_STATUS_RESOURCES
484 ========================================================================
486 NDIS_STATUS RTMPAllocTxRxRingMemory(
487 IN PRTMP_ADAPTER pAd)
489 // COUNTER_802_11 pCounter = &pAd->WlanCounters;
494 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
499 // Init the CmdQ and CmdQLock
500 NdisAllocateSpinLock(&pAd->CmdQLock);
501 NdisAcquireSpinLock(&pAd->CmdQLock);
502 RTUSBInitializeCmdQ(&pAd->CmdQ);
503 NdisReleaseSpinLock(&pAd->CmdQLock);
506 NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
507 //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
508 NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
509 NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
510 NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
511 NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
512 NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
513 NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
514 NdisAllocateSpinLock(&pAd->BulkInLock);
516 for (num = 0; num < NUM_OF_TX_RING; num++)
518 NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
522 NdisAllocateSpinLock(&pAd->GenericLock);
523 #endif // RALINK_ATE //
525 // NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX
527 // NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
528 // NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
530 // for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
532 // NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
538 // MacTableInitialize(pAd);
541 // Init send data structures and related parameters
543 Status = NICInitTransmit(pAd);
544 if (Status != NDIS_STATUS_SUCCESS)
548 // Init receive data structures and related parameters
550 Status = NICInitRecv(pAd);
551 if (Status != NDIS_STATUS_SUCCESS)
554 pAd->PendingIoCount = 1;
558 NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
559 pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
561 if (pAd->FragFrame.pFragPacket == NULL)
563 Status = NDIS_STATUS_RESOURCES;
566 DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
572 ========================================================================
574 Calls USB_InterfaceStop and frees memory allocated for the URBs
575 calls NdisMDeregisterDevice and frees the memory
576 allocated in VNetInitialize for the Adapter Object
579 *pAd the raxx interface data pointer
585 ========================================================================
587 VOID RTMPFreeTxRxRingMemory(
588 IN PRTMP_ADAPTER pAd)
590 #define LM_URB_FREE(pObj, Context, BufferSize) \
591 if (NULL != Context->pUrb) { \
592 RTUSB_UNLINK_URB(Context->pUrb); \
593 RTUSB_FREE_URB(Context->pUrb); \
594 Context->pUrb = NULL; } \
595 if (NULL != Context->TransferBuffer) { \
596 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
597 Context->TransferBuffer, \
598 Context->data_dma); \
599 Context->TransferBuffer = NULL; }
603 PTX_CONTEXT pNullContext = &pAd->NullContext;
604 PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
605 PTX_CONTEXT pRTSContext = &pAd->RTSContext;
606 // PHT_TX_CONTEXT pHTTXContext;
607 //PRTMP_REORDERBUF pReorderBuf;
608 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
609 // RTMP_TX_RING *pTxRing;
611 DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
614 // Free all resources for the RECEIVE buffer queue.
615 for(i=0; i<(RX_RING_SIZE); i++)
617 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
619 LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
622 // Free PsPoll frame resource
623 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
625 // Free NULL frame resource
626 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
628 // Free RTS frame resource
629 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
632 // Free beacon frame resource
633 for(i=0; i<BEACON_RING_SIZE; i++)
635 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
637 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
641 // Free mgmt frame resource
642 for(i = 0; i < MGMT_RING_SIZE; i++)
644 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
645 //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
646 if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
648 RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
649 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
650 pMLMEContext->TransferBuffer = NULL;
655 if (NULL != pMLMEContext->pUrb)
657 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
658 RTUSB_FREE_URB(pMLMEContext->pUrb);
659 pMLMEContext->pUrb = NULL;
663 if (pAd->MgmtDescRing.AllocVa)
664 NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
667 // Free Tx frame resource
668 for (acidx = 0; acidx < 4; acidx++)
670 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
672 LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
675 if (pAd->FragFrame.pFragPacket)
676 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
680 NdisFreeSpinLock(&pAd->BulkOutLock[i]);
683 NdisFreeSpinLock(&pAd->BulkInLock);
684 NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
686 NdisFreeSpinLock(&pAd->CmdQLock);
688 NdisFreeSpinLock(&pAd->GenericLock);
689 #endif // RALINK_ATE //
690 // Clear all pending bulk-out request flags.
691 RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
693 // NdisFreeSpinLock(&pAd->MacTabLock);
695 // for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
697 // NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
700 DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n"));
705 ========================================================================
707 Allocate memory for adapter control block.
710 pAd Pointer to our adapter
715 NDIS_STATUS_RESOURCES
718 ========================================================================
720 NDIS_STATUS AdapterBlockAllocateMemory(
725 POS_COOKIE pObj = (POS_COOKIE) handle;
728 usb_dev = pObj->pUsb_Dev;
730 pObj->MLMEThr_task = NULL;
731 pObj->RTUSBCmdThr_task = NULL;
733 *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
737 NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
738 ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
739 return (NDIS_STATUS_SUCCESS);
743 return (NDIS_STATUS_FAILURE);
749 ========================================================================
751 Create kernel threads & tasklets.
754 *net_dev Pointer to wireless net device interface
761 ========================================================================
763 NDIS_STATUS CreateThreads(
764 IN struct net_device *net_dev)
766 PRTMP_ADAPTER pAd = net_dev->ml_priv;
767 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
768 struct task_struct *tsk;
770 //init_MUTEX(&(pAd->usbdev_semaphore));
772 init_MUTEX_LOCKED(&(pAd->mlme_semaphore));
773 init_completion (&pAd->mlmeComplete);
775 init_MUTEX_LOCKED(&(pAd->RTUSBCmd_semaphore));
776 init_completion (&pAd->CmdQComplete);
778 init_MUTEX_LOCKED(&(pAd->RTUSBTimer_semaphore));
779 init_completion (&pAd->TimerQComplete);
782 pObj->MLMEThr_task = NULL;
783 tsk = kthread_run(MlmeThread, pAd, pAd->net_dev->name);
786 printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
787 return NDIS_STATUS_FAILURE;
790 pObj->MLMEThr_task = tsk;
791 // Wait for the thread to start
792 wait_for_completion(&(pAd->mlmeComplete));
794 // Creat Command Thread
795 pObj->RTUSBCmdThr_task = NULL;
796 tsk = kthread_run(RTUSBCmdThread, pAd, pAd->net_dev->name);
800 printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
801 return NDIS_STATUS_FAILURE;
804 pObj->RTUSBCmdThr_task = tsk;
805 wait_for_completion(&(pAd->CmdQComplete));
807 pObj->TimerQThr_task = NULL;
808 tsk = kthread_run(TimerQThread, pAd, pAd->net_dev->name);
811 printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
812 return NDIS_STATUS_FAILURE;
814 pObj->TimerQThr_task = tsk;
815 // Wait for the thread to start
816 wait_for_completion(&(pAd->TimerQComplete));
818 // Create receive tasklet
819 tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd);
820 tasklet_init(&pObj->mgmt_dma_done_task, rt2870_mgmt_dma_done_tasklet, (unsigned long)pAd);
821 tasklet_init(&pObj->ac0_dma_done_task, rt2870_ac0_dma_done_tasklet, (unsigned long)pAd);
822 tasklet_init(&pObj->ac1_dma_done_task, rt2870_ac1_dma_done_tasklet, (unsigned long)pAd);
823 tasklet_init(&pObj->ac2_dma_done_task, rt2870_ac2_dma_done_tasklet, (unsigned long)pAd);
824 tasklet_init(&pObj->ac3_dma_done_task, rt2870_ac3_dma_done_tasklet, (unsigned long)pAd);
825 tasklet_init(&pObj->hcca_dma_done_task, rt2870_hcca_dma_done_tasklet, (unsigned long)pAd);
826 tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
827 tasklet_init(&pObj->null_frame_complete_task, rt2870_null_frame_complete_tasklet, (unsigned long)pAd);
828 tasklet_init(&pObj->rts_frame_complete_task, rt2870_rts_frame_complete_tasklet, (unsigned long)pAd);
829 tasklet_init(&pObj->pspoll_frame_complete_task, rt2870_pspoll_frame_complete_tasklet, (unsigned long)pAd);
831 return NDIS_STATUS_SUCCESS;
835 #ifdef CONFIG_STA_SUPPORT
837 ========================================================================
839 As STA's BSSID is a WC too, it uses shared key table.
840 This function write correct unicast TX key to ASIC WCID.
841 And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
842 Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
843 Caller guarantee WEP calls this function when set Txkey, default key index=0~3.
846 pAd Pointer to our adapter
847 pKey Pointer to the where the key stored
850 NDIS_SUCCESS Add key successfully
853 ========================================================================
855 VOID RTMPAddBSSIDCipher(
856 IN PRTMP_ADAPTER pAd,
858 IN PNDIS_802_11_KEY pKey,
861 PUCHAR pTxMic, pRxMic;
862 BOOLEAN bKeyRSC, bAuthenticator; // indicate the receive SC set by KeyRSC value
867 UCHAR KeyIdx, IVEIV[8];
870 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid));
872 // Bit 29 of Add-key KeyRSC
873 bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
875 // Bit 28 of Add-key Authenticator
876 bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
877 KeyIdx = (UCHAR)pKey->KeyIndex&0xff;
883 if (pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg == CIPHER_TKIP)
884 { if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
886 // for WPA-None Tx, Rx MIC is the same
887 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
890 else if (bAuthenticator == TRUE)
892 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
893 pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
897 pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
898 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
901 offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x10;
905 Value += (*(pTxMic+i+1)<<8);
906 Value += (*(pTxMic+i+2)<<16);
907 Value += (*(pTxMic+i+3)<<24);
908 RTUSBWriteMACRegister(pAd, offset+i, Value);
912 offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x18;
916 Value += (*(pRxMic+i+1)<<8);
917 Value += (*(pRxMic+i+2)<<16);
918 Value += (*(pRxMic+i+3)<<24);
919 RTUSBWriteMACRegister(pAd, offset+i, Value);
923 // Only Key lenth equal to TKIP key have these
924 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxMic, pRxMic, 8);
925 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.TxMic, pTxMic, 8);
927 DBGPRINT(RT_DEBUG_TRACE,
928 (" TxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
929 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],
930 pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
931 DBGPRINT(RT_DEBUG_TRACE,
932 (" RxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
933 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],
934 pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
937 // 2. Record Security Key.
938 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen= (UCHAR)pKey->KeyLength;
939 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
941 // 3. Check RxTsc. And used to init to ASIC IV.
943 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, &pKey->KeyRSC, 6);
945 NdisZeroMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, 6);
947 // 4. Init TxTsc to one based on WiFi WPA specs
948 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[0] = 1;
949 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[1] = 0;
950 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[2] = 0;
951 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[3] = 0;
952 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[4] = 0;
953 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[5] = 0;
955 CipherAlg = pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg;
957 offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE);
958 RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial,
959 ((pKey->KeyLength == LEN_TKIP_KEY) ? 16 : (USHORT)pKey->KeyLength));
961 offset = SHARED_KEY_TABLE_BASE + (KeyIdx * HW_KEY_ENTRY_SIZE);
962 RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, (USHORT)pKey->KeyLength);
964 offset = PAIRWISE_IVEIV_TABLE_BASE + (Aid * HW_IVEIV_ENTRY_SIZE);
965 NdisZeroMemory(IVEIV, 8);
968 if ((CipherAlg == CIPHER_TKIP) ||
969 (CipherAlg == CIPHER_TKIP_NO_MIC) ||
970 (CipherAlg == CIPHER_AES))
972 IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
974 // default key idx needs to set.
975 // in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key.
978 IVEIV[3] |= (KeyIdx<< 6);
980 RTUSBMultiWrite(pAd, (USHORT) offset, IVEIV, 8);
982 // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
983 if ((CipherAlg == CIPHER_TKIP) ||
984 (CipherAlg == CIPHER_TKIP_NO_MIC) ||
985 (CipherAlg == CIPHER_AES))
987 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
990 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
992 offset = MAC_WCID_ATTRIBUTE_BASE + (Aid* HW_WCID_ATTRI_SIZE);
993 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
994 RTUSBReadMACRegister(pAd, offset, &Value);
996 DBGPRINT(RT_DEBUG_TRACE, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n",
1000 // Add Bssid mac address at linkup. not here. check!
1001 /*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE);
1002 *for (i=0; i<MAC_ADDR_LEN; i++)
1004 RTMP_IO_WRITE8(pAd, offset+i, pKey->BSSID[i]);
1008 DBGPRINT(RT_DEBUG_ERROR, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n",
1009 CipherName[CipherAlg], pKey->KeyLength));
1010 DBGPRINT(RT_DEBUG_TRACE, ("Key [idx=%x] [KeyLen = %d]\n",
1011 pKey->KeyIndex, pKey->KeyLength));
1012 for(i=0; i<pKey->KeyLength; i++)
1013 DBGPRINT_RAW(RT_DEBUG_TRACE,(" %x:", pKey->KeyMaterial[i]));
1014 DBGPRINT(RT_DEBUG_TRACE,(" \n"));
1016 #endif // CONFIG_STA_SUPPORT //
1019 ========================================================================
1020 Routine Description:
1021 Get a received packet.
1024 pAd device control block
1025 pSaveRxD receive descriptor information
1026 *pbReschedule need reschedule flag
1027 *pRxPending pending received packet flag
1033 ========================================================================
1035 #define RT2870_RXDMALEN_FIELD_SIZE 4
1036 PNDIS_PACKET GetPacketFromRxRing(
1037 IN PRTMP_ADAPTER pAd,
1038 OUT PRT28XX_RXD_STRUC pSaveRxD,
1039 OUT BOOLEAN *pbReschedule,
1040 IN OUT UINT32 *pRxPending)
1042 PRX_CONTEXT pRxContext;
1046 ULONG RxBufferLength;
1049 pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
1050 if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
1053 RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
1054 if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
1059 pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
1060 // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
1061 ThisFrameLen = *pData + (*(pData+1)<<8);
1062 if (ThisFrameLen == 0)
1064 DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
1065 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
1068 if ((ThisFrameLen&0x3) != 0)
1070 DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
1071 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
1075 if ((ThisFrameLen + 8)> RxBufferLength) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
1077 DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
1078 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));
1080 // error frame. finish this loop
1084 // skip USB frame length field
1085 pData += RT2870_RXDMALEN_FIELD_SIZE;
1086 pRxWI = (PRXWI_STRUC)pData;
1087 #ifdef RT_BIG_ENDIAN
1088 RTMPWIEndianChange(pData, TYPE_RXWI);
1089 #endif // RT_BIG_ENDIAN //
1090 if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
1092 DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
1093 __func__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
1096 #ifdef RT_BIG_ENDIAN
1097 RTMPWIEndianChange(pData, TYPE_RXWI);
1098 #endif // RT_BIG_ENDIAN //
1100 // allocate a rx packet
1101 pSkb = dev_alloc_skb(ThisFrameLen);
1104 DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __func__));
1108 // copy the rx packet
1109 memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
1110 RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
1111 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
1114 *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
1115 #ifdef RT_BIG_ENDIAN
1116 RTMPDescriptorEndianChange((PUCHAR)pSaveRxD, TYPE_RXINFO);
1117 #endif // RT_BIG_ENDIAN //
1119 // update next packet read position.
1120 pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
1131 ========================================================================
1132 Routine Description:
1133 Handle received packets.
1136 data - URB information pointer
1142 ========================================================================
1144 static void rx_done_tasklet(unsigned long data)
1147 PRX_CONTEXT pRxContext;
1150 unsigned int IrqFlags;
1152 pUrb = (purbb_t)data;
1153 pRxContext = (PRX_CONTEXT)pUrb->context;
1154 pAd = pRxContext->pAd;
1155 Status = pUrb->status;
1158 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1159 pRxContext->InUse = FALSE;
1160 pRxContext->IRPPending = FALSE;
1161 pRxContext->BulkInOffset += pUrb->actual_length;
1162 //NdisInterlockedDecrement(&pAd->PendingRx);
1165 if (Status == USB_ST_NOERROR)
1167 pAd->BulkInComplete++;
1168 pAd->NextRxBulkInPosition = 0;
1169 if (pRxContext->BulkInOffset) // As jan's comment, it may bulk-in success but size is zero.
1171 pRxContext->Readable = TRUE;
1172 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1174 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1176 else // STATUS_OTHER
1178 pAd->BulkInCompleteFail++;
1179 // Still read this packet although it may comtain wrong bytes.
1180 pRxContext->Readable = FALSE;
1181 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1183 // Parsing all packets. because after reset, the index will reset to all zero.
1184 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1185 fRTMP_ADAPTER_BULKIN_RESET |
1186 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1187 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1190 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
1191 Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
1193 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1194 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
1198 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1203 // If the driver is in ATE mode and Rx frame is set into here.
1204 if (pAd->ContinBulkIn == TRUE)
1206 RTUSBBulkReceive(pAd);
1210 #endif // RALINK_ATE //
1211 RTUSBBulkReceive(pAd);
1218 static void rt2870_mgmt_dma_done_tasklet(unsigned long data)
1221 PTX_CONTEXT pMLMEContext;
1223 PNDIS_PACKET pPacket;
1226 unsigned long IrqFlags;
1229 pUrb = (purbb_t)data;
1230 pMLMEContext = (PTX_CONTEXT)pUrb->context;
1231 pAd = pMLMEContext->pAd;
1232 Status = pUrb->status;
1233 index = pMLMEContext->SelfIdx;
1235 ASSERT((pAd->MgmtRing.TxDmaIdx == index));
1237 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1240 if (Status != USB_ST_NOERROR)
1242 //Bulk-Out fail status handle
1243 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1244 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1245 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1246 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1248 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1249 // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
1250 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1251 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1255 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1256 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1258 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1259 // Reset MLME context flags
1260 pMLMEContext->IRPPending = FALSE;
1261 pMLMEContext->InUse = FALSE;
1262 pMLMEContext->bWaitingBulkOut = FALSE;
1263 pMLMEContext->BulkOutSize = 0;
1265 pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
1266 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
1268 // Increase MgmtRing Index
1269 INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
1270 pAd->MgmtRing.TxSwFreeIdx++;
1271 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1273 // No-matter success or fail, we free the mgmt packet.
1275 RTMPFreeNdisPacket(pAd, pPacket);
1277 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1278 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1279 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1281 // do nothing and return directly.
1285 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) &&
1286 ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
1287 { // For Mgmt Bulk-Out failed, ignore it now.
1288 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1293 // Always call Bulk routine, even reset bulk.
1294 // The protectioon of rest bulk should be in BulkOut routine
1295 if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
1297 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
1299 RTUSBKickBulkOut(pAd);
1306 static void rt2870_hcca_dma_done_tasklet(unsigned long data)
1309 PHT_TX_CONTEXT pHTTXContext;
1310 UCHAR BulkOutPipeId = 4;
1314 DBGPRINT_RAW(RT_DEBUG_ERROR, ("--->hcca_dma_done_tasklet\n"));
1317 pUrb = (purbb_t)data;
1318 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1319 pAd = pHTTXContext->pAd;
1321 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1323 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1324 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1325 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1327 // do nothing and return directly.
1331 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1333 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1336 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1337 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1338 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1339 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1340 (pHTTXContext->bCurWriting == FALSE))
1342 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1345 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
1346 RTUSBKickBulkOut(pAd);
1350 DBGPRINT_RAW(RT_DEBUG_ERROR, ("<---hcca_dma_done_tasklet\n"));
1356 static void rt2870_ac3_dma_done_tasklet(unsigned long data)
1359 PHT_TX_CONTEXT pHTTXContext;
1360 UCHAR BulkOutPipeId = 3;
1364 pUrb = (purbb_t)data;
1365 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1366 pAd = pHTTXContext->pAd;
1368 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1370 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1371 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1372 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1374 // do nothing and return directly.
1378 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1380 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1383 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1384 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1385 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1386 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1387 (pHTTXContext->bCurWriting == FALSE))
1389 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1392 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3);
1393 RTUSBKickBulkOut(pAd);
1402 static void rt2870_ac2_dma_done_tasklet(unsigned long data)
1405 PHT_TX_CONTEXT pHTTXContext;
1406 UCHAR BulkOutPipeId = 2;
1410 pUrb = (purbb_t)data;
1411 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1412 pAd = pHTTXContext->pAd;
1414 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1416 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1417 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1418 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1420 // do nothing and return directly.
1424 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1426 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1429 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1430 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1431 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1432 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1433 (pHTTXContext->bCurWriting == FALSE))
1435 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1438 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2);
1439 RTUSBKickBulkOut(pAd);
1447 static void rt2870_ac1_dma_done_tasklet(unsigned long data)
1450 PHT_TX_CONTEXT pHTTXContext;
1451 UCHAR BulkOutPipeId = 1;
1455 pUrb = (purbb_t)data;
1456 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1457 pAd = pHTTXContext->pAd;
1459 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1461 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1462 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1463 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1465 // do nothing and return directly.
1469 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1471 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1474 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1475 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1476 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1477 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1478 (pHTTXContext->bCurWriting == FALSE))
1480 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1483 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
1484 RTUSBKickBulkOut(pAd);
1493 static void rt2870_ac0_dma_done_tasklet(unsigned long data)
1496 PHT_TX_CONTEXT pHTTXContext;
1497 UCHAR BulkOutPipeId = 0;
1501 pUrb = (purbb_t)data;
1502 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1503 pAd = pHTTXContext->pAd;
1505 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1507 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1508 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1509 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1511 // do nothing and return directly.
1515 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1517 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1520 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1521 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1522 /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1523 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1524 (pHTTXContext->bCurWriting == FALSE))
1526 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1529 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
1530 RTUSBKickBulkOut(pAd);
1540 static void rt2870_null_frame_complete_tasklet(unsigned long data)
1543 PTX_CONTEXT pNullContext;
1546 unsigned long irqFlag;
1549 pUrb = (purbb_t)data;
1550 pNullContext = (PTX_CONTEXT)pUrb->context;
1551 pAd = pNullContext->pAd;
1552 Status = pUrb->status;
1554 // Reset Null frame context flags
1555 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
1556 pNullContext->IRPPending = FALSE;
1557 pNullContext->InUse = FALSE;
1558 pAd->BulkOutPending[0] = FALSE;
1559 pAd->watchDogTxPendingCnt[0] = 0;
1561 if (Status == USB_ST_NOERROR)
1563 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1565 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1567 else // STATUS_OTHER
1569 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1570 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1571 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1572 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1574 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
1575 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1576 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1577 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1578 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1582 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1586 // Always call Bulk routine, even reset bulk.
1587 // The protectioon of rest bulk should be in BulkOut routine
1588 RTUSBKickBulkOut(pAd);
1593 static void rt2870_rts_frame_complete_tasklet(unsigned long data)
1596 PTX_CONTEXT pRTSContext;
1599 unsigned long irqFlag;
1602 pUrb = (purbb_t)data;
1603 pRTSContext = (PTX_CONTEXT)pUrb->context;
1604 pAd = pRTSContext->pAd;
1605 Status = pUrb->status;
1607 // Reset RTS frame context flags
1608 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
1609 pRTSContext->IRPPending = FALSE;
1610 pRTSContext->InUse = FALSE;
1612 if (Status == USB_ST_NOERROR)
1614 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1615 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1617 else // STATUS_OTHER
1619 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1620 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1621 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1622 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1624 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
1625 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1626 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1627 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1628 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1632 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1636 RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
1637 pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
1638 RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
1640 // Always call Bulk routine, even reset bulk.
1641 // The protectioon of rest bulk should be in BulkOut routine
1642 RTUSBKickBulkOut(pAd);
1647 static void rt2870_pspoll_frame_complete_tasklet(unsigned long data)
1650 PTX_CONTEXT pPsPollContext;
1655 pUrb = (purbb_t)data;
1656 pPsPollContext = (PTX_CONTEXT)pUrb->context;
1657 pAd = pPsPollContext->pAd;
1658 Status = pUrb->status;
1660 // Reset PsPoll context flags
1661 pPsPollContext->IRPPending = FALSE;
1662 pPsPollContext->InUse = FALSE;
1663 pAd->watchDogTxPendingCnt[0] = 0;
1665 if (Status == USB_ST_NOERROR)
1667 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1669 else // STATUS_OTHER
1671 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1672 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1673 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1674 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1676 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
1677 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1678 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1679 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1683 RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
1684 pAd->BulkOutPending[0] = FALSE;
1685 RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
1687 // Always call Bulk routine, even reset bulk.
1688 // The protectioon of rest bulk should be in BulkOut routine
1689 RTUSBKickBulkOut(pAd);
1694 static void rt2870_dataout_complete_tasklet(unsigned long data)
1699 PHT_TX_CONTEXT pHTTXContext;
1700 UCHAR BulkOutPipeId;
1702 unsigned long IrqFlags;
1705 pUrb = (purbb_t)data;
1706 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1707 pAd = pHTTXContext->pAd;
1708 pObj = (POS_COOKIE) pAd->OS_Cookie;
1709 Status = pUrb->status;
1711 // Store BulkOut PipeId
1712 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
1713 pAd->BulkOutDataOneSecCount++;
1715 //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
1716 // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
1718 RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1719 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
1720 pHTTXContext->IRPPending = FALSE;
1721 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
1723 if (Status == USB_ST_NOERROR)
1725 pAd->BulkOutComplete++;
1727 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1729 pAd->Counters8023.GoodTransmits++;
1730 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1731 FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
1732 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1736 else // STATUS_OTHER
1740 pAd->BulkOutCompleteOther++;
1742 pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
1744 if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1745 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1746 fRTMP_ADAPTER_NIC_NOT_EXIST |
1747 fRTMP_ADAPTER_BULKOUT_RESET)))
1749 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1750 pAd->bulkResetPipeid = BulkOutPipeId;
1751 pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
1753 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1755 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
1756 DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
1757 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]));
1758 //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
1763 // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
1764 // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
1766 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1767 if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
1768 (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
1769 !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
1771 // Indicate There is data avaliable
1772 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
1774 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1776 // Always call Bulk routine, even reset bulk.
1777 // The protection of rest bulk should be in BulkOut routine
1778 RTUSBKickBulkOut(pAd);
1781 /* End of 2870_rtmp_init.c */