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 struct rt_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
int NICInitRecv(struct rt_rtmp_adapter *pAd)
54
int Status = NDIS_STATUS_SUCCESS;
55
struct os_cookie *pObj = (struct os_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
struct rt_rx_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
struct rt_rx_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
int NICInitTransmit(struct rt_rtmp_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
int Status = NDIS_STATUS_SUCCESS;
164
struct rt_tx_context *pNullContext = &(pAd->NullContext);
165
struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext);
166
struct rt_tx_context *pRTSContext = &(pAd->RTSContext);
167
struct rt_tx_context *pMLMEContext = NULL;
168
/* struct rt_ht_tx_context *pHTTXContext = NULL; */
169
struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
171
/* struct rt_rtmp_tx_ring *pTxRing; */
172
struct rt_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
struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
204
NdisZeroMemory(pHTTXContext, sizeof(struct rt_ht_tx_context));
206
LM_USB_ALLOC(pObj, pHTTXContext, struct rt_httx_buffer *,
207
sizeof(struct rt_httx_buffer), Status,
208
("<-- ERROR in Alloc TX TxContext[%d] urb!\n",
210
("<-- ERROR in Alloc TX TxContext[%d] struct rt_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(struct rt_tx_context);
236
os_alloc_mem(pAd, (u8 **) (&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(struct rt_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
(struct rt_tx_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 = (u8 *)RingBaseVa + sizeof(struct rt_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;
288
/* BEACON_RING_SIZE */
290
for (i = 0; i < BEACON_RING_SIZE; i++) /* 2 */
292
struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
294
NdisZeroMemory(pBeaconContext, sizeof(struct rt_tx_context));
297
LM_USB_ALLOC(pObj, pBeaconContext, struct rt_tx_buffer *,
298
sizeof(struct rt_tx_buffer), Status,
299
("<-- ERROR in Alloc TX BeaconContext[%d] urb!\n",
301
("<-- ERROR in Alloc TX BeaconContext[%d] struct rt_tx_buffer!\n",
304
pBeaconContext->pAd = pAd;
305
pBeaconContext->pIrp = NULL;
306
pBeaconContext->InUse = FALSE;
307
pBeaconContext->IRPPending = FALSE;
313
NdisZeroMemory(pNullContext, sizeof(struct rt_tx_context));
316
LM_USB_ALLOC(pObj, pNullContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
318
("<-- ERROR in Alloc TX NullContext urb!\n"),
320
("<-- ERROR in Alloc TX NullContext struct rt_tx_buffer!\n"),
323
pNullContext->pAd = pAd;
324
pNullContext->pIrp = NULL;
325
pNullContext->InUse = FALSE;
326
pNullContext->IRPPending = FALSE;
331
NdisZeroMemory(pRTSContext, sizeof(struct rt_tx_context));
334
LM_USB_ALLOC(pObj, pRTSContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
336
("<-- ERROR in Alloc TX RTSContext urb!\n"),
338
("<-- ERROR in Alloc TX RTSContext struct rt_tx_buffer!\n"),
341
pRTSContext->pAd = pAd;
342
pRTSContext->pIrp = NULL;
343
pRTSContext->InUse = FALSE;
344
pRTSContext->IRPPending = FALSE;
349
/*NdisZeroMemory(pPsPollContext, sizeof(struct rt_tx_context)); */
351
LM_USB_ALLOC(pObj, pPsPollContext, struct rt_tx_buffer *,
352
sizeof(struct rt_tx_buffer), Status,
353
("<-- ERROR in Alloc TX PsPollContext urb!\n"),
355
("<-- ERROR in Alloc TX PsPollContext struct rt_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(struct rt_tx_buffer));
377
LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
380
LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
383
for (i = 0; i < BEACON_RING_SIZE; i++) {
384
struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
386
LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
390
if (pAd->MgmtDescRing.AllocVa) {
391
pMgmtRing = &pAd->MgmtRing;
392
for (i = 0; i < MGMT_RING_SIZE; i++) {
394
(struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
396
LM_URB_FREE(pObj, pMLMEContext,
397
sizeof(struct rt_tx_buffer));
399
os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
400
pAd->MgmtDescRing.AllocVa = NULL;
404
for (acidx = 0; acidx < 4; acidx++) {
405
struct rt_ht_tx_context *pTxContext = &(pAd->TxContext[acidx]);
407
LM_URB_FREE(pObj, pTxContext, sizeof(struct rt_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
int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd)
433
/* struct rt_counter_802_11 pCounter = &pAd->WlanCounters; */
437
DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
440
/* Init the struct rt_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(struct rt_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(struct rt_rtmp_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
struct rt_tx_context *pNullContext = &pAd->NullContext;
537
struct rt_tx_context *pPsPollContext = &pAd->PsPollContext;
538
struct rt_tx_context *pRTSContext = &pAd->RTSContext;
539
/* struct rt_ht_tx_context *pHTTXContext; */
540
/*PRTMP_REORDERBUF pReorderBuf; */
541
struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
542
/* struct rt_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
struct rt_rx_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(struct rt_tx_buffer));
557
/* Free NULL frame resource */
558
LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
560
/* Free RTS frame resource */
561
LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
563
/* Free beacon frame resource */
564
for (i = 0; i < BEACON_RING_SIZE; i++) {
565
struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
567
LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
570
/* Free mgmt frame resource */
571
for (i = 0; i < MGMT_RING_SIZE; i++) {
572
struct rt_tx_context *pMLMEContext =
573
(struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
574
/*LM_URB_FREE(pObj, pMLMEContext, sizeof(struct rt_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
struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
597
LM_URB_FREE(pObj, pHTTXContext, sizeof(struct rt_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
int RTUSBWriteHWMACAddress(struct rt_rtmp_adapter *pAd)
641
MAC_DW0_STRUC StaMacReg0;
642
MAC_DW1_STRUC StaMacReg1;
643
int 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(struct rt_rtmp_adapter *pAd)
696
========================================================================
701
*pAd the raxx interface data pointer
707
========================================================================
709
void RT28XXDMAEnable(struct rt_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(struct rt_rtmp_adapter *pAd,
772
unsigned long FrameLen, unsigned long UpdatePos)
774
u8 *pBeaconFrame = NULL;
777
struct rt_beacon_sync *pBeaconSync = pAd->CommonCfg.pBeaconSync;
779
/* u16 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 = (u8 *)& 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((u8 *)(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(struct rt_rtmp_adapter *pAd)
854
struct rt_beacon_sync *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(struct rt_rtmp_adapter *pAd)
889
struct rt_beacon_sync *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
u8 CapabilityInfoLocationInBeacon = 0;
902
u8 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(struct rt_rtmp_adapter *pAd)
934
struct rt_beacon_sync *pBeaconSync;
937
os_alloc_mem(pAd, (u8 **) (&pAd->CommonCfg.pBeaconSync),
938
sizeof(struct rt_beacon_sync));
939
/*NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(struct rt_beacon_sync), MEM_ALLOC_FLAG); */
940
if (pAd->CommonCfg.pBeaconSync) {
941
pBeaconSync = pAd->CommonCfg.pBeaconSync;
942
NdisZeroMemory(pBeaconSync, sizeof(struct rt_beacon_sync));
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(struct rt_rtmp_adapter *pAd)
959
struct rt_beacon_sync *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(void *SystemSpecific1,
1001
void *FunctionContext,
1002
void *SystemSpecific2, void *SystemSpecific3)
1004
struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
1005
LARGE_INTEGER tsfTime_a; /*, tsfTime_b, deltaTime_exp, deltaTime_ab; */
1006
u32 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(struct rt_rtmp_adapter *pAd)
1043
struct rt_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(struct rt_rtmp_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(struct rt_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
struct rt_mlme_disassoc_req DisReq;
1089
struct rt_mlme_queue_elem *pMsgElem =
1090
(struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_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(struct rt_mlme_disassoc_req);
1102
NdisMoveMemory(pMsgElem->Msg, &DisReq,
1104
(struct rt_mlme_disassoc_req));
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 // */