ad8c6017647214d43f433628466ab5523995012a
[firefly-linux-kernel-4.4.55.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
31 #include        "../rt_config.h"
32
33
34 /*
35 ========================================================================
36 Routine Description:
37     Initialize receive data structures.
38
39 Arguments:
40     pAd                                 Pointer to our adapter
41
42 Return Value:
43         NDIS_STATUS_SUCCESS
44         NDIS_STATUS_RESOURCES
45
46 Note:
47         Initialize all receive releated private buffer, include those define
48         in RTMP_ADAPTER structure and all private data structures. The mahor
49         work is to allocate buffer for each packet and chain buffer to
50         NDIS packet descriptor.
51 ========================================================================
52 */
53 NDIS_STATUS     NICInitRecv(
54         IN      PRTMP_ADAPTER   pAd)
55 {
56         UCHAR                           i;
57         NDIS_STATUS                     Status = NDIS_STATUS_SUCCESS;
58         POS_COOKIE                      pObj = (POS_COOKIE) pAd->OS_Cookie;
59
60
61         DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
62         pObj = pObj;
63
64         //InterlockedExchange(&pAd->PendingRx, 0);
65         pAd->PendingRx = 0;
66         pAd->NextRxBulkInReadIndex      = 0;    // Next Rx Read index
67         pAd->NextRxBulkInIndex          = 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
68         pAd->NextRxBulkInPosition       = 0;
69
70         for (i = 0; i < (RX_RING_SIZE); i++)
71         {
72                 PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
73
74                 //Allocate URB
75                 pRxContext->pUrb = RTUSB_ALLOC_URB(0);
76                 if (pRxContext->pUrb == NULL)
77                 {
78                         Status = NDIS_STATUS_RESOURCES;
79                         goto out1;
80                 }
81
82                 // Allocate transfer buffer
83                 pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
84                 if (pRxContext->TransferBuffer == NULL)
85                 {
86                         Status = NDIS_STATUS_RESOURCES;
87                         goto out1;
88                 }
89
90                 NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
91
92                 pRxContext->pAd = pAd;
93                 pRxContext->pIrp = NULL;
94                 pRxContext->InUse               = FALSE;
95                 pRxContext->IRPPending  = FALSE;
96                 pRxContext->Readable    = FALSE;
97                 //pRxContext->ReorderInUse = FALSE;
98                 pRxContext->bRxHandling = FALSE;
99                 pRxContext->BulkInOffset = 0;
100         }
101
102         DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status));
103         return Status;
104
105 out1:
106         for (i = 0; i < (RX_RING_SIZE); i++)
107         {
108                 PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
109
110                 if (NULL != pRxContext->TransferBuffer)
111                 {
112                         RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
113                                                                 pRxContext->TransferBuffer, pRxContext->data_dma);
114                         pRxContext->TransferBuffer = NULL;
115                 }
116
117                 if (NULL != pRxContext->pUrb)
118                 {
119                         RTUSB_UNLINK_URB(pRxContext->pUrb);
120                         RTUSB_FREE_URB(pRxContext->pUrb);
121                         pRxContext->pUrb = NULL;
122                 }
123         }
124
125         return Status;
126 }
127
128
129 /*
130 ========================================================================
131 Routine Description:
132     Initialize transmit data structures.
133
134 Arguments:
135     pAd                                 Pointer to our adapter
136
137 Return Value:
138         NDIS_STATUS_SUCCESS
139         NDIS_STATUS_RESOURCES
140
141 Note:
142 ========================================================================
143 */
144 NDIS_STATUS     NICInitTransmit(
145         IN      PRTMP_ADAPTER   pAd)
146 {
147 #define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2)        \
148         Context->pUrb = RTUSB_ALLOC_URB(0);             \
149         if (Context->pUrb == NULL) {                    \
150                 DBGPRINT(RT_DEBUG_ERROR, msg1);         \
151                 Status = NDIS_STATUS_RESOURCES;         \
152                 goto err1; }                                            \
153                                                                                         \
154         Context->TransferBuffer =                               \
155                 (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma);        \
156         if (Context->TransferBuffer == NULL) {  \
157                 DBGPRINT(RT_DEBUG_ERROR, msg2);         \
158                 Status = NDIS_STATUS_RESOURCES;         \
159                 goto err2; }
160
161 #define LM_URB_FREE(pObj, Context, BufferSize)                          \
162         if (NULL != Context->pUrb) {                                                    \
163                 RTUSB_UNLINK_URB(Context->pUrb);                                        \
164                 RTUSB_FREE_URB(Context->pUrb);                                          \
165                 Context->pUrb = NULL; }                                                         \
166         if (NULL != Context->TransferBuffer) {                          \
167                 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,       \
168                                                                 Context->TransferBuffer,        \
169                                                                 Context->data_dma);                     \
170                 Context->TransferBuffer = NULL; }
171
172         UCHAR                   i, acidx;
173         NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
174         PTX_CONTEXT             pNullContext   = &(pAd->NullContext);
175         PTX_CONTEXT             pPsPollContext = &(pAd->PsPollContext);
176         PTX_CONTEXT             pRTSContext    = &(pAd->RTSContext);
177         PTX_CONTEXT             pMLMEContext = NULL;
178 //      PHT_TX_CONTEXT  pHTTXContext = NULL;
179         POS_COOKIE              pObj = (POS_COOKIE) pAd->OS_Cookie;
180         PVOID                   RingBaseVa;
181 //      RTMP_TX_RING    *pTxRing;
182         RTMP_MGMT_RING  *pMgmtRing;
183
184         DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
185         pObj = pObj;
186
187         // Init 4 set of Tx parameters
188         for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
189         {
190                 // Initialize all Transmit releated queues
191                 InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
192
193                 // Next Local tx ring pointer waiting for buck out
194                 pAd->NextBulkOutIndex[acidx] = acidx;
195                 pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
196                 //pAd->DataBulkDoneIdx[acidx] = 0;
197         }
198
199         //pAd->NextMLMEIndex    = 0;
200         //pAd->PushMgmtIndex    = 0;
201         //pAd->PopMgmtIndex     = 0;
202         //InterlockedExchange(&pAd->MgmtQueueSize, 0);
203         //InterlockedExchange(&pAd->TxCount, 0);
204
205         //pAd->PrioRingFirstIndex       = 0;
206         //pAd->PrioRingTxCnt            = 0;
207
208         do
209         {
210                 //
211                 // TX_RING_SIZE, 4 ACs
212                 //
213                 for(acidx=0; acidx<4; acidx++)
214                 {
215                         PHT_TX_CONTEXT  pHTTXContext = &(pAd->TxContext[acidx]);
216
217                         NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
218                         //Allocate URB
219                         LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
220                                                         ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
221                                                         done,
222                                                         ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
223                                                         out1);
224
225                         NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
226                         pHTTXContext->pAd = pAd;
227                         pHTTXContext->pIrp = NULL;
228                         pHTTXContext->IRPPending = FALSE;
229                         pHTTXContext->NextBulkOutPosition = 0;
230                         pHTTXContext->ENextBulkOutPosition = 0;
231                         pHTTXContext->CurWritePosition = 0;
232                         pHTTXContext->CurWriteRealPos = 0;
233                         pHTTXContext->BulkOutSize = 0;
234                         pHTTXContext->BulkOutPipeId = acidx;
235                         pHTTXContext->bRingEmpty = TRUE;
236                         pHTTXContext->bCopySavePad = FALSE;
237                         pAd->BulkOutPending[acidx] = FALSE;
238                 }
239
240
241                 //
242                 // MGMT_RING_SIZE
243                 //
244
245                 // Allocate MGMT ring descriptor's memory
246                 pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
247                 os_alloc_mem(pAd, (PUCHAR *)(&pAd->MgmtDescRing.AllocVa), pAd->MgmtDescRing.AllocSize);
248                 if (pAd->MgmtDescRing.AllocVa == NULL)
249                 {
250                         DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
251                         Status = NDIS_STATUS_RESOURCES;
252                         goto out1;
253                 }
254                 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
255                 RingBaseVa     = pAd->MgmtDescRing.AllocVa;
256
257                 // Initialize MGMT Ring and associated buffer memory
258                 pMgmtRing = &pAd->MgmtRing;
259                 for (i = 0; i < MGMT_RING_SIZE; i++)
260                 {
261                         // link the pre-allocated Mgmt buffer to MgmtRing.Cell
262                         pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
263                         pMgmtRing->Cell[i].AllocVa = RingBaseVa;
264                         pMgmtRing->Cell[i].pNdisPacket = NULL;
265                         pMgmtRing->Cell[i].pNextNdisPacket = NULL;
266
267                         //Allocate URB for MLMEContext
268                         pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
269                         pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
270                         if (pMLMEContext->pUrb == NULL)
271                         {
272                                 DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
273                                 Status = NDIS_STATUS_RESOURCES;
274                                 goto out2;
275                         }
276                         pMLMEContext->pAd = pAd;
277                         pMLMEContext->pIrp = NULL;
278                         pMLMEContext->TransferBuffer = NULL;
279                         pMLMEContext->InUse = FALSE;
280                         pMLMEContext->IRPPending = FALSE;
281                         pMLMEContext->bWaitingBulkOut = FALSE;
282                         pMLMEContext->BulkOutSize = 0;
283                         pMLMEContext->SelfIdx = i;
284
285                         // Offset to next ring descriptor address
286                         RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
287                 }
288                 DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
289
290                 //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
291                 pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
292                 pAd->MgmtRing.TxCpuIdx = 0;
293                 pAd->MgmtRing.TxDmaIdx = 0;
294
295                 //
296                 // BEACON_RING_SIZE
297                 //
298                 for(i=0; i<BEACON_RING_SIZE; i++) // 2
299                 {
300                         PTX_CONTEXT     pBeaconContext = &(pAd->BeaconContext[i]);
301
302
303                         NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
304
305                         //Allocate URB
306                         LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
307                                                         ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
308                                                         out2,
309                                                         ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
310                                                         out3);
311
312                         pBeaconContext->pAd = pAd;
313                         pBeaconContext->pIrp = NULL;
314                         pBeaconContext->InUse = FALSE;
315                         pBeaconContext->IRPPending = FALSE;
316                 }
317
318                 //
319                 // NullContext
320                 //
321                 NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
322
323                 //Allocate URB
324                 LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
325                                                 ("<-- ERROR in Alloc TX NullContext urb!! \n"),
326                                                 out3,
327                                                 ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
328                                                 out4);
329
330                 pNullContext->pAd = pAd;
331                 pNullContext->pIrp = NULL;
332                 pNullContext->InUse = FALSE;
333                 pNullContext->IRPPending = FALSE;
334
335                 //
336                 // RTSContext
337                 //
338                 NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
339
340                 //Allocate URB
341                 LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
342                                                 ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
343                                                 out4,
344                                                 ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
345                                                 out5);
346
347                 pRTSContext->pAd = pAd;
348                 pRTSContext->pIrp = NULL;
349                 pRTSContext->InUse = FALSE;
350                 pRTSContext->IRPPending = FALSE;
351
352                 //
353                 // PsPollContext
354                 //
355                 //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
356                 //Allocate URB
357                 LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
358                                                 ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
359                                                 out5,
360                                                 ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
361                                                 out6);
362
363                 pPsPollContext->pAd = pAd;
364                 pPsPollContext->pIrp = NULL;
365                 pPsPollContext->InUse = FALSE;
366                 pPsPollContext->IRPPending = FALSE;
367                 pPsPollContext->bAggregatible = FALSE;
368                 pPsPollContext->LastOne = TRUE;
369
370         }   while (FALSE);
371
372
373 done:
374         DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status));
375
376         return Status;
377
378         /* --------------------------- ERROR HANDLE --------------------------- */
379 out6:
380         LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
381
382 out5:
383         LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
384
385 out4:
386         LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
387
388 out3:
389         for(i=0; i<BEACON_RING_SIZE; i++)
390         {
391                 PTX_CONTEXT     pBeaconContext = &(pAd->BeaconContext[i]);
392                 if (pBeaconContext)
393                         LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
394         }
395
396 out2:
397         if (pAd->MgmtDescRing.AllocVa)
398         {
399                 pMgmtRing = &pAd->MgmtRing;
400                 for(i=0; i<MGMT_RING_SIZE; i++)
401                 {
402                         pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
403                         if (pMLMEContext)
404                                 LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
405                 }
406                 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
407                 pAd->MgmtDescRing.AllocVa = NULL;
408         }
409
410 out1:
411         for (acidx = 0; acidx < 4; acidx++)
412         {
413                 PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
414                 if (pTxContext)
415                         LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
416         }
417
418         // Here we didn't have any pre-allocated memory need to free.
419
420         return Status;
421 }
422
423
424 /*
425 ========================================================================
426 Routine Description:
427     Allocate DMA memory blocks for send, receive.
428
429 Arguments:
430     pAd                                 Pointer to our adapter
431
432 Return Value:
433         NDIS_STATUS_SUCCESS
434         NDIS_STATUS_FAILURE
435         NDIS_STATUS_RESOURCES
436
437 Note:
438 ========================================================================
439 */
440 NDIS_STATUS     RTMPAllocTxRxRingMemory(
441         IN      PRTMP_ADAPTER   pAd)
442 {
443 //      COUNTER_802_11  pCounter = &pAd->WlanCounters;
444         NDIS_STATUS             Status;
445         INT                             num;
446
447
448         DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
449
450
451         do
452         {
453                 // Init the CmdQ and CmdQLock
454                 NdisAllocateSpinLock(&pAd->CmdQLock);
455                 NdisAcquireSpinLock(&pAd->CmdQLock);
456                 RTUSBInitializeCmdQ(&pAd->CmdQ);
457                 NdisReleaseSpinLock(&pAd->CmdQLock);
458
459
460                 NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
461                 //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
462                 NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
463                 NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
464                 NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
465                 NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
466                 NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
467                 NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
468                 NdisAllocateSpinLock(&pAd->BulkInLock);
469
470                 for (num = 0; num < NUM_OF_TX_RING; num++)
471                 {
472                         NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
473                 }
474
475
476 //              NdisAllocateSpinLock(&pAd->MemLock);    // Not used in RT28XX
477
478 //              NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
479 //              NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
480
481 //              for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
482 //              {
483 //                      NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
484 //              }
485
486                 //
487                 // Init Mac Table
488                 //
489 //              MacTableInitialize(pAd);
490
491                 //
492                 // Init send data structures and related parameters
493                 //
494                 Status = NICInitTransmit(pAd);
495                 if (Status != NDIS_STATUS_SUCCESS)
496                         break;
497
498                 //
499                 // Init receive data structures and related parameters
500                 //
501                 Status = NICInitRecv(pAd);
502                 if (Status != NDIS_STATUS_SUCCESS)
503                         break;
504
505                 pAd->PendingIoCount = 1;
506
507         } while (FALSE);
508
509         NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
510         pAd->FragFrame.pFragPacket =  RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
511
512         if (pAd->FragFrame.pFragPacket == NULL)
513         {
514                 Status = NDIS_STATUS_RESOURCES;
515         }
516
517         DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
518         return Status;
519 }
520
521
522 /*
523 ========================================================================
524 Routine Description:
525         Calls USB_InterfaceStop and frees memory allocated for the URBs
526     calls NdisMDeregisterDevice and frees the memory
527     allocated in VNetInitialize for the Adapter Object
528
529 Arguments:
530         *pAd                            the raxx interface data pointer
531
532 Return Value:
533         None
534
535 Note:
536 ========================================================================
537 */
538 VOID    RTMPFreeTxRxRingMemory(
539         IN      PRTMP_ADAPTER   pAd)
540 {
541 #define LM_URB_FREE(pObj, Context, BufferSize)                          \
542         if (NULL != Context->pUrb) {                                                    \
543                 RTUSB_UNLINK_URB(Context->pUrb);                                        \
544                 RTUSB_FREE_URB(Context->pUrb);                                          \
545                 Context->pUrb = NULL; }                                                         \
546         if (NULL != Context->TransferBuffer) {                                  \
547                 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,       \
548                                                                 Context->TransferBuffer,        \
549                                                                 Context->data_dma);                     \
550                 Context->TransferBuffer = NULL; }
551
552
553         UINT                i, acidx;
554         PTX_CONTEXT                     pNullContext   = &pAd->NullContext;
555         PTX_CONTEXT                     pPsPollContext = &pAd->PsPollContext;
556         PTX_CONTEXT                     pRTSContext    = &pAd->RTSContext;
557 //      PHT_TX_CONTEXT          pHTTXContext;
558         //PRTMP_REORDERBUF      pReorderBuf;
559         POS_COOKIE                      pObj = (POS_COOKIE) pAd->OS_Cookie;
560 //      RTMP_TX_RING            *pTxRing;
561
562         DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
563         pObj = pObj;
564
565         // Free all resources for the RECEIVE buffer queue.
566         for(i=0; i<(RX_RING_SIZE); i++)
567         {
568                 PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
569                 if (pRxContext)
570                         LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
571         }
572
573         // Free PsPoll frame resource
574         LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
575
576         // Free NULL frame resource
577         LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
578
579         // Free RTS frame resource
580         LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
581
582
583         // Free beacon frame resource
584         for(i=0; i<BEACON_RING_SIZE; i++)
585         {
586                 PTX_CONTEXT     pBeaconContext = &(pAd->BeaconContext[i]);
587                 if (pBeaconContext)
588                         LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
589         }
590
591
592         // Free mgmt frame resource
593         for(i = 0; i < MGMT_RING_SIZE; i++)
594         {
595                 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
596                 //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
597                 if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
598                 {
599                         RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
600                         pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
601                         pMLMEContext->TransferBuffer = NULL;
602                 }
603
604                 if (pMLMEContext)
605                 {
606                         if (NULL != pMLMEContext->pUrb)
607                         {
608                                 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
609                                 RTUSB_FREE_URB(pMLMEContext->pUrb);
610                                 pMLMEContext->pUrb = NULL;
611                         }
612                 }
613         }
614         if (pAd->MgmtDescRing.AllocVa)
615                 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
616
617
618         // Free Tx frame resource
619         for (acidx = 0; acidx < 4; acidx++)
620                 {
621                 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
622                         if (pHTTXContext)
623                                 LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
624                 }
625
626         if (pAd->FragFrame.pFragPacket)
627                 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
628
629         for(i=0; i<6; i++)
630         {
631                 NdisFreeSpinLock(&pAd->BulkOutLock[i]);
632         }
633
634         NdisFreeSpinLock(&pAd->BulkInLock);
635         NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
636
637         NdisFreeSpinLock(&pAd->CmdQLock);
638         // Clear all pending bulk-out request flags.
639         RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
640
641 //      NdisFreeSpinLock(&pAd->MacTabLock);
642
643 //      for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
644 //      {
645 //              NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
646 //      }
647
648         DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n"));
649 }
650
651
652 /*
653 ========================================================================
654 Routine Description:
655     Write WLAN MAC address to USB 2870.
656
657 Arguments:
658     pAd                                 Pointer to our adapter
659
660 Return Value:
661         NDIS_STATUS_SUCCESS
662
663 Note:
664 ========================================================================
665 */
666 NDIS_STATUS     RTUSBWriteHWMACAddress(
667         IN      PRTMP_ADAPTER           pAd)
668 {
669         MAC_DW0_STRUC   StaMacReg0;
670         MAC_DW1_STRUC   StaMacReg1;
671         NDIS_STATUS             Status = NDIS_STATUS_SUCCESS;
672         LARGE_INTEGER   NOW;
673
674
675         // initialize the random number generator
676         RTMP_GetCurrentSystemTime(&NOW);
677
678         if (pAd->bLocalAdminMAC != TRUE)
679         {
680                 pAd->CurrentAddress[0] = pAd->PermanentAddress[0];
681                 pAd->CurrentAddress[1] = pAd->PermanentAddress[1];
682                 pAd->CurrentAddress[2] = pAd->PermanentAddress[2];
683                 pAd->CurrentAddress[3] = pAd->PermanentAddress[3];
684                 pAd->CurrentAddress[4] = pAd->PermanentAddress[4];
685                 pAd->CurrentAddress[5] = pAd->PermanentAddress[5];
686         }
687         // Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC
688         StaMacReg0.field.Byte0 = pAd->CurrentAddress[0];
689         StaMacReg0.field.Byte1 = pAd->CurrentAddress[1];
690         StaMacReg0.field.Byte2 = pAd->CurrentAddress[2];
691         StaMacReg0.field.Byte3 = pAd->CurrentAddress[3];
692         StaMacReg1.field.Byte4 = pAd->CurrentAddress[4];
693         StaMacReg1.field.Byte5 = pAd->CurrentAddress[5];
694         StaMacReg1.field.U2MeMask = 0xff;
695         DBGPRINT_RAW(RT_DEBUG_TRACE, ("Local MAC = %02x:%02x:%02x:%02x:%02x:%02x\n",
696                         pAd->CurrentAddress[0], pAd->CurrentAddress[1], pAd->CurrentAddress[2],
697                         pAd->CurrentAddress[3], pAd->CurrentAddress[4], pAd->CurrentAddress[5]));
698
699         RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word);
700         RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word);
701         return Status;
702 }
703
704
705 /*
706 ========================================================================
707 Routine Description:
708     Disable DMA.
709
710 Arguments:
711         *pAd                            the raxx interface data pointer
712
713 Return Value:
714         None
715
716 Note:
717 ========================================================================
718 */
719 VOID RT28XXDMADisable(
720         IN RTMP_ADAPTER                 *pAd)
721 {
722         // no use
723 }
724
725
726 /*
727 ========================================================================
728 Routine Description:
729     Enable DMA.
730
731 Arguments:
732         *pAd                            the raxx interface data pointer
733
734 Return Value:
735         None
736
737 Note:
738 ========================================================================
739 */
740 VOID RT28XXDMAEnable(
741         IN RTMP_ADAPTER                 *pAd)
742 {
743         WPDMA_GLO_CFG_STRUC     GloCfg;
744         USB_DMA_CFG_STRUC       UsbCfg;
745         int                                     i = 0;
746
747
748         RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
749         do
750         {
751                 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
752                 if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
753                         break;
754
755                 DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
756                 RTMPusecDelay(1000);
757                 i++;
758         }while ( i <200);
759
760
761         RTMPusecDelay(50);
762         GloCfg.field.EnTXWriteBackDDONE = 1;
763         GloCfg.field.EnableRxDMA = 1;
764         GloCfg.field.EnableTxDMA = 1;
765         DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
766         RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
767
768         UsbCfg.word = 0;
769         UsbCfg.field.phyclear = 0;
770         /* usb version is 1.1,do not use bulk in aggregation */
771         if (pAd->BulkInMaxPacketSize == 512)
772                         UsbCfg.field.RxBulkAggEn = 1;
773         /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
774         UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
775         UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
776         UsbCfg.field.RxBulkEn = 1;
777         UsbCfg.field.TxBulkEn = 1;
778
779         RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
780
781 }
782
783 /********************************************************************
784   *
785   *     2870 Beacon Update Related functions.
786   *
787   ********************************************************************/
788
789 /*
790 ========================================================================
791 Routine Description:
792     Write Beacon buffer to Asic.
793
794 Arguments:
795         *pAd                            the raxx interface data pointer
796
797 Return Value:
798         None
799
800 Note:
801 ========================================================================
802 */
803 VOID RT28xx_UpdateBeaconToAsic(
804         IN RTMP_ADAPTER         *pAd,
805         IN INT                          apidx,
806         IN ULONG                        FrameLen,
807         IN ULONG                        UpdatePos)
808 {
809         PUCHAR          pBeaconFrame = NULL;
810         UCHAR                   *ptr;
811         UINT                    i, padding;
812         BEACON_SYNC_STRUCT      *pBeaconSync = pAd->CommonCfg.pBeaconSync;
813         UINT32                  longValue;
814 //      USHORT                  shortValue;
815         BOOLEAN                 bBcnReq = FALSE;
816         UCHAR                   bcn_idx = 0;
817
818
819         if (pBeaconFrame == NULL)
820         {
821                 DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
822                 return;
823         }
824
825         if (pBeaconSync == NULL)
826         {
827                 DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
828                 return;
829         }
830
831         //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
832         //      ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
833         //      )
834         if (bBcnReq == FALSE)
835         {
836                 /* when the ra interface is down, do not send its beacon frame */
837                 /* clear all zero */
838                 for(i=0; i<TXWI_SIZE; i+=4) {
839                         RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
840                 }
841                 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
842                 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
843         }
844         else
845         {
846                 ptr = (PUCHAR)&pAd->BeaconTxWI;
847                 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
848                 {       // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
849                         pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
850                         NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
851                 }
852
853                 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
854                 {
855                         for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
856                         {
857                                 longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
858                                 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
859                                 ptr += 4;
860                         }
861                 }
862
863                 ptr = pBeaconSync->BeaconBuf[bcn_idx];
864                 padding = (FrameLen & 0x01);
865                 NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
866                 FrameLen += padding;
867                 for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
868                 {
869                         if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
870                         {
871                                 NdisMoveMemory(ptr, pBeaconFrame, 2);
872                                 //shortValue = *ptr + (*(ptr+1)<<8);
873                                 //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
874                                 RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
875                         }
876                         ptr +=2;
877                         pBeaconFrame += 2;
878                 }
879
880                 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
881
882                 // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
883 }
884
885 }
886
887
888 VOID RTUSBBssBeaconStop(
889         IN RTMP_ADAPTER *pAd)
890 {
891         BEACON_SYNC_STRUCT      *pBeaconSync;
892         int i, offset;
893         BOOLEAN Cancelled = TRUE;
894
895         pBeaconSync = pAd->CommonCfg.pBeaconSync;
896         if (pBeaconSync && pBeaconSync->EnableBeacon)
897         {
898                 INT NumOfBcn;
899
900                 {
901                         NumOfBcn = MAX_MESH_NUM;
902                 }
903
904                 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
905
906                 for(i=0; i<NumOfBcn; i++)
907                 {
908                         NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
909                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
910
911                         for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
912                                 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
913
914                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
915                         pBeaconSync->TimIELocationInBeacon[i] = 0;
916                 }
917                 pBeaconSync->BeaconBitMap = 0;
918                 pBeaconSync->DtimBitOn = 0;
919         }
920 }
921
922
923 VOID RTUSBBssBeaconStart(
924         IN RTMP_ADAPTER *pAd)
925 {
926         int apidx;
927         BEACON_SYNC_STRUCT      *pBeaconSync;
928 //      LARGE_INTEGER   tsfTime, deltaTime;
929
930         pBeaconSync = pAd->CommonCfg.pBeaconSync;
931         if (pBeaconSync && pBeaconSync->EnableBeacon)
932         {
933                 INT NumOfBcn;
934
935                 {
936                         NumOfBcn = MAX_MESH_NUM;
937                 }
938
939                 for(apidx=0; apidx<NumOfBcn; apidx++)
940                 {
941                         UCHAR CapabilityInfoLocationInBeacon = 0;
942                         UCHAR TimIELocationInBeacon = 0;
943
944
945                         NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
946                         pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
947                         pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
948                         NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
949                 }
950                 pBeaconSync->BeaconBitMap = 0;
951                 pBeaconSync->DtimBitOn = 0;
952                 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
953
954                 pAd->CommonCfg.BeaconAdjust = 0;
955                 pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
956                 pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
957                 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n",
958                                                                         pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain));
959                 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, 10 /*pAd->CommonCfg.BeaconPeriod*/);
960
961         }
962 }
963
964
965 VOID RTUSBBssBeaconInit(
966         IN RTMP_ADAPTER *pAd)
967 {
968         BEACON_SYNC_STRUCT      *pBeaconSync;
969         int i;
970
971         os_alloc_mem(pAd, (PUCHAR *)(&pAd->CommonCfg.pBeaconSync), sizeof(BEACON_SYNC_STRUCT));
972         //NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
973         if (pAd->CommonCfg.pBeaconSync)
974         {
975                 pBeaconSync = pAd->CommonCfg.pBeaconSync;
976                 NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
977                 for(i=0; i < HW_BEACON_MAX_COUNT; i++)
978                 {
979                         NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
980                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
981                         pBeaconSync->TimIELocationInBeacon[i] = 0;
982                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
983                 }
984                 pBeaconSync->BeaconBitMap = 0;
985
986                 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
987                 pBeaconSync->EnableBeacon = TRUE;
988         }
989 }
990
991
992 VOID RTUSBBssBeaconExit(
993         IN RTMP_ADAPTER *pAd)
994 {
995         BEACON_SYNC_STRUCT      *pBeaconSync;
996         BOOLEAN Cancelled = TRUE;
997         int i;
998
999         if (pAd->CommonCfg.pBeaconSync)
1000         {
1001                 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1002                 pBeaconSync->EnableBeacon = FALSE;
1003                 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1004                 pBeaconSync->BeaconBitMap = 0;
1005
1006                 for(i=0; i<HW_BEACON_MAX_COUNT; i++)
1007                 {
1008                         NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1009                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1010                         pBeaconSync->TimIELocationInBeacon[i] = 0;
1011                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1012                 }
1013
1014                 os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
1015                 pAd->CommonCfg.pBeaconSync = NULL;
1016         }
1017 }
1018
1019
1020 /*
1021     ========================================================================
1022     Routine Description:
1023         For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism
1024         to update the beacon context in each Beacon interval. Here we use a periodical timer
1025         to simulate the TBTT interrupt to handle the beacon context update.
1026
1027     Arguments:
1028         SystemSpecific1         - Not used.
1029         FunctionContext         - Pointer to our Adapter context.
1030         SystemSpecific2         - Not used.
1031         SystemSpecific3         - Not used.
1032
1033     Return Value:
1034         None
1035
1036     ========================================================================
1037 */
1038 VOID BeaconUpdateExec(
1039     IN PVOID SystemSpecific1,
1040     IN PVOID FunctionContext,
1041     IN PVOID SystemSpecific2,
1042     IN PVOID SystemSpecific3)
1043 {
1044         PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER)FunctionContext;
1045         LARGE_INTEGER   tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
1046         UINT32                  delta, delta2MS, period2US, remain, remain_low, remain_high;
1047 //      BOOLEAN                 positive;
1048
1049         if (pAd->CommonCfg.IsUpdateBeacon==TRUE)
1050         {
1051                 ReSyncBeaconTime(pAd);
1052
1053
1054         }
1055
1056         RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1057         RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1058
1059
1060         //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1061         period2US = (pAd->CommonCfg.BeaconPeriod << 10);
1062         remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1063         remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1064         remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
1065         delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1066
1067         delta2MS = (delta>>10);
1068         if (delta2MS > 150)
1069         {
1070                 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100;
1071                 pAd->CommonCfg.IsUpdateBeacon=FALSE;
1072         }
1073         else
1074         {
1075                 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10;
1076                 pAd->CommonCfg.IsUpdateBeacon=TRUE;
1077         }
1078
1079 }
1080
1081
1082 /********************************************************************
1083   *
1084   *     2870 Radio on/off Related functions.
1085   *
1086   ********************************************************************/
1087 VOID RT28xxUsbMlmeRadioOn(
1088         IN PRTMP_ADAPTER pAd)
1089 {
1090         RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
1091
1092     DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
1093
1094         if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1095                 return;
1096
1097         {
1098                 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
1099                 RTMPusecDelay(10000);
1100         }
1101         //NICResetFromError(pAd);
1102
1103         // Enable Tx/Rx
1104         RTMPEnableRxTx(pAd);
1105
1106         if (pChipOps->AsicReverseRfFromSleepMode)
1107                 pChipOps->AsicReverseRfFromSleepMode(pAd);
1108
1109         // Clear Radio off flag
1110         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1111
1112                 RTUSBBulkReceive(pAd);
1113
1114         // Set LED
1115         RTMPSetLED(pAd, LED_RADIO_ON);
1116 }
1117
1118
1119 VOID RT28xxUsbMlmeRadioOFF(
1120         IN PRTMP_ADAPTER pAd)
1121 {
1122         WPDMA_GLO_CFG_STRUC     GloCfg;
1123         UINT32  Value, i;
1124
1125         DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
1126
1127         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1128                 return;
1129
1130         // Clear PMKID cache.
1131         pAd->StaCfg.SavedPMKNum = 0;
1132         RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(BSSID_INFO)));
1133
1134         // Link down first if any association exists
1135         if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
1136         {
1137                 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1138                 {
1139                         MLME_DISASSOC_REQ_STRUCT DisReq;
1140                         MLME_QUEUE_ELEM *pMsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
1141
1142                         if (pMsgElem)
1143                         {
1144                                 COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid);
1145                                 DisReq.Reason =  REASON_DISASSOC_STA_LEAVING;
1146
1147                                 pMsgElem->Machine = ASSOC_STATE_MACHINE;
1148                                 pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
1149                                 pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
1150                                 NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
1151
1152                                 MlmeDisassocReqAction(pAd, pMsgElem);
1153                                 kfree(pMsgElem);
1154
1155                                 RTMPusecDelay(1000);
1156                         }
1157                 }
1158         }
1159
1160         // Set Radio off flag
1161         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1162
1163         {
1164                 // Link down first if any association exists
1165                 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1166                         LinkDown(pAd, FALSE);
1167                 RTMPusecDelay(10000);
1168
1169                 //==========================================
1170                 // Clean up old bss table
1171                 BssTableInit(&pAd->ScanTab);
1172         }
1173
1174         // Set LED
1175         RTMPSetLED(pAd, LED_RADIO_OFF);
1176
1177
1178         if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1179         {
1180                 // Must using 40MHz.
1181                 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
1182         }
1183         else
1184         {
1185                 // Must using 20MHz.
1186                 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
1187         }
1188
1189         // Disable Tx/Rx DMA
1190         RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word);    // disable DMA
1191         GloCfg.field.EnableTxDMA = 0;
1192         GloCfg.field.EnableRxDMA = 0;
1193         RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word);    // abort all TX rings
1194
1195         // Waiting for DMA idle
1196         i = 0;
1197         do
1198         {
1199                 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1200                 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1201                         break;
1202
1203                 RTMPusecDelay(1000);
1204         }while (i++ < 100);
1205
1206         // Disable MAC Tx/Rx
1207         RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1208         Value &= (0xfffffff3);
1209         RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1210
1211         {
1212                 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1213         }
1214 }
1215
1216 #endif // RTMP_MAC_USB //