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 *************************************************************************
30 #include "../rt_config.h"
33 ========================================================================
35 Initialize receive data structures.
38 pAd Pointer to our adapter
45 Initialize all receive releated private buffer, include those define
46 in RTMP_ADAPTER structure and all private data structures. The mahor
47 work is to allocate buffer for each packet and chain buffer to
48 NDIS packet descriptor.
49 ========================================================================
51 NDIS_STATUS NICInitRecv(IN PRTMP_ADAPTER pAd)
54 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
55 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
57 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
60 //InterlockedExchange(&pAd->PendingRx, 0);
62 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
63 pAd->NextRxBulkInIndex = 0; //RX_RING_SIZE -1; // Rx Bulk pointer
64 pAd->NextRxBulkInPosition = 0;
66 for (i = 0; i < (RX_RING_SIZE); i++) {
67 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
70 pRxContext->pUrb = RTUSB_ALLOC_URB(0);
71 if (pRxContext->pUrb == NULL) {
72 Status = NDIS_STATUS_RESOURCES;
75 // Allocate transfer buffer
76 pRxContext->TransferBuffer =
77 RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
78 &pRxContext->data_dma);
79 if (pRxContext->TransferBuffer == NULL) {
80 Status = NDIS_STATUS_RESOURCES;
84 NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
86 pRxContext->pAd = pAd;
87 pRxContext->pIrp = NULL;
88 pRxContext->InUse = FALSE;
89 pRxContext->IRPPending = FALSE;
90 pRxContext->Readable = FALSE;
91 //pRxContext->ReorderInUse = FALSE;
92 pRxContext->bRxHandling = FALSE;
93 pRxContext->BulkInOffset = 0;
96 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status));
100 for (i = 0; i < (RX_RING_SIZE); i++) {
101 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
103 if (NULL != pRxContext->TransferBuffer) {
104 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
105 pRxContext->TransferBuffer,
106 pRxContext->data_dma);
107 pRxContext->TransferBuffer = NULL;
110 if (NULL != pRxContext->pUrb) {
111 RTUSB_UNLINK_URB(pRxContext->pUrb);
112 RTUSB_FREE_URB(pRxContext->pUrb);
113 pRxContext->pUrb = NULL;
121 ========================================================================
123 Initialize transmit data structures.
126 pAd Pointer to our adapter
130 NDIS_STATUS_RESOURCES
133 ========================================================================
135 NDIS_STATUS NICInitTransmit(IN PRTMP_ADAPTER pAd)
137 #define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \
138 Context->pUrb = RTUSB_ALLOC_URB(0); \
139 if (Context->pUrb == NULL) { \
140 DBGPRINT(RT_DEBUG_ERROR, msg1); \
141 Status = NDIS_STATUS_RESOURCES; \
144 Context->TransferBuffer = \
145 (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \
146 if (Context->TransferBuffer == NULL) { \
147 DBGPRINT(RT_DEBUG_ERROR, msg2); \
148 Status = NDIS_STATUS_RESOURCES; \
151 #define LM_URB_FREE(pObj, Context, BufferSize) \
152 if (NULL != Context->pUrb) { \
153 RTUSB_UNLINK_URB(Context->pUrb); \
154 RTUSB_FREE_URB(Context->pUrb); \
155 Context->pUrb = NULL; } \
156 if (NULL != Context->TransferBuffer) { \
157 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
158 Context->TransferBuffer, \
159 Context->data_dma); \
160 Context->TransferBuffer = NULL; }
163 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
164 PTX_CONTEXT pNullContext = &(pAd->NullContext);
165 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
166 PTX_CONTEXT pRTSContext = &(pAd->RTSContext);
167 PTX_CONTEXT pMLMEContext = NULL;
168 // PHT_TX_CONTEXT pHTTXContext = NULL;
169 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
171 // RTMP_TX_RING *pTxRing;
172 RTMP_MGMT_RING *pMgmtRing;
174 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
177 // Init 4 set of Tx parameters
178 for (acidx = 0; acidx < NUM_OF_TX_RING; acidx++) {
179 // Initialize all Transmit releated queues
180 InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
182 // Next Local tx ring pointer waiting for buck out
183 pAd->NextBulkOutIndex[acidx] = acidx;
184 pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
185 //pAd->DataBulkDoneIdx[acidx] = 0;
188 //pAd->NextMLMEIndex = 0;
189 //pAd->PushMgmtIndex = 0;
190 //pAd->PopMgmtIndex = 0;
191 //InterlockedExchange(&pAd->MgmtQueueSize, 0);
192 //InterlockedExchange(&pAd->TxCount, 0);
194 //pAd->PrioRingFirstIndex = 0;
195 //pAd->PrioRingTxCnt = 0;
199 // TX_RING_SIZE, 4 ACs
201 for (acidx = 0; acidx < 4; acidx++) {
202 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
204 NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
206 LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER,
207 sizeof(HTTX_BUFFER), Status,
208 ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n",
210 ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n",
213 NdisZeroMemory(pHTTXContext->TransferBuffer->
215 pHTTXContext->pAd = pAd;
216 pHTTXContext->pIrp = NULL;
217 pHTTXContext->IRPPending = FALSE;
218 pHTTXContext->NextBulkOutPosition = 0;
219 pHTTXContext->ENextBulkOutPosition = 0;
220 pHTTXContext->CurWritePosition = 0;
221 pHTTXContext->CurWriteRealPos = 0;
222 pHTTXContext->BulkOutSize = 0;
223 pHTTXContext->BulkOutPipeId = acidx;
224 pHTTXContext->bRingEmpty = TRUE;
225 pHTTXContext->bCopySavePad = FALSE;
226 pAd->BulkOutPending[acidx] = FALSE;
233 // Allocate MGMT ring descriptor's memory
234 pAd->MgmtDescRing.AllocSize =
235 MGMT_RING_SIZE * sizeof(TX_CONTEXT);
236 os_alloc_mem(pAd, (PUCHAR *) (&pAd->MgmtDescRing.AllocVa),
237 pAd->MgmtDescRing.AllocSize);
238 if (pAd->MgmtDescRing.AllocVa == NULL) {
239 DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
240 Status = NDIS_STATUS_RESOURCES;
243 NdisZeroMemory(pAd->MgmtDescRing.AllocVa,
244 pAd->MgmtDescRing.AllocSize);
245 RingBaseVa = pAd->MgmtDescRing.AllocVa;
247 // Initialize MGMT Ring and associated buffer memory
248 pMgmtRing = &pAd->MgmtRing;
249 for (i = 0; i < MGMT_RING_SIZE; i++) {
250 // link the pre-allocated Mgmt buffer to MgmtRing.Cell
251 pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
252 pMgmtRing->Cell[i].AllocVa = RingBaseVa;
253 pMgmtRing->Cell[i].pNdisPacket = NULL;
254 pMgmtRing->Cell[i].pNextNdisPacket = NULL;
256 //Allocate URB for MLMEContext
258 (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
259 pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
260 if (pMLMEContext->pUrb == NULL) {
261 DBGPRINT(RT_DEBUG_ERROR,
262 ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n",
264 Status = NDIS_STATUS_RESOURCES;
267 pMLMEContext->pAd = pAd;
268 pMLMEContext->pIrp = NULL;
269 pMLMEContext->TransferBuffer = NULL;
270 pMLMEContext->InUse = FALSE;
271 pMLMEContext->IRPPending = FALSE;
272 pMLMEContext->bWaitingBulkOut = FALSE;
273 pMLMEContext->BulkOutSize = 0;
274 pMLMEContext->SelfIdx = i;
276 // Offset to next ring descriptor address
277 RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
279 DBGPRINT(RT_DEBUG_TRACE,
280 ("MGMT Ring: total %d entry allocated\n", i));
282 //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
283 pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
284 pAd->MgmtRing.TxCpuIdx = 0;
285 pAd->MgmtRing.TxDmaIdx = 0;
290 for (i = 0; i < BEACON_RING_SIZE; i++) // 2
292 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
294 NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
297 LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER,
298 sizeof(TX_BUFFER), Status,
299 ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n",
301 ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n",
304 pBeaconContext->pAd = pAd;
305 pBeaconContext->pIrp = NULL;
306 pBeaconContext->InUse = FALSE;
307 pBeaconContext->IRPPending = FALSE;
313 NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
316 LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER),
318 ("<-- ERROR in Alloc TX NullContext urb!! \n"),
320 ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
323 pNullContext->pAd = pAd;
324 pNullContext->pIrp = NULL;
325 pNullContext->InUse = FALSE;
326 pNullContext->IRPPending = FALSE;
331 NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
334 LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER),
336 ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
338 ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
341 pRTSContext->pAd = pAd;
342 pRTSContext->pIrp = NULL;
343 pRTSContext->InUse = FALSE;
344 pRTSContext->IRPPending = FALSE;
349 //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
351 LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER,
352 sizeof(TX_BUFFER), Status,
353 ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
355 ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
358 pPsPollContext->pAd = pAd;
359 pPsPollContext->pIrp = NULL;
360 pPsPollContext->InUse = FALSE;
361 pPsPollContext->IRPPending = FALSE;
362 pPsPollContext->bAggregatible = FALSE;
363 pPsPollContext->LastOne = TRUE;
368 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status));
372 /* --------------------------- ERROR HANDLE --------------------------- */
374 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
377 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
380 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
383 for (i = 0; i < BEACON_RING_SIZE; i++) {
384 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
386 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
390 if (pAd->MgmtDescRing.AllocVa) {
391 pMgmtRing = &pAd->MgmtRing;
392 for (i = 0; i < MGMT_RING_SIZE; i++) {
394 (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
396 LM_URB_FREE(pObj, pMLMEContext,
399 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
400 pAd->MgmtDescRing.AllocVa = NULL;
404 for (acidx = 0; acidx < 4; acidx++) {
405 PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
407 LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
410 // Here we didn't have any pre-allocated memory need to free.
416 ========================================================================
418 Allocate DMA memory blocks for send, receive.
421 pAd Pointer to our adapter
426 NDIS_STATUS_RESOURCES
429 ========================================================================
431 NDIS_STATUS RTMPAllocTxRxRingMemory(IN PRTMP_ADAPTER pAd)
433 // COUNTER_802_11 pCounter = &pAd->WlanCounters;
437 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
440 // Init the CmdQ and CmdQLock
441 NdisAllocateSpinLock(&pAd->CmdQLock);
442 NdisAcquireSpinLock(&pAd->CmdQLock);
443 RTUSBInitializeCmdQ(&pAd->CmdQ);
444 NdisReleaseSpinLock(&pAd->CmdQLock);
446 NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
447 //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
448 NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
449 NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
450 NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
451 NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
452 NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
453 NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
454 NdisAllocateSpinLock(&pAd->BulkInLock);
456 for (num = 0; num < NUM_OF_TX_RING; num++) {
457 NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
460 // NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX
462 // NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
463 // NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
465 // for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
467 // NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
473 // MacTableInitialize(pAd);
476 // Init send data structures and related parameters
478 Status = NICInitTransmit(pAd);
479 if (Status != NDIS_STATUS_SUCCESS)
483 // Init receive data structures and related parameters
485 Status = NICInitRecv(pAd);
486 if (Status != NDIS_STATUS_SUCCESS)
489 pAd->PendingIoCount = 1;
493 NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
494 pAd->FragFrame.pFragPacket =
495 RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
497 if (pAd->FragFrame.pFragPacket == NULL) {
498 Status = NDIS_STATUS_RESOURCES;
502 ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
507 ========================================================================
509 Calls USB_InterfaceStop and frees memory allocated for the URBs
510 calls NdisMDeregisterDevice and frees the memory
511 allocated in VNetInitialize for the Adapter Object
514 *pAd the raxx interface data pointer
520 ========================================================================
522 VOID RTMPFreeTxRxRingMemory(IN PRTMP_ADAPTER pAd)
524 #define LM_URB_FREE(pObj, Context, BufferSize) \
525 if (NULL != Context->pUrb) { \
526 RTUSB_UNLINK_URB(Context->pUrb); \
527 RTUSB_FREE_URB(Context->pUrb); \
528 Context->pUrb = NULL; } \
529 if (NULL != Context->TransferBuffer) { \
530 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
531 Context->TransferBuffer, \
532 Context->data_dma); \
533 Context->TransferBuffer = NULL; }
536 PTX_CONTEXT pNullContext = &pAd->NullContext;
537 PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
538 PTX_CONTEXT pRTSContext = &pAd->RTSContext;
539 // PHT_TX_CONTEXT pHTTXContext;
540 //PRTMP_REORDERBUF pReorderBuf;
541 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
542 // RTMP_TX_RING *pTxRing;
544 DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
547 // Free all resources for the RECEIVE buffer queue.
548 for (i = 0; i < (RX_RING_SIZE); i++) {
549 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
551 LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
554 // Free PsPoll frame resource
555 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
557 // Free NULL frame resource
558 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
560 // Free RTS frame resource
561 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
563 // Free beacon frame resource
564 for (i = 0; i < BEACON_RING_SIZE; i++) {
565 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
567 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
570 // Free mgmt frame resource
571 for (i = 0; i < MGMT_RING_SIZE; i++) {
572 PTX_CONTEXT pMLMEContext =
573 (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
574 //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
575 if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) {
576 RTMPFreeNdisPacket(pAd,
577 pAd->MgmtRing.Cell[i].pNdisPacket);
578 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
579 pMLMEContext->TransferBuffer = NULL;
583 if (NULL != pMLMEContext->pUrb) {
584 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
585 RTUSB_FREE_URB(pMLMEContext->pUrb);
586 pMLMEContext->pUrb = NULL;
590 if (pAd->MgmtDescRing.AllocVa)
591 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
593 // Free Tx frame resource
594 for (acidx = 0; acidx < 4; acidx++) {
595 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
597 LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
600 if (pAd->FragFrame.pFragPacket)
601 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket,
602 NDIS_STATUS_SUCCESS);
604 for (i = 0; i < 6; i++) {
605 NdisFreeSpinLock(&pAd->BulkOutLock[i]);
608 NdisFreeSpinLock(&pAd->BulkInLock);
609 NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
611 NdisFreeSpinLock(&pAd->CmdQLock);
612 // Clear all pending bulk-out request flags.
613 RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
615 // NdisFreeSpinLock(&pAd->MacTabLock);
617 // for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
619 // NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
622 DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n"));
626 ========================================================================
628 Write WLAN MAC address to USB 2870.
631 pAd Pointer to our adapter
637 ========================================================================
639 NDIS_STATUS RTUSBWriteHWMACAddress(IN PRTMP_ADAPTER pAd)
641 MAC_DW0_STRUC StaMacReg0;
642 MAC_DW1_STRUC StaMacReg1;
643 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
646 // initialize the random number generator
647 RTMP_GetCurrentSystemTime(&NOW);
649 if (pAd->bLocalAdminMAC != TRUE) {
650 pAd->CurrentAddress[0] = pAd->PermanentAddress[0];
651 pAd->CurrentAddress[1] = pAd->PermanentAddress[1];
652 pAd->CurrentAddress[2] = pAd->PermanentAddress[2];
653 pAd->CurrentAddress[3] = pAd->PermanentAddress[3];
654 pAd->CurrentAddress[4] = pAd->PermanentAddress[4];
655 pAd->CurrentAddress[5] = pAd->PermanentAddress[5];
657 // Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC
658 StaMacReg0.field.Byte0 = pAd->CurrentAddress[0];
659 StaMacReg0.field.Byte1 = pAd->CurrentAddress[1];
660 StaMacReg0.field.Byte2 = pAd->CurrentAddress[2];
661 StaMacReg0.field.Byte3 = pAd->CurrentAddress[3];
662 StaMacReg1.field.Byte4 = pAd->CurrentAddress[4];
663 StaMacReg1.field.Byte5 = pAd->CurrentAddress[5];
664 StaMacReg1.field.U2MeMask = 0xff;
665 DBGPRINT_RAW(RT_DEBUG_TRACE,
666 ("Local MAC = %02x:%02x:%02x:%02x:%02x:%02x\n",
667 pAd->CurrentAddress[0], pAd->CurrentAddress[1],
668 pAd->CurrentAddress[2], pAd->CurrentAddress[3],
669 pAd->CurrentAddress[4], pAd->CurrentAddress[5]));
671 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word);
672 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word);
677 ========================================================================
682 *pAd the raxx interface data pointer
688 ========================================================================
690 VOID RT28XXDMADisable(IN RTMP_ADAPTER * pAd)
696 ========================================================================
701 *pAd the raxx interface data pointer
707 ========================================================================
709 VOID RT28XXDMAEnable(IN RTMP_ADAPTER * pAd)
711 WPDMA_GLO_CFG_STRUC GloCfg;
712 USB_DMA_CFG_STRUC UsbCfg;
715 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
717 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
718 if ((GloCfg.field.TxDMABusy == 0)
719 && (GloCfg.field.RxDMABusy == 0))
722 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
728 GloCfg.field.EnTXWriteBackDDONE = 1;
729 GloCfg.field.EnableRxDMA = 1;
730 GloCfg.field.EnableTxDMA = 1;
731 DBGPRINT(RT_DEBUG_TRACE,
732 ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
733 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
736 UsbCfg.field.phyclear = 0;
737 /* usb version is 1.1,do not use bulk in aggregation */
738 if (pAd->BulkInMaxPacketSize == 512)
739 UsbCfg.field.RxBulkAggEn = 1;
740 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
741 UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE / 1024) - 3;
742 UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
743 UsbCfg.field.RxBulkEn = 1;
744 UsbCfg.field.TxBulkEn = 1;
746 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
750 /********************************************************************
752 * 2870 Beacon Update Related functions.
754 ********************************************************************/
757 ========================================================================
759 Write Beacon buffer to Asic.
762 *pAd the raxx interface data pointer
768 ========================================================================
770 VOID RT28xx_UpdateBeaconToAsic(IN RTMP_ADAPTER * pAd,
772 IN ULONG FrameLen, IN ULONG UpdatePos)
774 PUCHAR pBeaconFrame = NULL;
777 BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
779 // USHORT shortValue;
780 BOOLEAN bBcnReq = FALSE;
783 if (pBeaconFrame == NULL) {
784 DBGPRINT(RT_DEBUG_ERROR, ("pBeaconFrame is NULL!\n"));
788 if (pBeaconSync == NULL) {
789 DBGPRINT(RT_DEBUG_ERROR, ("pBeaconSync is NULL!\n"));
792 //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
793 // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
795 if (bBcnReq == FALSE) {
796 /* when the ra interface is down, do not send its beacon frame */
798 for (i = 0; i < TXWI_SIZE; i += 4) {
799 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
802 pBeaconSync->BeaconBitMap &=
803 (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
804 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
806 ptr = (PUCHAR) & pAd->BeaconTxWI;
807 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
808 pBeaconSync->BeaconBitMap &=
809 (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
810 NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx],
811 &pAd->BeaconTxWI, TXWI_SIZE);
814 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) !=
816 for (i = 0; i < TXWI_SIZE; i += 4) // 16-byte TXWI field
819 *ptr + (*(ptr + 1) << 8) +
820 (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
822 pAd->BeaconOffset[bcn_idx] + i,
828 ptr = pBeaconSync->BeaconBuf[bcn_idx];
829 padding = (FrameLen & 0x01);
830 NdisZeroMemory((PUCHAR) (pBeaconFrame + FrameLen), padding);
832 for (i = 0; i < FrameLen /*HW_BEACON_OFFSET */ ; i += 2) {
833 if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE) {
834 NdisMoveMemory(ptr, pBeaconFrame, 2);
835 //shortValue = *ptr + (*(ptr+1)<<8);
836 //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
838 pAd->BeaconOffset[bcn_idx] +
839 TXWI_SIZE + i, ptr, 2);
845 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
847 // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
852 VOID RTUSBBssBeaconStop(IN RTMP_ADAPTER * pAd)
854 BEACON_SYNC_STRUCT *pBeaconSync;
856 BOOLEAN Cancelled = TRUE;
858 pBeaconSync = pAd->CommonCfg.pBeaconSync;
859 if (pBeaconSync && pBeaconSync->EnableBeacon) {
863 NumOfBcn = MAX_MESH_NUM;
866 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
868 for (i = 0; i < NumOfBcn; i++) {
869 NdisZeroMemory(pBeaconSync->BeaconBuf[i],
871 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
873 for (offset = 0; offset < HW_BEACON_OFFSET; offset += 4)
875 pAd->BeaconOffset[i] + offset,
878 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
879 pBeaconSync->TimIELocationInBeacon[i] = 0;
881 pBeaconSync->BeaconBitMap = 0;
882 pBeaconSync->DtimBitOn = 0;
886 VOID RTUSBBssBeaconStart(IN RTMP_ADAPTER * pAd)
889 BEACON_SYNC_STRUCT *pBeaconSync;
890 // LARGE_INTEGER tsfTime, deltaTime;
892 pBeaconSync = pAd->CommonCfg.pBeaconSync;
893 if (pBeaconSync && pBeaconSync->EnableBeacon) {
897 NumOfBcn = MAX_MESH_NUM;
900 for (apidx = 0; apidx < NumOfBcn; apidx++) {
901 UCHAR CapabilityInfoLocationInBeacon = 0;
902 UCHAR TimIELocationInBeacon = 0;
904 NdisZeroMemory(pBeaconSync->BeaconBuf[apidx],
906 pBeaconSync->CapabilityInfoLocationInBeacon[apidx] =
907 CapabilityInfoLocationInBeacon;
908 pBeaconSync->TimIELocationInBeacon[apidx] =
909 TimIELocationInBeacon;
910 NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx],
913 pBeaconSync->BeaconBitMap = 0;
914 pBeaconSync->DtimBitOn = 0;
915 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
917 pAd->CommonCfg.BeaconAdjust = 0;
918 pAd->CommonCfg.BeaconFactor =
919 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
920 pAd->CommonCfg.BeaconRemain =
921 (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
922 DBGPRINT(RT_DEBUG_TRACE,
923 ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n",
924 pAd->CommonCfg.BeaconFactor,
925 pAd->CommonCfg.BeaconRemain));
926 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer,
927 10 /*pAd->CommonCfg.BeaconPeriod */ );
932 VOID RTUSBBssBeaconInit(IN RTMP_ADAPTER * pAd)
934 BEACON_SYNC_STRUCT *pBeaconSync;
937 os_alloc_mem(pAd, (PUCHAR *) (&pAd->CommonCfg.pBeaconSync),
938 sizeof(BEACON_SYNC_STRUCT));
939 //NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
940 if (pAd->CommonCfg.pBeaconSync) {
941 pBeaconSync = pAd->CommonCfg.pBeaconSync;
942 NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
943 for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
944 NdisZeroMemory(pBeaconSync->BeaconBuf[i],
946 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
947 pBeaconSync->TimIELocationInBeacon[i] = 0;
948 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
950 pBeaconSync->BeaconBitMap = 0;
952 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
953 pBeaconSync->EnableBeacon = TRUE;
957 VOID RTUSBBssBeaconExit(IN RTMP_ADAPTER * pAd)
959 BEACON_SYNC_STRUCT *pBeaconSync;
960 BOOLEAN Cancelled = TRUE;
963 if (pAd->CommonCfg.pBeaconSync) {
964 pBeaconSync = pAd->CommonCfg.pBeaconSync;
965 pBeaconSync->EnableBeacon = FALSE;
966 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
967 pBeaconSync->BeaconBitMap = 0;
969 for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
970 NdisZeroMemory(pBeaconSync->BeaconBuf[i],
972 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
973 pBeaconSync->TimIELocationInBeacon[i] = 0;
974 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
977 os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
978 pAd->CommonCfg.pBeaconSync = NULL;
983 ========================================================================
985 For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism
986 to update the beacon context in each Beacon interval. Here we use a periodical timer
987 to simulate the TBTT interrupt to handle the beacon context update.
990 SystemSpecific1 - Not used.
991 FunctionContext - Pointer to our Adapter context.
992 SystemSpecific2 - Not used.
993 SystemSpecific3 - Not used.
998 ========================================================================
1000 VOID BeaconUpdateExec(IN PVOID SystemSpecific1,
1001 IN PVOID FunctionContext,
1002 IN PVOID SystemSpecific2, IN PVOID SystemSpecific3)
1004 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) FunctionContext;
1005 LARGE_INTEGER tsfTime_a; //, tsfTime_b, deltaTime_exp, deltaTime_ab;
1006 UINT32 delta, delta2MS, period2US, remain, remain_low, remain_high;
1007 // BOOLEAN positive;
1009 if (pAd->CommonCfg.IsUpdateBeacon == TRUE) {
1010 ReSyncBeaconTime(pAd);
1014 RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1015 RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1017 //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1018 period2US = (pAd->CommonCfg.BeaconPeriod << 10);
1019 remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1020 remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1022 (remain_high + remain_low) % (pAd->CommonCfg.BeaconPeriod << 10);
1023 delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1025 delta2MS = (delta >> 10);
1026 if (delta2MS > 150) {
1027 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100;
1028 pAd->CommonCfg.IsUpdateBeacon = FALSE;
1030 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10;
1031 pAd->CommonCfg.IsUpdateBeacon = TRUE;
1036 /********************************************************************
1038 * 2870 Radio on/off Related functions.
1040 ********************************************************************/
1041 VOID RT28xxUsbMlmeRadioOn(IN PRTMP_ADAPTER pAd)
1043 RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
1045 DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOn()\n"));
1047 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1051 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
1052 RTMPusecDelay(10000);
1054 //NICResetFromError(pAd);
1057 RTMPEnableRxTx(pAd);
1059 if (pChipOps->AsicReverseRfFromSleepMode)
1060 pChipOps->AsicReverseRfFromSleepMode(pAd);
1062 // Clear Radio off flag
1063 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1065 RTUSBBulkReceive(pAd);
1068 RTMPSetLED(pAd, LED_RADIO_ON);
1071 VOID RT28xxUsbMlmeRadioOFF(IN PRTMP_ADAPTER pAd)
1073 WPDMA_GLO_CFG_STRUC GloCfg;
1076 DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOFF()\n"));
1078 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1081 // Clear PMKID cache.
1082 pAd->StaCfg.SavedPMKNum = 0;
1083 RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(BSSID_INFO)));
1085 // Link down first if any association exists
1086 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
1087 if (INFRA_ON(pAd) || ADHOC_ON(pAd)) {
1088 MLME_DISASSOC_REQ_STRUCT DisReq;
1089 MLME_QUEUE_ELEM *pMsgElem =
1090 (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM),
1094 COPY_MAC_ADDR(&DisReq.Addr,
1095 pAd->CommonCfg.Bssid);
1096 DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
1098 pMsgElem->Machine = ASSOC_STATE_MACHINE;
1099 pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
1101 sizeof(MLME_DISASSOC_REQ_STRUCT);
1102 NdisMoveMemory(pMsgElem->Msg, &DisReq,
1104 (MLME_DISASSOC_REQ_STRUCT));
1106 MlmeDisassocReqAction(pAd, pMsgElem);
1109 RTMPusecDelay(1000);
1113 // Set Radio off flag
1114 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1117 // Link down first if any association exists
1118 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1119 LinkDown(pAd, FALSE);
1120 RTMPusecDelay(10000);
1122 //==========================================
1123 // Clean up old bss table
1124 BssTableInit(&pAd->ScanTab);
1128 RTMPSetLED(pAd, LED_RADIO_OFF);
1130 if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
1131 // Must using 40MHz.
1132 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
1134 // Must using 20MHz.
1135 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
1138 // Disable Tx/Rx DMA
1139 RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
1140 GloCfg.field.EnableTxDMA = 0;
1141 GloCfg.field.EnableRxDMA = 0;
1142 RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings
1144 // Waiting for DMA idle
1147 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1148 if ((GloCfg.field.TxDMABusy == 0)
1149 && (GloCfg.field.RxDMABusy == 0))
1152 RTMPusecDelay(1000);
1153 } while (i++ < 100);
1155 // Disable MAC Tx/Rx
1156 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1157 Value &= (0xfffffff3);
1158 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1161 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1165 #endif // RTMP_MAC_USB //