Staging: rt28x0: run common/*.c files through Lindent
[sfrench/cifs-2.6.git] / drivers / staging / rt2860 / common / cmm_mac_usb.c
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 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 */
51 NDIS_STATUS NICInitRecv(IN PRTMP_ADAPTER pAd)
52 {
53         UCHAR i;
54         NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
55         POS_COOKIE pObj = (POS_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                 PRX_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                 PRX_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 */
135 NDIS_STATUS NICInitTransmit(IN PRTMP_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         UCHAR i, acidx;
163         NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
164         PTX_CONTEXT pNullContext = &(pAd->NullContext);
165         PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
166         PTX_CONTEXT pRTSContext = &(pAd->RTSContext);
167         PTX_CONTEXT pMLMEContext = NULL;
168 //      PHT_TX_CONTEXT  pHTTXContext = NULL;
169         POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
170         PVOID RingBaseVa;
171 //      RTMP_TX_RING    *pTxRing;
172         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                         PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
203
204                         NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
205                         //Allocate URB
206                         LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER,
207                                      sizeof(HTTX_BUFFER), Status,
208                                      ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n",
209                                       acidx), done,
210                                      ("<-- ERROR in Alloc TX TxContext[%d] 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(TX_CONTEXT);
236                 os_alloc_mem(pAd, (PUCHAR *) (&pAd->MgmtDescRing.AllocVa),
237                              pAd->MgmtDescRing.AllocSize);
238                 if (pAd->MgmtDescRing.AllocVa == NULL) {
239                         DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
240                         Status = NDIS_STATUS_RESOURCES;
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(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                             (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
259                         pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
260                         if (pMLMEContext->pUrb == NULL) {
261                                 DBGPRINT(RT_DEBUG_ERROR,
262                                          ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n",
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 = (PUCHAR) RingBaseVa + sizeof(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                         PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
293
294                         NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
295
296                         //Allocate URB
297                         LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER,
298                                      sizeof(TX_BUFFER), Status,
299                                      ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n",
300                                       i), out2,
301                                      ("<-- ERROR in Alloc TX BeaconContext[%d] 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(TX_CONTEXT));
314
315                 //Allocate URB
316                 LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER),
317                              Status,
318                              ("<-- ERROR in Alloc TX NullContext urb!! \n"),
319                              out3,
320                              ("<-- ERROR in Alloc TX NullContext 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(TX_CONTEXT));
332
333                 //Allocate URB
334                 LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER),
335                              Status,
336                              ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
337                              out4,
338                              ("<-- ERROR in Alloc TX RTSContext 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(TX_CONTEXT));
350                 //Allocate URB
351                 LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER,
352                              sizeof(TX_BUFFER), Status,
353                              ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
354                              out5,
355                              ("<-- ERROR in Alloc TX PsPollContext 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(TX_BUFFER));
375
376 out5:
377         LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
378
379 out4:
380         LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
381
382 out3:
383         for (i = 0; i < BEACON_RING_SIZE; i++) {
384                 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
385                 if (pBeaconContext)
386                         LM_URB_FREE(pObj, pBeaconContext, sizeof(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                             (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
395                         if (pMLMEContext)
396                                 LM_URB_FREE(pObj, pMLMEContext,
397                                             sizeof(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                 PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
406                 if (pTxContext)
407                         LM_URB_FREE(pObj, pTxContext, sizeof(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 */
431 NDIS_STATUS RTMPAllocTxRxRingMemory(IN PRTMP_ADAPTER pAd)
432 {
433 //      COUNTER_802_11  pCounter = &pAd->WlanCounters;
434         NDIS_STATUS Status;
435         INT num;
436
437         DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
438
439         do {
440                 // Init the 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(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 */
522 VOID RTMPFreeTxRxRingMemory(IN PRTMP_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         UINT i, acidx;
536         PTX_CONTEXT pNullContext = &pAd->NullContext;
537         PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
538         PTX_CONTEXT pRTSContext = &pAd->RTSContext;
539 //      PHT_TX_CONTEXT          pHTTXContext;
540         //PRTMP_REORDERBUF      pReorderBuf;
541         POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
542 //      RTMP_TX_RING            *pTxRing;
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                 PRX_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(TX_BUFFER));
556
557         // Free NULL frame resource
558         LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
559
560         // Free RTS frame resource
561         LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
562
563         // Free beacon frame resource
564         for (i = 0; i < BEACON_RING_SIZE; i++) {
565                 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
566                 if (pBeaconContext)
567                         LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
568         }
569
570         // Free mgmt frame resource
571         for (i = 0; i < MGMT_RING_SIZE; i++) {
572                 PTX_CONTEXT pMLMEContext =
573                     (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
574                 //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
575                 if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) {
576                         RTMPFreeNdisPacket(pAd,
577                                            pAd->MgmtRing.Cell[i].pNdisPacket);
578                         pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
579                         pMLMEContext->TransferBuffer = NULL;
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                 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
596                 if (pHTTXContext)
597                         LM_URB_FREE(pObj, pHTTXContext, sizeof(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 */
639 NDIS_STATUS RTUSBWriteHWMACAddress(IN PRTMP_ADAPTER pAd)
640 {
641         MAC_DW0_STRUC StaMacReg0;
642         MAC_DW1_STRUC StaMacReg1;
643         NDIS_STATUS 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 = %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]));
670
671         RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word);
672         RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word);
673         return Status;
674 }
675
676 /*
677 ========================================================================
678 Routine Description:
679     Disable DMA.
680
681 Arguments:
682         *pAd                            the raxx interface data pointer
683
684 Return Value:
685         None
686
687 Note:
688 ========================================================================
689 */
690 VOID RT28XXDMADisable(IN RTMP_ADAPTER * pAd)
691 {
692         // no use
693 }
694
695 /*
696 ========================================================================
697 Routine Description:
698     Enable DMA.
699
700 Arguments:
701         *pAd                            the raxx interface data pointer
702
703 Return Value:
704         None
705
706 Note:
707 ========================================================================
708 */
709 VOID RT28XXDMAEnable(IN RTMP_ADAPTER * pAd)
710 {
711         WPDMA_GLO_CFG_STRUC GloCfg;
712         USB_DMA_CFG_STRUC UsbCfg;
713         int i = 0;
714
715         RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
716         do {
717                 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
718                 if ((GloCfg.field.TxDMABusy == 0)
719                     && (GloCfg.field.RxDMABusy == 0))
720                         break;
721
722                 DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
723                 RTMPusecDelay(1000);
724                 i++;
725         } while (i < 200);
726
727         RTMPusecDelay(50);
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);
734
735         UsbCfg.word = 0;
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;
745
746         RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
747
748 }
749
750 /********************************************************************
751   *
752   *     2870 Beacon Update Related functions.
753   *
754   ********************************************************************/
755
756 /*
757 ========================================================================
758 Routine Description:
759     Write Beacon buffer to Asic.
760
761 Arguments:
762         *pAd                            the raxx interface data pointer
763
764 Return Value:
765         None
766
767 Note:
768 ========================================================================
769 */
770 VOID RT28xx_UpdateBeaconToAsic(IN RTMP_ADAPTER * pAd,
771                                IN INT apidx,
772                                IN ULONG FrameLen, IN ULONG UpdatePos)
773 {
774         PUCHAR pBeaconFrame = NULL;
775         UCHAR *ptr;
776         UINT i, padding;
777         BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
778         UINT32 longValue;
779 //      USHORT                  shortValue;
780         BOOLEAN bBcnReq = FALSE;
781         UCHAR bcn_idx = 0;
782
783         if (pBeaconFrame == NULL) {
784                 DBGPRINT(RT_DEBUG_ERROR, ("pBeaconFrame is NULL!\n"));
785                 return;
786         }
787
788         if (pBeaconSync == NULL) {
789                 DBGPRINT(RT_DEBUG_ERROR, ("pBeaconSync is NULL!\n"));
790                 return;
791         }
792         //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
793         //      ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
794         //      )
795         if (bBcnReq == FALSE) {
796                 /* when the ra interface is down, do not send its beacon frame */
797                 /* clear all zero */
798                 for (i = 0; i < TXWI_SIZE; i += 4) {
799                         RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
800                                         0x00);
801                 }
802                 pBeaconSync->BeaconBitMap &=
803                     (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
804                 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
805         } else {
806                 ptr = (PUCHAR) & pAd->BeaconTxWI;
807                 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) {  // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
808                         pBeaconSync->BeaconBitMap &=
809                             (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
810                         NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx],
811                                        &pAd->BeaconTxWI, TXWI_SIZE);
812                 }
813
814                 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) !=
815                     (1 << bcn_idx)) {
816                         for (i = 0; i < TXWI_SIZE; i += 4)      // 16-byte TXWI field
817                         {
818                                 longValue =
819                                     *ptr + (*(ptr + 1) << 8) +
820                                     (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
821                                 RTMP_IO_WRITE32(pAd,
822                                                 pAd->BeaconOffset[bcn_idx] + i,
823                                                 longValue);
824                                 ptr += 4;
825                         }
826                 }
827
828                 ptr = pBeaconSync->BeaconBuf[bcn_idx];
829                 padding = (FrameLen & 0x01);
830                 NdisZeroMemory((PUCHAR) (pBeaconFrame + FrameLen), padding);
831                 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);
837                                 RTUSBMultiWrite(pAd,
838                                                 pAd->BeaconOffset[bcn_idx] +
839                                                 TXWI_SIZE + i, ptr, 2);
840                         }
841                         ptr += 2;
842                         pBeaconFrame += 2;
843                 }
844
845                 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
846
847                 // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
848         }
849
850 }
851
852 VOID RTUSBBssBeaconStop(IN RTMP_ADAPTER * pAd)
853 {
854         BEACON_SYNC_STRUCT *pBeaconSync;
855         int i, offset;
856         BOOLEAN Cancelled = TRUE;
857
858         pBeaconSync = pAd->CommonCfg.pBeaconSync;
859         if (pBeaconSync && pBeaconSync->EnableBeacon) {
860                 INT NumOfBcn;
861
862                 {
863                         NumOfBcn = MAX_MESH_NUM;
864                 }
865
866                 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
867
868                 for (i = 0; i < NumOfBcn; i++) {
869                         NdisZeroMemory(pBeaconSync->BeaconBuf[i],
870                                        HW_BEACON_OFFSET);
871                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
872
873                         for (offset = 0; offset < HW_BEACON_OFFSET; offset += 4)
874                                 RTMP_IO_WRITE32(pAd,
875                                                 pAd->BeaconOffset[i] + offset,
876                                                 0x00);
877
878                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
879                         pBeaconSync->TimIELocationInBeacon[i] = 0;
880                 }
881                 pBeaconSync->BeaconBitMap = 0;
882                 pBeaconSync->DtimBitOn = 0;
883         }
884 }
885
886 VOID RTUSBBssBeaconStart(IN RTMP_ADAPTER * pAd)
887 {
888         int apidx;
889         BEACON_SYNC_STRUCT *pBeaconSync;
890 //      LARGE_INTEGER   tsfTime, deltaTime;
891
892         pBeaconSync = pAd->CommonCfg.pBeaconSync;
893         if (pBeaconSync && pBeaconSync->EnableBeacon) {
894                 INT NumOfBcn;
895
896                 {
897                         NumOfBcn = MAX_MESH_NUM;
898                 }
899
900                 for (apidx = 0; apidx < NumOfBcn; apidx++) {
901                         UCHAR CapabilityInfoLocationInBeacon = 0;
902                         UCHAR TimIELocationInBeacon = 0;
903
904                         NdisZeroMemory(pBeaconSync->BeaconBuf[apidx],
905                                        HW_BEACON_OFFSET);
906                         pBeaconSync->CapabilityInfoLocationInBeacon[apidx] =
907                             CapabilityInfoLocationInBeacon;
908                         pBeaconSync->TimIELocationInBeacon[apidx] =
909                             TimIELocationInBeacon;
910                         NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx],
911                                        TXWI_SIZE);
912                 }
913                 pBeaconSync->BeaconBitMap = 0;
914                 pBeaconSync->DtimBitOn = 0;
915                 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
916
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 */ );
928
929         }
930 }
931
932 VOID RTUSBBssBeaconInit(IN RTMP_ADAPTER * pAd)
933 {
934         BEACON_SYNC_STRUCT *pBeaconSync;
935         int i;
936
937         os_alloc_mem(pAd, (PUCHAR *) (&pAd->CommonCfg.pBeaconSync),
938                      sizeof(BEACON_SYNC_STRUCT));
939         //NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
940         if (pAd->CommonCfg.pBeaconSync) {
941                 pBeaconSync = pAd->CommonCfg.pBeaconSync;
942                 NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
943                 for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
944                         NdisZeroMemory(pBeaconSync->BeaconBuf[i],
945                                        HW_BEACON_OFFSET);
946                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
947                         pBeaconSync->TimIELocationInBeacon[i] = 0;
948                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
949                 }
950                 pBeaconSync->BeaconBitMap = 0;
951
952                 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
953                 pBeaconSync->EnableBeacon = TRUE;
954         }
955 }
956
957 VOID RTUSBBssBeaconExit(IN RTMP_ADAPTER * pAd)
958 {
959         BEACON_SYNC_STRUCT *pBeaconSync;
960         BOOLEAN Cancelled = TRUE;
961         int i;
962
963         if (pAd->CommonCfg.pBeaconSync) {
964                 pBeaconSync = pAd->CommonCfg.pBeaconSync;
965                 pBeaconSync->EnableBeacon = FALSE;
966                 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
967                 pBeaconSync->BeaconBitMap = 0;
968
969                 for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
970                         NdisZeroMemory(pBeaconSync->BeaconBuf[i],
971                                        HW_BEACON_OFFSET);
972                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
973                         pBeaconSync->TimIELocationInBeacon[i] = 0;
974                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
975                 }
976
977                 os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
978                 pAd->CommonCfg.pBeaconSync = NULL;
979         }
980 }
981
982 /*
983     ========================================================================
984     Routine Description:
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.
988
989     Arguments:
990         SystemSpecific1         - Not used.
991         FunctionContext         - Pointer to our Adapter context.
992         SystemSpecific2         - Not used.
993         SystemSpecific3         - Not used.
994
995     Return Value:
996         None
997
998     ========================================================================
999 */
1000 VOID BeaconUpdateExec(IN PVOID SystemSpecific1,
1001                       IN PVOID FunctionContext,
1002                       IN PVOID SystemSpecific2, IN PVOID SystemSpecific3)
1003 {
1004         PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) FunctionContext;
1005         LARGE_INTEGER tsfTime_a;        //, tsfTime_b, deltaTime_exp, deltaTime_ab;
1006         UINT32 delta, delta2MS, period2US, remain, remain_low, remain_high;
1007 //      BOOLEAN                 positive;
1008
1009         if (pAd->CommonCfg.IsUpdateBeacon == TRUE) {
1010                 ReSyncBeaconTime(pAd);
1011
1012         }
1013
1014         RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1015         RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1016
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);
1021         remain =
1022             (remain_high + remain_low) % (pAd->CommonCfg.BeaconPeriod << 10);
1023         delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1024
1025         delta2MS = (delta >> 10);
1026         if (delta2MS > 150) {
1027                 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100;
1028                 pAd->CommonCfg.IsUpdateBeacon = FALSE;
1029         } else {
1030                 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10;
1031                 pAd->CommonCfg.IsUpdateBeacon = TRUE;
1032         }
1033
1034 }
1035
1036 /********************************************************************
1037   *
1038   *     2870 Radio on/off Related functions.
1039   *
1040   ********************************************************************/
1041 VOID RT28xxUsbMlmeRadioOn(IN PRTMP_ADAPTER pAd)
1042 {
1043         RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
1044
1045         DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOn()\n"));
1046
1047         if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1048                 return;
1049
1050         {
1051                 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
1052                 RTMPusecDelay(10000);
1053         }
1054         //NICResetFromError(pAd);
1055
1056         // Enable Tx/Rx
1057         RTMPEnableRxTx(pAd);
1058
1059         if (pChipOps->AsicReverseRfFromSleepMode)
1060                 pChipOps->AsicReverseRfFromSleepMode(pAd);
1061
1062         // Clear Radio off flag
1063         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1064
1065         RTUSBBulkReceive(pAd);
1066
1067         // Set LED
1068         RTMPSetLED(pAd, LED_RADIO_ON);
1069 }
1070
1071 VOID RT28xxUsbMlmeRadioOFF(IN PRTMP_ADAPTER pAd)
1072 {
1073         WPDMA_GLO_CFG_STRUC GloCfg;
1074         UINT32 Value, i;
1075
1076         DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOFF()\n"));
1077
1078         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1079                 return;
1080
1081         // Clear PMKID cache.
1082         pAd->StaCfg.SavedPMKNum = 0;
1083         RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(BSSID_INFO)));
1084
1085         // Link down first if any association exists
1086         if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
1087                 if (INFRA_ON(pAd) || ADHOC_ON(pAd)) {
1088                         MLME_DISASSOC_REQ_STRUCT DisReq;
1089                         MLME_QUEUE_ELEM *pMsgElem =
1090                             (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM),
1091                                                         MEM_ALLOC_FLAG);
1092
1093                         if (pMsgElem) {
1094                                 COPY_MAC_ADDR(&DisReq.Addr,
1095                                               pAd->CommonCfg.Bssid);
1096                                 DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
1097
1098                                 pMsgElem->Machine = ASSOC_STATE_MACHINE;
1099                                 pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
1100                                 pMsgElem->MsgLen =
1101                                     sizeof(MLME_DISASSOC_REQ_STRUCT);
1102                                 NdisMoveMemory(pMsgElem->Msg, &DisReq,
1103                                                sizeof
1104                                                (MLME_DISASSOC_REQ_STRUCT));
1105
1106                                 MlmeDisassocReqAction(pAd, pMsgElem);
1107                                 kfree(pMsgElem);
1108
1109                                 RTMPusecDelay(1000);
1110                         }
1111                 }
1112         }
1113         // Set Radio off flag
1114         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1115
1116         {
1117                 // Link down first if any association exists
1118                 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1119                         LinkDown(pAd, FALSE);
1120                 RTMPusecDelay(10000);
1121
1122                 //==========================================
1123                 // Clean up old bss table
1124                 BssTableInit(&pAd->ScanTab);
1125         }
1126
1127         // Set LED
1128         RTMPSetLED(pAd, LED_RADIO_OFF);
1129
1130         if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
1131                 // Must using 40MHz.
1132                 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
1133         } else {
1134                 // Must using 20MHz.
1135                 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
1136         }
1137
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
1143
1144         // Waiting for DMA idle
1145         i = 0;
1146         do {
1147                 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1148                 if ((GloCfg.field.TxDMABusy == 0)
1149                     && (GloCfg.field.RxDMABusy == 0))
1150                         break;
1151
1152                 RTMPusecDelay(1000);
1153         } while (i++ < 100);
1154
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);
1159
1160         {
1161                 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1162         }
1163 }
1164
1165 #endif // RTMP_MAC_USB //