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 #include "../rt_config.h"
35 ========================================================================
37 Initialize receive data structures.
40 pAd Pointer to our adapter
47 Initialize all receive releated private buffer, include those define
48 in RTMP_ADAPTER structure and all private data structures. The mahor
49 work is to allocate buffer for each packet and chain buffer to
50 NDIS packet descriptor.
51 ========================================================================
53 NDIS_STATUS NICInitRecv(
57 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
58 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
61 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
64 //InterlockedExchange(&pAd->PendingRx, 0);
66 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
67 pAd->NextRxBulkInIndex = 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
68 pAd->NextRxBulkInPosition = 0;
70 for (i = 0; i < (RX_RING_SIZE); i++)
72 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
75 pRxContext->pUrb = RTUSB_ALLOC_URB(0);
76 if (pRxContext->pUrb == NULL)
78 Status = NDIS_STATUS_RESOURCES;
82 // Allocate transfer buffer
83 pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
84 if (pRxContext->TransferBuffer == NULL)
86 Status = NDIS_STATUS_RESOURCES;
90 NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
92 pRxContext->pAd = pAd;
93 pRxContext->pIrp = NULL;
94 pRxContext->InUse = FALSE;
95 pRxContext->IRPPending = FALSE;
96 pRxContext->Readable = FALSE;
97 //pRxContext->ReorderInUse = FALSE;
98 pRxContext->bRxHandling = FALSE;
99 pRxContext->BulkInOffset = 0;
102 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status));
106 for (i = 0; i < (RX_RING_SIZE); i++)
108 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
110 if (NULL != pRxContext->TransferBuffer)
112 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
113 pRxContext->TransferBuffer, pRxContext->data_dma);
114 pRxContext->TransferBuffer = NULL;
117 if (NULL != pRxContext->pUrb)
119 RTUSB_UNLINK_URB(pRxContext->pUrb);
120 RTUSB_FREE_URB(pRxContext->pUrb);
121 pRxContext->pUrb = NULL;
130 ========================================================================
132 Initialize transmit data structures.
135 pAd Pointer to our adapter
139 NDIS_STATUS_RESOURCES
142 ========================================================================
144 NDIS_STATUS NICInitTransmit(
145 IN PRTMP_ADAPTER pAd)
147 #define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \
148 Context->pUrb = RTUSB_ALLOC_URB(0); \
149 if (Context->pUrb == NULL) { \
150 DBGPRINT(RT_DEBUG_ERROR, msg1); \
151 Status = NDIS_STATUS_RESOURCES; \
154 Context->TransferBuffer = \
155 (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \
156 if (Context->TransferBuffer == NULL) { \
157 DBGPRINT(RT_DEBUG_ERROR, msg2); \
158 Status = NDIS_STATUS_RESOURCES; \
161 #define LM_URB_FREE(pObj, Context, BufferSize) \
162 if (NULL != Context->pUrb) { \
163 RTUSB_UNLINK_URB(Context->pUrb); \
164 RTUSB_FREE_URB(Context->pUrb); \
165 Context->pUrb = NULL; } \
166 if (NULL != Context->TransferBuffer) { \
167 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
168 Context->TransferBuffer, \
169 Context->data_dma); \
170 Context->TransferBuffer = NULL; }
173 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
174 PTX_CONTEXT pNullContext = &(pAd->NullContext);
175 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
176 PTX_CONTEXT pRTSContext = &(pAd->RTSContext);
177 PTX_CONTEXT pMLMEContext = NULL;
178 // PHT_TX_CONTEXT pHTTXContext = NULL;
179 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
181 // RTMP_TX_RING *pTxRing;
182 RTMP_MGMT_RING *pMgmtRing;
184 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
187 // Init 4 set of Tx parameters
188 for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
190 // Initialize all Transmit releated queues
191 InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
193 // Next Local tx ring pointer waiting for buck out
194 pAd->NextBulkOutIndex[acidx] = acidx;
195 pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
196 //pAd->DataBulkDoneIdx[acidx] = 0;
199 //pAd->NextMLMEIndex = 0;
200 //pAd->PushMgmtIndex = 0;
201 //pAd->PopMgmtIndex = 0;
202 //InterlockedExchange(&pAd->MgmtQueueSize, 0);
203 //InterlockedExchange(&pAd->TxCount, 0);
205 //pAd->PrioRingFirstIndex = 0;
206 //pAd->PrioRingTxCnt = 0;
211 // TX_RING_SIZE, 4 ACs
213 for(acidx=0; acidx<4; acidx++)
215 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
217 NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
219 LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
220 ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
222 ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
225 NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
226 pHTTXContext->pAd = pAd;
227 pHTTXContext->pIrp = NULL;
228 pHTTXContext->IRPPending = FALSE;
229 pHTTXContext->NextBulkOutPosition = 0;
230 pHTTXContext->ENextBulkOutPosition = 0;
231 pHTTXContext->CurWritePosition = 0;
232 pHTTXContext->CurWriteRealPos = 0;
233 pHTTXContext->BulkOutSize = 0;
234 pHTTXContext->BulkOutPipeId = acidx;
235 pHTTXContext->bRingEmpty = TRUE;
236 pHTTXContext->bCopySavePad = FALSE;
237 pAd->BulkOutPending[acidx] = FALSE;
245 // Allocate MGMT ring descriptor's memory
246 pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
247 os_alloc_mem(pAd, (PUCHAR *)(&pAd->MgmtDescRing.AllocVa), pAd->MgmtDescRing.AllocSize);
248 if (pAd->MgmtDescRing.AllocVa == NULL)
250 DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
251 Status = NDIS_STATUS_RESOURCES;
254 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
255 RingBaseVa = pAd->MgmtDescRing.AllocVa;
257 // Initialize MGMT Ring and associated buffer memory
258 pMgmtRing = &pAd->MgmtRing;
259 for (i = 0; i < MGMT_RING_SIZE; i++)
261 // link the pre-allocated Mgmt buffer to MgmtRing.Cell
262 pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
263 pMgmtRing->Cell[i].AllocVa = RingBaseVa;
264 pMgmtRing->Cell[i].pNdisPacket = NULL;
265 pMgmtRing->Cell[i].pNextNdisPacket = NULL;
267 //Allocate URB for MLMEContext
268 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
269 pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
270 if (pMLMEContext->pUrb == NULL)
272 DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
273 Status = NDIS_STATUS_RESOURCES;
276 pMLMEContext->pAd = pAd;
277 pMLMEContext->pIrp = NULL;
278 pMLMEContext->TransferBuffer = NULL;
279 pMLMEContext->InUse = FALSE;
280 pMLMEContext->IRPPending = FALSE;
281 pMLMEContext->bWaitingBulkOut = FALSE;
282 pMLMEContext->BulkOutSize = 0;
283 pMLMEContext->SelfIdx = i;
285 // Offset to next ring descriptor address
286 RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
288 DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
290 //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
291 pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
292 pAd->MgmtRing.TxCpuIdx = 0;
293 pAd->MgmtRing.TxDmaIdx = 0;
298 for(i=0; i<BEACON_RING_SIZE; i++) // 2
300 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
303 NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
306 LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
307 ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
309 ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
312 pBeaconContext->pAd = pAd;
313 pBeaconContext->pIrp = NULL;
314 pBeaconContext->InUse = FALSE;
315 pBeaconContext->IRPPending = FALSE;
321 NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
324 LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
325 ("<-- ERROR in Alloc TX NullContext urb!! \n"),
327 ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
330 pNullContext->pAd = pAd;
331 pNullContext->pIrp = NULL;
332 pNullContext->InUse = FALSE;
333 pNullContext->IRPPending = FALSE;
338 NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
341 LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
342 ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
344 ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
347 pRTSContext->pAd = pAd;
348 pRTSContext->pIrp = NULL;
349 pRTSContext->InUse = FALSE;
350 pRTSContext->IRPPending = FALSE;
355 //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
357 LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
358 ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
360 ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
363 pPsPollContext->pAd = pAd;
364 pPsPollContext->pIrp = NULL;
365 pPsPollContext->InUse = FALSE;
366 pPsPollContext->IRPPending = FALSE;
367 pPsPollContext->bAggregatible = FALSE;
368 pPsPollContext->LastOne = TRUE;
374 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status));
378 /* --------------------------- ERROR HANDLE --------------------------- */
380 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
383 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
386 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
389 for(i=0; i<BEACON_RING_SIZE; i++)
391 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
393 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
397 if (pAd->MgmtDescRing.AllocVa)
399 pMgmtRing = &pAd->MgmtRing;
400 for(i=0; i<MGMT_RING_SIZE; i++)
402 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
404 LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
406 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
407 pAd->MgmtDescRing.AllocVa = NULL;
411 for (acidx = 0; acidx < 4; acidx++)
413 PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
415 LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
418 // Here we didn't have any pre-allocated memory need to free.
425 ========================================================================
427 Allocate DMA memory blocks for send, receive.
430 pAd Pointer to our adapter
435 NDIS_STATUS_RESOURCES
438 ========================================================================
440 NDIS_STATUS RTMPAllocTxRxRingMemory(
441 IN PRTMP_ADAPTER pAd)
443 // COUNTER_802_11 pCounter = &pAd->WlanCounters;
448 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
453 // Init the CmdQ and CmdQLock
454 NdisAllocateSpinLock(&pAd->CmdQLock);
455 NdisAcquireSpinLock(&pAd->CmdQLock);
456 RTUSBInitializeCmdQ(&pAd->CmdQ);
457 NdisReleaseSpinLock(&pAd->CmdQLock);
460 NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
461 //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
462 NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
463 NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
464 NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
465 NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
466 NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
467 NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
468 NdisAllocateSpinLock(&pAd->BulkInLock);
470 for (num = 0; num < NUM_OF_TX_RING; num++)
472 NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
476 // NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX
478 // NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
479 // NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
481 // for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
483 // NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
489 // MacTableInitialize(pAd);
492 // Init send data structures and related parameters
494 Status = NICInitTransmit(pAd);
495 if (Status != NDIS_STATUS_SUCCESS)
499 // Init receive data structures and related parameters
501 Status = NICInitRecv(pAd);
502 if (Status != NDIS_STATUS_SUCCESS)
505 pAd->PendingIoCount = 1;
509 NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
510 pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
512 if (pAd->FragFrame.pFragPacket == NULL)
514 Status = NDIS_STATUS_RESOURCES;
517 DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
523 ========================================================================
525 Calls USB_InterfaceStop and frees memory allocated for the URBs
526 calls NdisMDeregisterDevice and frees the memory
527 allocated in VNetInitialize for the Adapter Object
530 *pAd the raxx interface data pointer
536 ========================================================================
538 VOID RTMPFreeTxRxRingMemory(
539 IN PRTMP_ADAPTER pAd)
541 #define LM_URB_FREE(pObj, Context, BufferSize) \
542 if (NULL != Context->pUrb) { \
543 RTUSB_UNLINK_URB(Context->pUrb); \
544 RTUSB_FREE_URB(Context->pUrb); \
545 Context->pUrb = NULL; } \
546 if (NULL != Context->TransferBuffer) { \
547 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
548 Context->TransferBuffer, \
549 Context->data_dma); \
550 Context->TransferBuffer = NULL; }
554 PTX_CONTEXT pNullContext = &pAd->NullContext;
555 PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
556 PTX_CONTEXT pRTSContext = &pAd->RTSContext;
557 // PHT_TX_CONTEXT pHTTXContext;
558 //PRTMP_REORDERBUF pReorderBuf;
559 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
560 // RTMP_TX_RING *pTxRing;
562 DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
565 // Free all resources for the RECEIVE buffer queue.
566 for(i=0; i<(RX_RING_SIZE); i++)
568 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
570 LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
573 // Free PsPoll frame resource
574 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
576 // Free NULL frame resource
577 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
579 // Free RTS frame resource
580 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
583 // Free beacon frame resource
584 for(i=0; i<BEACON_RING_SIZE; i++)
586 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
588 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
592 // Free mgmt frame resource
593 for(i = 0; i < MGMT_RING_SIZE; i++)
595 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
596 //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
597 if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
599 RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
600 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
601 pMLMEContext->TransferBuffer = NULL;
606 if (NULL != pMLMEContext->pUrb)
608 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
609 RTUSB_FREE_URB(pMLMEContext->pUrb);
610 pMLMEContext->pUrb = NULL;
614 if (pAd->MgmtDescRing.AllocVa)
615 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
618 // Free Tx frame resource
619 for (acidx = 0; acidx < 4; acidx++)
621 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
623 LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
626 if (pAd->FragFrame.pFragPacket)
627 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
631 NdisFreeSpinLock(&pAd->BulkOutLock[i]);
634 NdisFreeSpinLock(&pAd->BulkInLock);
635 NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
637 NdisFreeSpinLock(&pAd->CmdQLock);
638 // Clear all pending bulk-out request flags.
639 RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
641 // NdisFreeSpinLock(&pAd->MacTabLock);
643 // for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
645 // NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
648 DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n"));
653 ========================================================================
655 Write WLAN MAC address to USB 2870.
658 pAd Pointer to our adapter
664 ========================================================================
666 NDIS_STATUS RTUSBWriteHWMACAddress(
667 IN PRTMP_ADAPTER pAd)
669 MAC_DW0_STRUC StaMacReg0;
670 MAC_DW1_STRUC StaMacReg1;
671 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
675 // initialize the random number generator
676 RTMP_GetCurrentSystemTime(&NOW);
678 if (pAd->bLocalAdminMAC != TRUE)
680 pAd->CurrentAddress[0] = pAd->PermanentAddress[0];
681 pAd->CurrentAddress[1] = pAd->PermanentAddress[1];
682 pAd->CurrentAddress[2] = pAd->PermanentAddress[2];
683 pAd->CurrentAddress[3] = pAd->PermanentAddress[3];
684 pAd->CurrentAddress[4] = pAd->PermanentAddress[4];
685 pAd->CurrentAddress[5] = pAd->PermanentAddress[5];
687 // Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC
688 StaMacReg0.field.Byte0 = pAd->CurrentAddress[0];
689 StaMacReg0.field.Byte1 = pAd->CurrentAddress[1];
690 StaMacReg0.field.Byte2 = pAd->CurrentAddress[2];
691 StaMacReg0.field.Byte3 = pAd->CurrentAddress[3];
692 StaMacReg1.field.Byte4 = pAd->CurrentAddress[4];
693 StaMacReg1.field.Byte5 = pAd->CurrentAddress[5];
694 StaMacReg1.field.U2MeMask = 0xff;
695 DBGPRINT_RAW(RT_DEBUG_TRACE, ("Local MAC = %02x:%02x:%02x:%02x:%02x:%02x\n",
696 pAd->CurrentAddress[0], pAd->CurrentAddress[1], pAd->CurrentAddress[2],
697 pAd->CurrentAddress[3], pAd->CurrentAddress[4], pAd->CurrentAddress[5]));
699 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word);
700 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word);
706 ========================================================================
711 *pAd the raxx interface data pointer
717 ========================================================================
719 VOID RT28XXDMADisable(
720 IN RTMP_ADAPTER *pAd)
727 ========================================================================
732 *pAd the raxx interface data pointer
738 ========================================================================
740 VOID RT28XXDMAEnable(
741 IN RTMP_ADAPTER *pAd)
743 WPDMA_GLO_CFG_STRUC GloCfg;
744 USB_DMA_CFG_STRUC UsbCfg;
748 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
751 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
752 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
755 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
762 GloCfg.field.EnTXWriteBackDDONE = 1;
763 GloCfg.field.EnableRxDMA = 1;
764 GloCfg.field.EnableTxDMA = 1;
765 DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
766 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
769 UsbCfg.field.phyclear = 0;
770 /* usb version is 1.1,do not use bulk in aggregation */
771 if (pAd->BulkInMaxPacketSize == 512)
772 UsbCfg.field.RxBulkAggEn = 1;
773 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
774 UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
775 UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
776 UsbCfg.field.RxBulkEn = 1;
777 UsbCfg.field.TxBulkEn = 1;
779 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
783 /********************************************************************
785 * 2870 Beacon Update Related functions.
787 ********************************************************************/
790 ========================================================================
792 Write Beacon buffer to Asic.
795 *pAd the raxx interface data pointer
801 ========================================================================
803 VOID RT28xx_UpdateBeaconToAsic(
804 IN RTMP_ADAPTER *pAd,
809 PUCHAR pBeaconFrame = NULL;
812 BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
814 // USHORT shortValue;
815 BOOLEAN bBcnReq = FALSE;
819 if (pBeaconFrame == NULL)
821 DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
825 if (pBeaconSync == NULL)
827 DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
831 //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
832 // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
834 if (bBcnReq == FALSE)
836 /* when the ra interface is down, do not send its beacon frame */
838 for(i=0; i<TXWI_SIZE; i+=4) {
839 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
841 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
842 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
846 ptr = (PUCHAR)&pAd->BeaconTxWI;
847 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
848 { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
849 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
850 NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
853 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
855 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
857 longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
858 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
863 ptr = pBeaconSync->BeaconBuf[bcn_idx];
864 padding = (FrameLen & 0x01);
865 NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
867 for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
869 if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
871 NdisMoveMemory(ptr, pBeaconFrame, 2);
872 //shortValue = *ptr + (*(ptr+1)<<8);
873 //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
874 RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
880 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
882 // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
888 VOID RTUSBBssBeaconStop(
889 IN RTMP_ADAPTER *pAd)
891 BEACON_SYNC_STRUCT *pBeaconSync;
893 BOOLEAN Cancelled = TRUE;
895 pBeaconSync = pAd->CommonCfg.pBeaconSync;
896 if (pBeaconSync && pBeaconSync->EnableBeacon)
901 NumOfBcn = MAX_MESH_NUM;
904 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
906 for(i=0; i<NumOfBcn; i++)
908 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
909 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
911 for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
912 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
914 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
915 pBeaconSync->TimIELocationInBeacon[i] = 0;
917 pBeaconSync->BeaconBitMap = 0;
918 pBeaconSync->DtimBitOn = 0;
923 VOID RTUSBBssBeaconStart(
924 IN RTMP_ADAPTER *pAd)
927 BEACON_SYNC_STRUCT *pBeaconSync;
928 // LARGE_INTEGER tsfTime, deltaTime;
930 pBeaconSync = pAd->CommonCfg.pBeaconSync;
931 if (pBeaconSync && pBeaconSync->EnableBeacon)
936 NumOfBcn = MAX_MESH_NUM;
939 for(apidx=0; apidx<NumOfBcn; apidx++)
941 UCHAR CapabilityInfoLocationInBeacon = 0;
942 UCHAR TimIELocationInBeacon = 0;
945 NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
946 pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
947 pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
948 NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
950 pBeaconSync->BeaconBitMap = 0;
951 pBeaconSync->DtimBitOn = 0;
952 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
954 pAd->CommonCfg.BeaconAdjust = 0;
955 pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
956 pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
957 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n",
958 pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain));
959 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, 10 /*pAd->CommonCfg.BeaconPeriod*/);
965 VOID RTUSBBssBeaconInit(
966 IN RTMP_ADAPTER *pAd)
968 BEACON_SYNC_STRUCT *pBeaconSync;
971 os_alloc_mem(pAd, (PUCHAR *)(&pAd->CommonCfg.pBeaconSync), sizeof(BEACON_SYNC_STRUCT));
972 //NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
973 if (pAd->CommonCfg.pBeaconSync)
975 pBeaconSync = pAd->CommonCfg.pBeaconSync;
976 NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
977 for(i=0; i < HW_BEACON_MAX_COUNT; i++)
979 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
980 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
981 pBeaconSync->TimIELocationInBeacon[i] = 0;
982 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
984 pBeaconSync->BeaconBitMap = 0;
986 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
987 pBeaconSync->EnableBeacon = TRUE;
992 VOID RTUSBBssBeaconExit(
993 IN RTMP_ADAPTER *pAd)
995 BEACON_SYNC_STRUCT *pBeaconSync;
996 BOOLEAN Cancelled = TRUE;
999 if (pAd->CommonCfg.pBeaconSync)
1001 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1002 pBeaconSync->EnableBeacon = FALSE;
1003 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1004 pBeaconSync->BeaconBitMap = 0;
1006 for(i=0; i<HW_BEACON_MAX_COUNT; i++)
1008 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1009 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1010 pBeaconSync->TimIELocationInBeacon[i] = 0;
1011 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1014 os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
1015 pAd->CommonCfg.pBeaconSync = NULL;
1021 ========================================================================
1022 Routine Description:
1023 For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism
1024 to update the beacon context in each Beacon interval. Here we use a periodical timer
1025 to simulate the TBTT interrupt to handle the beacon context update.
1028 SystemSpecific1 - Not used.
1029 FunctionContext - Pointer to our Adapter context.
1030 SystemSpecific2 - Not used.
1031 SystemSpecific3 - Not used.
1036 ========================================================================
1038 VOID BeaconUpdateExec(
1039 IN PVOID SystemSpecific1,
1040 IN PVOID FunctionContext,
1041 IN PVOID SystemSpecific2,
1042 IN PVOID SystemSpecific3)
1044 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
1045 LARGE_INTEGER tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
1046 UINT32 delta, delta2MS, period2US, remain, remain_low, remain_high;
1047 // BOOLEAN positive;
1049 if (pAd->CommonCfg.IsUpdateBeacon==TRUE)
1051 ReSyncBeaconTime(pAd);
1056 RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1057 RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1060 //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1061 period2US = (pAd->CommonCfg.BeaconPeriod << 10);
1062 remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1063 remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1064 remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
1065 delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1067 delta2MS = (delta>>10);
1070 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100;
1071 pAd->CommonCfg.IsUpdateBeacon=FALSE;
1075 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10;
1076 pAd->CommonCfg.IsUpdateBeacon=TRUE;
1082 /********************************************************************
1084 * 2870 Radio on/off Related functions.
1086 ********************************************************************/
1087 VOID RT28xxUsbMlmeRadioOn(
1088 IN PRTMP_ADAPTER pAd)
1090 RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
1092 DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
1094 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1098 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
1099 RTMPusecDelay(10000);
1101 //NICResetFromError(pAd);
1104 RTMPEnableRxTx(pAd);
1106 if (pChipOps->AsicReverseRfFromSleepMode)
1107 pChipOps->AsicReverseRfFromSleepMode(pAd);
1109 // Clear Radio off flag
1110 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1112 RTUSBBulkReceive(pAd);
1115 RTMPSetLED(pAd, LED_RADIO_ON);
1119 VOID RT28xxUsbMlmeRadioOFF(
1120 IN PRTMP_ADAPTER pAd)
1122 WPDMA_GLO_CFG_STRUC GloCfg;
1125 DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
1127 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1130 // Clear PMKID cache.
1131 pAd->StaCfg.SavedPMKNum = 0;
1132 RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(BSSID_INFO)));
1134 // Link down first if any association exists
1135 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
1137 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1139 MLME_DISASSOC_REQ_STRUCT DisReq;
1140 MLME_QUEUE_ELEM *pMsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
1144 COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid);
1145 DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
1147 pMsgElem->Machine = ASSOC_STATE_MACHINE;
1148 pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
1149 pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
1150 NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
1152 MlmeDisassocReqAction(pAd, pMsgElem);
1155 RTMPusecDelay(1000);
1160 // Set Radio off flag
1161 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1164 // Link down first if any association exists
1165 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1166 LinkDown(pAd, FALSE);
1167 RTMPusecDelay(10000);
1169 //==========================================
1170 // Clean up old bss table
1171 BssTableInit(&pAd->ScanTab);
1175 RTMPSetLED(pAd, LED_RADIO_OFF);
1178 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1180 // Must using 40MHz.
1181 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
1185 // Must using 20MHz.
1186 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
1189 // Disable Tx/Rx DMA
1190 RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
1191 GloCfg.field.EnableTxDMA = 0;
1192 GloCfg.field.EnableRxDMA = 0;
1193 RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings
1195 // Waiting for DMA idle
1199 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1200 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1203 RTMPusecDelay(1000);
1206 // Disable MAC Tx/Rx
1207 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1208 Value &= (0xfffffff3);
1209 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1212 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1216 #endif // RTMP_MAC_USB //