1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
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. *
14 * *
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. *
19 * *
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. *
24 * *
25 *************************************************************************
26 */
27
28 #ifdef RTMP_MAC_USB
29
30 #include "../rt_config.h"
31
32 /*
33 ========================================================================
34 Routine Description:
35 Initialize receive data structures.
36
37 Arguments:
38 pAd Pointer to our adapter
39
40 Return Value:
41 NDIS_STATUS_SUCCESS
42 NDIS_STATUS_RESOURCES
43
44 Note:
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 ========================================================================
50 */
NICInitRecv(struct rt_rtmp_adapter * pAd)51 int NICInitRecv(struct rt_rtmp_adapter *pAd)
52 {
53 u8 i;
54 int Status = NDIS_STATUS_SUCCESS;
55 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
56
57 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
58 pObj = pObj;
59
60 /*InterlockedExchange(&pAd->PendingRx, 0); */
61 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;
65
66 for (i = 0; i < (RX_RING_SIZE); i++) {
67 struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
68
69 /*Allocate URB */
70 pRxContext->pUrb = RTUSB_ALLOC_URB(0);
71 if (pRxContext->pUrb == NULL) {
72 Status = NDIS_STATUS_RESOURCES;
73 goto out1;
74 }
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;
81 goto out1;
82 }
83
84 NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
85
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;
94 }
95
96 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status));
97 return Status;
98
99 out1:
100 for (i = 0; i < (RX_RING_SIZE); i++) {
101 struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
102
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;
108 }
109
110 if (NULL != pRxContext->pUrb) {
111 RTUSB_UNLINK_URB(pRxContext->pUrb);
112 RTUSB_FREE_URB(pRxContext->pUrb);
113 pRxContext->pUrb = NULL;
114 }
115 }
116
117 return Status;
118 }
119
120 /*
121 ========================================================================
122 Routine Description:
123 Initialize transmit data structures.
124
125 Arguments:
126 pAd Pointer to our adapter
127
128 Return Value:
129 NDIS_STATUS_SUCCESS
130 NDIS_STATUS_RESOURCES
131
132 Note:
133 ========================================================================
134 */
NICInitTransmit(struct rt_rtmp_adapter * pAd)135 int NICInitTransmit(struct rt_rtmp_adapter *pAd)
136 {
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; \
142 goto err1; } \
143 \
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; \
149 goto err2; }
150
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; }
161
162 u8 i, acidx;
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;
170 void *RingBaseVa;
171 /* struct rt_rtmp_tx_ring *pTxRing; */
172 struct rt_rtmp_mgmt_ring *pMgmtRing;
173
174 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
175 pObj = pObj;
176
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]);
181
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; */
186 }
187
188 /*pAd->NextMLMEIndex = 0; */
189 /*pAd->PushMgmtIndex = 0; */
190 /*pAd->PopMgmtIndex = 0; */
191 /*InterlockedExchange(&pAd->MgmtQueueSize, 0); */
192 /*InterlockedExchange(&pAd->TxCount, 0); */
193
194 /*pAd->PrioRingFirstIndex = 0; */
195 /*pAd->PrioRingTxCnt = 0; */
196
197 do {
198 /* */
199 /* TX_RING_SIZE, 4 ACs */
200 /* */
201 for (acidx = 0; acidx < 4; acidx++) {
202 struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
203
204 NdisZeroMemory(pHTTXContext, sizeof(struct rt_ht_tx_context));
205 /*Allocate URB */
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",
209 acidx), done,
210 ("<-- ERROR in Alloc TX TxContext[%d] struct rt_httx_buffer!\n",
211 acidx), out1);
212
213 NdisZeroMemory(pHTTXContext->TransferBuffer->
214 Aggregation, 4);
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;
227 }
228
229 /* */
230 /* MGMT_RING_SIZE */
231 /* */
232
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;
241 goto out1;
242 }
243 NdisZeroMemory(pAd->MgmtDescRing.AllocVa,
244 pAd->MgmtDescRing.AllocSize);
245 RingBaseVa = pAd->MgmtDescRing.AllocVa;
246
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;
255
256 /*Allocate URB for MLMEContext */
257 pMLMEContext =
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",
263 i));
264 Status = NDIS_STATUS_RESOURCES;
265 goto out2;
266 }
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;
275
276 /* Offset to next ring descriptor address */
277 RingBaseVa = (u8 *)RingBaseVa + sizeof(struct rt_tx_context);
278 }
279 DBGPRINT(RT_DEBUG_TRACE,
280 ("MGMT Ring: total %d entry allocated\n", i));
281
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;
286
287 /* */
288 /* BEACON_RING_SIZE */
289 /* */
290 for (i = 0; i < BEACON_RING_SIZE; i++) /* 2 */
291 {
292 struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
293
294 NdisZeroMemory(pBeaconContext, sizeof(struct rt_tx_context));
295
296 /*Allocate URB */
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",
300 i), out2,
301 ("<-- ERROR in Alloc TX BeaconContext[%d] struct rt_tx_buffer!\n",
302 i), out3);
303
304 pBeaconContext->pAd = pAd;
305 pBeaconContext->pIrp = NULL;
306 pBeaconContext->InUse = FALSE;
307 pBeaconContext->IRPPending = FALSE;
308 }
309
310 /* */
311 /* NullContext */
312 /* */
313 NdisZeroMemory(pNullContext, sizeof(struct rt_tx_context));
314
315 /*Allocate URB */
316 LM_USB_ALLOC(pObj, pNullContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
317 Status,
318 ("<-- ERROR in Alloc TX NullContext urb!\n"),
319 out3,
320 ("<-- ERROR in Alloc TX NullContext struct rt_tx_buffer!\n"),
321 out4);
322
323 pNullContext->pAd = pAd;
324 pNullContext->pIrp = NULL;
325 pNullContext->InUse = FALSE;
326 pNullContext->IRPPending = FALSE;
327
328 /* */
329 /* RTSContext */
330 /* */
331 NdisZeroMemory(pRTSContext, sizeof(struct rt_tx_context));
332
333 /*Allocate URB */
334 LM_USB_ALLOC(pObj, pRTSContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
335 Status,
336 ("<-- ERROR in Alloc TX RTSContext urb!\n"),
337 out4,
338 ("<-- ERROR in Alloc TX RTSContext struct rt_tx_buffer!\n"),
339 out5);
340
341 pRTSContext->pAd = pAd;
342 pRTSContext->pIrp = NULL;
343 pRTSContext->InUse = FALSE;
344 pRTSContext->IRPPending = FALSE;
345
346 /* */
347 /* PsPollContext */
348 /* */
349 /*NdisZeroMemory(pPsPollContext, sizeof(struct rt_tx_context)); */
350 /*Allocate URB */
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"),
354 out5,
355 ("<-- ERROR in Alloc TX PsPollContext struct rt_tx_buffer!\n"),
356 out6);
357
358 pPsPollContext->pAd = pAd;
359 pPsPollContext->pIrp = NULL;
360 pPsPollContext->InUse = FALSE;
361 pPsPollContext->IRPPending = FALSE;
362 pPsPollContext->bAggregatible = FALSE;
363 pPsPollContext->LastOne = TRUE;
364
365 } while (FALSE);
366
367 done:
368 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status));
369
370 return Status;
371
372 /* --------------------------- ERROR HANDLE --------------------------- */
373 out6:
374 LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer));
375
376 out5:
377 LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
378
379 out4:
380 LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
381
382 out3:
383 for (i = 0; i < BEACON_RING_SIZE; i++) {
384 struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
385 if (pBeaconContext)
386 LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
387 }
388
389 out2:
390 if (pAd->MgmtDescRing.AllocVa) {
391 pMgmtRing = &pAd->MgmtRing;
392 for (i = 0; i < MGMT_RING_SIZE; i++) {
393 pMLMEContext =
394 (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
395 if (pMLMEContext)
396 LM_URB_FREE(pObj, pMLMEContext,
397 sizeof(struct rt_tx_buffer));
398 }
399 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
400 pAd->MgmtDescRing.AllocVa = NULL;
401 }
402
403 out1:
404 for (acidx = 0; acidx < 4; acidx++) {
405 struct rt_ht_tx_context *pTxContext = &(pAd->TxContext[acidx]);
406 if (pTxContext)
407 LM_URB_FREE(pObj, pTxContext, sizeof(struct rt_httx_buffer));
408 }
409
410 /* Here we didn't have any pre-allocated memory need to free. */
411
412 return Status;
413 }
414
415 /*
416 ========================================================================
417 Routine Description:
418 Allocate DMA memory blocks for send, receive.
419
420 Arguments:
421 pAd Pointer to our adapter
422
423 Return Value:
424 NDIS_STATUS_SUCCESS
425 NDIS_STATUS_FAILURE
426 NDIS_STATUS_RESOURCES
427
428 Note:
429 ========================================================================
430 */
RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter * pAd)431 int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd)
432 {
433 /* struct rt_counter_802_11 pCounter = &pAd->WlanCounters; */
434 int Status;
435 int num;
436
437 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
438
439 do {
440 /* Init the struct rt_cmdq and CmdQLock */
441 NdisAllocateSpinLock(&pAd->CmdQLock);
442 NdisAcquireSpinLock(&pAd->CmdQLock);
443 RTUSBInitializeCmdQ(&pAd->CmdQ);
444 NdisReleaseSpinLock(&pAd->CmdQLock);
445
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);
455
456 for (num = 0; num < NUM_OF_TX_RING; num++) {
457 NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
458 }
459
460 /* NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX */
461
462 /* NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit() */
463 /* NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit() */
464
465 /* for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++) */
466 /* { */
467 /* NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock); */
468 /* } */
469
470 /* */
471 /* Init Mac Table */
472 /* */
473 /* MacTableInitialize(pAd); */
474
475 /* */
476 /* Init send data structures and related parameters */
477 /* */
478 Status = NICInitTransmit(pAd);
479 if (Status != NDIS_STATUS_SUCCESS)
480 break;
481
482 /* */
483 /* Init receive data structures and related parameters */
484 /* */
485 Status = NICInitRecv(pAd);
486 if (Status != NDIS_STATUS_SUCCESS)
487 break;
488
489 pAd->PendingIoCount = 1;
490
491 } while (FALSE);
492
493 NdisZeroMemory(&pAd->FragFrame, sizeof(struct rt_fragment_frame));
494 pAd->FragFrame.pFragPacket =
495 RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
496
497 if (pAd->FragFrame.pFragPacket == NULL) {
498 Status = NDIS_STATUS_RESOURCES;
499 }
500
501 DBGPRINT_S(Status,
502 ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
503 return Status;
504 }
505
506 /*
507 ========================================================================
508 Routine Description:
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
512
513 Arguments:
514 *pAd the raxx interface data pointer
515
516 Return Value:
517 None
518
519 Note:
520 ========================================================================
521 */
RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter * pAd)522 void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd)
523 {
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; }
534
535 u32 i, acidx;
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; */
543
544 DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
545 pObj = pObj;
546
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]);
550 if (pRxContext)
551 LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
552 }
553
554 /* Free PsPoll frame resource */
555 LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer));
556
557 /* Free NULL frame resource */
558 LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
559
560 /* Free RTS frame resource */
561 LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
562
563 /* Free beacon frame resource */
564 for (i = 0; i < BEACON_RING_SIZE; i++) {
565 struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
566 if (pBeaconContext)
567 LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
568 }
569
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;
580 }
581
582 if (pMLMEContext) {
583 if (NULL != pMLMEContext->pUrb) {
584 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
585 RTUSB_FREE_URB(pMLMEContext->pUrb);
586 pMLMEContext->pUrb = NULL;
587 }
588 }
589 }
590 if (pAd->MgmtDescRing.AllocVa)
591 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
592
593 /* Free Tx frame resource */
594 for (acidx = 0; acidx < 4; acidx++) {
595 struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
596 if (pHTTXContext)
597 LM_URB_FREE(pObj, pHTTXContext, sizeof(struct rt_httx_buffer));
598 }
599
600 if (pAd->FragFrame.pFragPacket)
601 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket,
602 NDIS_STATUS_SUCCESS);
603
604 for (i = 0; i < 6; i++) {
605 NdisFreeSpinLock(&pAd->BulkOutLock[i]);
606 }
607
608 NdisFreeSpinLock(&pAd->BulkInLock);
609 NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
610
611 NdisFreeSpinLock(&pAd->CmdQLock);
612 /* Clear all pending bulk-out request flags. */
613 RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
614
615 /* NdisFreeSpinLock(&pAd->MacTabLock); */
616
617 /* for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++) */
618 /* { */
619 /* NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock); */
620 /* } */
621
622 DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n"));
623 }
624
625 /*
626 ========================================================================
627 Routine Description:
628 Write WLAN MAC address to USB 2870.
629
630 Arguments:
631 pAd Pointer to our adapter
632
633 Return Value:
634 NDIS_STATUS_SUCCESS
635
636 Note:
637 ========================================================================
638 */
RTUSBWriteHWMACAddress(struct rt_rtmp_adapter * pAd)639 int RTUSBWriteHWMACAddress(struct rt_rtmp_adapter *pAd)
640 {
641 MAC_DW0_STRUC StaMacReg0;
642 MAC_DW1_STRUC StaMacReg1;
643 int Status = NDIS_STATUS_SUCCESS;
644 LARGE_INTEGER NOW;
645
646 /* initialize the random number generator */
647 RTMP_GetCurrentSystemTime(&NOW);
648
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];
656 }
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 = %pM\n", pAd->CurrentAddress));
667
668 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word);
669 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word);
670 return Status;
671 }
672
673 /*
674 ========================================================================
675 Routine Description:
676 Disable DMA.
677
678 Arguments:
679 *pAd the raxx interface data pointer
680
681 Return Value:
682 None
683
684 Note:
685 ========================================================================
686 */
RT28XXDMADisable(struct rt_rtmp_adapter * pAd)687 void RT28XXDMADisable(struct rt_rtmp_adapter *pAd)
688 {
689 /* no use */
690 }
691
692 /*
693 ========================================================================
694 Routine Description:
695 Enable DMA.
696
697 Arguments:
698 *pAd the raxx interface data pointer
699
700 Return Value:
701 None
702
703 Note:
704 ========================================================================
705 */
RT28XXDMAEnable(struct rt_rtmp_adapter * pAd)706 void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd)
707 {
708 WPDMA_GLO_CFG_STRUC GloCfg;
709 USB_DMA_CFG_STRUC UsbCfg;
710 int i = 0;
711
712 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
713 do {
714 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
715 if ((GloCfg.field.TxDMABusy == 0)
716 && (GloCfg.field.RxDMABusy == 0))
717 break;
718
719 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
720 RTMPusecDelay(1000);
721 i++;
722 } while (i < 200);
723
724 RTMPusecDelay(50);
725 GloCfg.field.EnTXWriteBackDDONE = 1;
726 GloCfg.field.EnableRxDMA = 1;
727 GloCfg.field.EnableTxDMA = 1;
728 DBGPRINT(RT_DEBUG_TRACE,
729 ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
730 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
731
732 UsbCfg.word = 0;
733 UsbCfg.field.phyclear = 0;
734 /* usb version is 1.1,do not use bulk in aggregation */
735 if (pAd->BulkInMaxPacketSize == 512)
736 UsbCfg.field.RxBulkAggEn = 1;
737 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
738 UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE / 1024) - 3;
739 UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
740 UsbCfg.field.RxBulkEn = 1;
741 UsbCfg.field.TxBulkEn = 1;
742
743 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
744
745 }
746
747 /********************************************************************
748 *
749 * 2870 Beacon Update Related functions.
750 *
751 ********************************************************************/
752
753 /*
754 ========================================================================
755 Routine Description:
756 Write Beacon buffer to Asic.
757
758 Arguments:
759 *pAd the raxx interface data pointer
760
761 Return Value:
762 None
763
764 Note:
765 ========================================================================
766 */
RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter * pAd,int apidx,unsigned long FrameLen,unsigned long UpdatePos)767 void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd,
768 int apidx,
769 unsigned long FrameLen, unsigned long UpdatePos)
770 {
771 u8 *pBeaconFrame = NULL;
772 u8 *ptr;
773 u32 i, padding;
774 struct rt_beacon_sync *pBeaconSync = pAd->CommonCfg.pBeaconSync;
775 u32 longValue;
776 /* u16 shortValue; */
777 BOOLEAN bBcnReq = FALSE;
778 u8 bcn_idx = 0;
779
780 if (pBeaconFrame == NULL) {
781 DBGPRINT(RT_DEBUG_ERROR, ("pBeaconFrame is NULL!\n"));
782 return;
783 }
784
785 if (pBeaconSync == NULL) {
786 DBGPRINT(RT_DEBUG_ERROR, ("pBeaconSync is NULL!\n"));
787 return;
788 }
789 /*if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) || */
790 /* ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) */
791 /* ) */
792 if (bBcnReq == FALSE) {
793 /* when the ra interface is down, do not send its beacon frame */
794 /* clear all zero */
795 for (i = 0; i < TXWI_SIZE; i += 4) {
796 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
797 0x00);
798 }
799 pBeaconSync->BeaconBitMap &=
800 (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
801 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
802 } else {
803 ptr = (u8 *)& pAd->BeaconTxWI;
804 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) { /* If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames. */
805 pBeaconSync->BeaconBitMap &=
806 (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
807 NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx],
808 &pAd->BeaconTxWI, TXWI_SIZE);
809 }
810
811 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) !=
812 (1 << bcn_idx)) {
813 for (i = 0; i < TXWI_SIZE; i += 4) /* 16-byte TXWI field */
814 {
815 longValue =
816 *ptr + (*(ptr + 1) << 8) +
817 (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
818 RTMP_IO_WRITE32(pAd,
819 pAd->BeaconOffset[bcn_idx] + i,
820 longValue);
821 ptr += 4;
822 }
823 }
824
825 ptr = pBeaconSync->BeaconBuf[bcn_idx];
826 padding = (FrameLen & 0x01);
827 NdisZeroMemory((u8 *)(pBeaconFrame + FrameLen), padding);
828 FrameLen += padding;
829 for (i = 0; i < FrameLen /*HW_BEACON_OFFSET */ ; i += 2) {
830 if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE) {
831 NdisMoveMemory(ptr, pBeaconFrame, 2);
832 /*shortValue = *ptr + (*(ptr+1)<<8); */
833 /*RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue); */
834 RTUSBMultiWrite(pAd,
835 pAd->BeaconOffset[bcn_idx] +
836 TXWI_SIZE + i, ptr, 2);
837 }
838 ptr += 2;
839 pBeaconFrame += 2;
840 }
841
842 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
843
844 /* For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame. */
845 }
846
847 }
848
RTUSBBssBeaconStop(struct rt_rtmp_adapter * pAd)849 void RTUSBBssBeaconStop(struct rt_rtmp_adapter *pAd)
850 {
851 struct rt_beacon_sync *pBeaconSync;
852 int i, offset;
853 BOOLEAN Cancelled = TRUE;
854
855 pBeaconSync = pAd->CommonCfg.pBeaconSync;
856 if (pBeaconSync && pBeaconSync->EnableBeacon) {
857 int NumOfBcn;
858
859 {
860 NumOfBcn = MAX_MESH_NUM;
861 }
862
863 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
864
865 for (i = 0; i < NumOfBcn; i++) {
866 NdisZeroMemory(pBeaconSync->BeaconBuf[i],
867 HW_BEACON_OFFSET);
868 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
869
870 for (offset = 0; offset < HW_BEACON_OFFSET; offset += 4)
871 RTMP_IO_WRITE32(pAd,
872 pAd->BeaconOffset[i] + offset,
873 0x00);
874
875 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
876 pBeaconSync->TimIELocationInBeacon[i] = 0;
877 }
878 pBeaconSync->BeaconBitMap = 0;
879 pBeaconSync->DtimBitOn = 0;
880 }
881 }
882
RTUSBBssBeaconStart(struct rt_rtmp_adapter * pAd)883 void RTUSBBssBeaconStart(struct rt_rtmp_adapter *pAd)
884 {
885 int apidx;
886 struct rt_beacon_sync *pBeaconSync;
887 /* LARGE_INTEGER tsfTime, deltaTime; */
888
889 pBeaconSync = pAd->CommonCfg.pBeaconSync;
890 if (pBeaconSync && pBeaconSync->EnableBeacon) {
891 int NumOfBcn;
892
893 {
894 NumOfBcn = MAX_MESH_NUM;
895 }
896
897 for (apidx = 0; apidx < NumOfBcn; apidx++) {
898 u8 CapabilityInfoLocationInBeacon = 0;
899 u8 TimIELocationInBeacon = 0;
900
901 NdisZeroMemory(pBeaconSync->BeaconBuf[apidx],
902 HW_BEACON_OFFSET);
903 pBeaconSync->CapabilityInfoLocationInBeacon[apidx] =
904 CapabilityInfoLocationInBeacon;
905 pBeaconSync->TimIELocationInBeacon[apidx] =
906 TimIELocationInBeacon;
907 NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx],
908 TXWI_SIZE);
909 }
910 pBeaconSync->BeaconBitMap = 0;
911 pBeaconSync->DtimBitOn = 0;
912 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
913
914 pAd->CommonCfg.BeaconAdjust = 0;
915 pAd->CommonCfg.BeaconFactor =
916 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
917 pAd->CommonCfg.BeaconRemain =
918 (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
919 DBGPRINT(RT_DEBUG_TRACE,
920 ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n",
921 pAd->CommonCfg.BeaconFactor,
922 pAd->CommonCfg.BeaconRemain));
923 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer,
924 10 /*pAd->CommonCfg.BeaconPeriod */ );
925
926 }
927 }
928
RTUSBBssBeaconInit(struct rt_rtmp_adapter * pAd)929 void RTUSBBssBeaconInit(struct rt_rtmp_adapter *pAd)
930 {
931 struct rt_beacon_sync *pBeaconSync;
932 int i;
933
934 os_alloc_mem(pAd, (u8 **) (&pAd->CommonCfg.pBeaconSync),
935 sizeof(struct rt_beacon_sync));
936 /*NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(struct rt_beacon_sync), MEM_ALLOC_FLAG); */
937 if (pAd->CommonCfg.pBeaconSync) {
938 pBeaconSync = pAd->CommonCfg.pBeaconSync;
939 NdisZeroMemory(pBeaconSync, sizeof(struct rt_beacon_sync));
940 for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
941 NdisZeroMemory(pBeaconSync->BeaconBuf[i],
942 HW_BEACON_OFFSET);
943 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
944 pBeaconSync->TimIELocationInBeacon[i] = 0;
945 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
946 }
947 pBeaconSync->BeaconBitMap = 0;
948
949 /*RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE); */
950 pBeaconSync->EnableBeacon = TRUE;
951 }
952 }
953
RTUSBBssBeaconExit(struct rt_rtmp_adapter * pAd)954 void RTUSBBssBeaconExit(struct rt_rtmp_adapter *pAd)
955 {
956 struct rt_beacon_sync *pBeaconSync;
957 BOOLEAN Cancelled = TRUE;
958 int i;
959
960 if (pAd->CommonCfg.pBeaconSync) {
961 pBeaconSync = pAd->CommonCfg.pBeaconSync;
962 pBeaconSync->EnableBeacon = FALSE;
963 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
964 pBeaconSync->BeaconBitMap = 0;
965
966 for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
967 NdisZeroMemory(pBeaconSync->BeaconBuf[i],
968 HW_BEACON_OFFSET);
969 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
970 pBeaconSync->TimIELocationInBeacon[i] = 0;
971 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
972 }
973
974 os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
975 pAd->CommonCfg.pBeaconSync = NULL;
976 }
977 }
978
979 /*
980 ========================================================================
981 Routine Description:
982 For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism
983 to update the beacon context in each Beacon interval. Here we use a periodical timer
984 to simulate the TBTT interrupt to handle the beacon context update.
985
986 Arguments:
987 SystemSpecific1 - Not used.
988 FunctionContext - Pointer to our Adapter context.
989 SystemSpecific2 - Not used.
990 SystemSpecific3 - Not used.
991
992 Return Value:
993 None
994
995 ========================================================================
996 */
BeaconUpdateExec(void * SystemSpecific1,void * FunctionContext,void * SystemSpecific2,void * SystemSpecific3)997 void BeaconUpdateExec(void *SystemSpecific1,
998 void *FunctionContext,
999 void *SystemSpecific2, void *SystemSpecific3)
1000 {
1001 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
1002 LARGE_INTEGER tsfTime_a; /*, tsfTime_b, deltaTime_exp, deltaTime_ab; */
1003 u32 delta, delta2MS, period2US, remain, remain_low, remain_high;
1004 /* BOOLEAN positive; */
1005
1006 if (pAd->CommonCfg.IsUpdateBeacon == TRUE) {
1007 ReSyncBeaconTime(pAd);
1008
1009 }
1010
1011 RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1012 RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1013
1014 /*positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp); */
1015 period2US = (pAd->CommonCfg.BeaconPeriod << 10);
1016 remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1017 remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1018 remain =
1019 (remain_high + remain_low) % (pAd->CommonCfg.BeaconPeriod << 10);
1020 delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1021
1022 delta2MS = (delta >> 10);
1023 if (delta2MS > 150) {
1024 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100;
1025 pAd->CommonCfg.IsUpdateBeacon = FALSE;
1026 } else {
1027 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10;
1028 pAd->CommonCfg.IsUpdateBeacon = TRUE;
1029 }
1030
1031 }
1032
1033 /********************************************************************
1034 *
1035 * 2870 Radio on/off Related functions.
1036 *
1037 ********************************************************************/
RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter * pAd)1038 void RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter *pAd)
1039 {
1040 struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
1041
1042 DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOn()\n"));
1043
1044 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1045 return;
1046
1047 {
1048 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
1049 RTMPusecDelay(10000);
1050 }
1051 /*NICResetFromError(pAd); */
1052
1053 /* Enable Tx/Rx */
1054 RTMPEnableRxTx(pAd);
1055
1056 if (pChipOps->AsicReverseRfFromSleepMode)
1057 pChipOps->AsicReverseRfFromSleepMode(pAd);
1058
1059 /* Clear Radio off flag */
1060 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1061
1062 RTUSBBulkReceive(pAd);
1063
1064 /* Set LED */
1065 RTMPSetLED(pAd, LED_RADIO_ON);
1066 }
1067
RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter * pAd)1068 void RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter *pAd)
1069 {
1070 WPDMA_GLO_CFG_STRUC GloCfg;
1071 u32 Value, i;
1072
1073 DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOFF()\n"));
1074
1075 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1076 return;
1077
1078 /* Clear PMKID cache. */
1079 pAd->StaCfg.SavedPMKNum = 0;
1080 RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(struct rt_bssid_info)));
1081
1082 /* Link down first if any association exists */
1083 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
1084 if (INFRA_ON(pAd) || ADHOC_ON(pAd)) {
1085 struct rt_mlme_disassoc_req DisReq;
1086 struct rt_mlme_queue_elem *pMsgElem =
1087 kmalloc(sizeof(struct rt_mlme_queue_elem),
1088 MEM_ALLOC_FLAG);
1089
1090 if (pMsgElem) {
1091 COPY_MAC_ADDR(&DisReq.Addr,
1092 pAd->CommonCfg.Bssid);
1093 DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
1094
1095 pMsgElem->Machine = ASSOC_STATE_MACHINE;
1096 pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
1097 pMsgElem->MsgLen =
1098 sizeof(struct rt_mlme_disassoc_req);
1099 NdisMoveMemory(pMsgElem->Msg, &DisReq,
1100 sizeof
1101 (struct rt_mlme_disassoc_req));
1102
1103 MlmeDisassocReqAction(pAd, pMsgElem);
1104 kfree(pMsgElem);
1105
1106 RTMPusecDelay(1000);
1107 }
1108 }
1109 }
1110 /* Set Radio off flag */
1111 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1112
1113 {
1114 /* Link down first if any association exists */
1115 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1116 LinkDown(pAd, FALSE);
1117 RTMPusecDelay(10000);
1118
1119 /*========================================== */
1120 /* Clean up old bss table */
1121 BssTableInit(&pAd->ScanTab);
1122 }
1123
1124 /* Set LED */
1125 RTMPSetLED(pAd, LED_RADIO_OFF);
1126
1127 if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
1128 /* Must using 40MHz. */
1129 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
1130 } else {
1131 /* Must using 20MHz. */
1132 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
1133 }
1134
1135 /* Disable Tx/Rx DMA */
1136 RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); /* disable DMA */
1137 GloCfg.field.EnableTxDMA = 0;
1138 GloCfg.field.EnableRxDMA = 0;
1139 RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); /* abort all TX rings */
1140
1141 /* Waiting for DMA idle */
1142 i = 0;
1143 do {
1144 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1145 if ((GloCfg.field.TxDMABusy == 0)
1146 && (GloCfg.field.RxDMABusy == 0))
1147 break;
1148
1149 RTMPusecDelay(1000);
1150 } while (i++ < 100);
1151
1152 /* Disable MAC Tx/Rx */
1153 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1154 Value &= (0xfffffff3);
1155 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1156
1157 {
1158 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1159 }
1160 }
1161
1162 #endif /* RTMP_MAC_USB // */
1163