Merge branches 'x86/acpi', 'x86/asm', 'x86/cpudetect', 'x86/crashdump', 'x86/debug...
[linux-2.6] / drivers / staging / rt2870 / common / 2870_rtmp_init.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         Module Name:
28         2870_rtmp_init.c
29
30         Abstract:
31         Miniport generic portion header file
32
33         Revision History:
34         Who         When          What
35         --------    ----------    ----------------------------------------------
36         Paul Lin    2002-08-01    created
37     John Chang  2004-08-20    RT2561/2661 use scatter-gather scheme
38     Jan Lee     2006-09-15    RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
39         Sample Lin      2007-05-31    Merge RT2860 and RT2870 drivers.
40 */
41
42 #include "../rt_config.h"
43
44
45 static void rx_done_tasklet(unsigned long data);
46 static void rt2870_hcca_dma_done_tasklet(unsigned long data);
47 static void rt2870_ac3_dma_done_tasklet(unsigned long data);
48 static void rt2870_ac2_dma_done_tasklet(unsigned long data);
49 static void rt2870_ac1_dma_done_tasklet(unsigned long data);
50 static void rt2870_ac0_dma_done_tasklet(unsigned long data);
51 static void rt2870_mgmt_dma_done_tasklet(unsigned long data);
52 static void rt2870_null_frame_complete_tasklet(unsigned long data);
53 static void rt2870_rts_frame_complete_tasklet(unsigned long data);
54 static void rt2870_pspoll_frame_complete_tasklet(unsigned long data);
55 static void rt2870_dataout_complete_tasklet(unsigned long data);
56
57
58 /*
59 ========================================================================
60 Routine Description:
61     Initialize receive data structures.
62
63 Arguments:
64     pAd                                 Pointer to our adapter
65
66 Return Value:
67         NDIS_STATUS_SUCCESS
68         NDIS_STATUS_RESOURCES
69
70 Note:
71         Initialize all receive releated private buffer, include those define
72         in RTMP_ADAPTER structure and all private data structures. The mahor
73         work is to allocate buffer for each packet and chain buffer to
74         NDIS packet descriptor.
75 ========================================================================
76 */
77 NDIS_STATUS     NICInitRecv(
78         IN      PRTMP_ADAPTER   pAd)
79 {
80         UCHAR                           i;
81         NDIS_STATUS                     Status = NDIS_STATUS_SUCCESS;
82         POS_COOKIE                      pObj = (POS_COOKIE) pAd->OS_Cookie;
83
84
85         DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
86         pObj = pObj;
87
88         //InterlockedExchange(&pAd->PendingRx, 0);
89         pAd->PendingRx = 0;
90         pAd->NextRxBulkInReadIndex      = 0;    // Next Rx Read index
91         pAd->NextRxBulkInIndex          = 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
92         pAd->NextRxBulkInPosition       = 0;
93
94         for (i = 0; i < (RX_RING_SIZE); i++)
95         {
96                 PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
97
98                 //Allocate URB
99                 pRxContext->pUrb = RTUSB_ALLOC_URB(0);
100                 if (pRxContext->pUrb == NULL)
101                 {
102                         Status = NDIS_STATUS_RESOURCES;
103                         goto out1;
104                 }
105
106                 // Allocate transfer buffer
107                 pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
108                 if (pRxContext->TransferBuffer == NULL)
109                 {
110                         Status = NDIS_STATUS_RESOURCES;
111                         goto out1;
112                 }
113
114                 NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
115
116                 pRxContext->pAd = pAd;
117                 pRxContext->pIrp = NULL;
118                 pRxContext->InUse               = FALSE;
119                 pRxContext->IRPPending  = FALSE;
120                 pRxContext->Readable    = FALSE;
121                 //pRxContext->ReorderInUse = FALSE;
122                 pRxContext->bRxHandling = FALSE;
123                 pRxContext->BulkInOffset = 0;
124         }
125
126         DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv\n"));
127         return Status;
128
129 out1:
130         for (i = 0; i < (RX_RING_SIZE); i++)
131         {
132                 PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
133
134                 if (NULL != pRxContext->TransferBuffer)
135                 {
136                         RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
137                                                                 pRxContext->TransferBuffer, pRxContext->data_dma);
138                         pRxContext->TransferBuffer = NULL;
139                 }
140
141                 if (NULL != pRxContext->pUrb)
142                 {
143                         RTUSB_UNLINK_URB(pRxContext->pUrb);
144                         RTUSB_FREE_URB(pRxContext->pUrb);
145                         pRxContext->pUrb = NULL;
146                 }
147         }
148
149         return Status;
150 }
151
152
153 /*
154 ========================================================================
155 Routine Description:
156     Initialize transmit data structures.
157
158 Arguments:
159     pAd                                 Pointer to our adapter
160
161 Return Value:
162         NDIS_STATUS_SUCCESS
163         NDIS_STATUS_RESOURCES
164
165 Note:
166 ========================================================================
167 */
168 NDIS_STATUS     NICInitTransmit(
169         IN      PRTMP_ADAPTER   pAd)
170 {
171 #define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2)        \
172         Context->pUrb = RTUSB_ALLOC_URB(0);             \
173         if (Context->pUrb == NULL) {                    \
174                 DBGPRINT(RT_DEBUG_ERROR, msg1);         \
175                 Status = NDIS_STATUS_RESOURCES;         \
176                 goto err1; }                                            \
177                                                                                         \
178         Context->TransferBuffer =                               \
179                 (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma);        \
180         if (Context->TransferBuffer == NULL) {  \
181                 DBGPRINT(RT_DEBUG_ERROR, msg2);         \
182                 Status = NDIS_STATUS_RESOURCES;         \
183                 goto err2; }
184
185 #define LM_URB_FREE(pObj, Context, BufferSize)                          \
186         if (NULL != Context->pUrb) {                                                    \
187                 RTUSB_UNLINK_URB(Context->pUrb);                                        \
188                 RTUSB_FREE_URB(Context->pUrb);                                          \
189                 Context->pUrb = NULL; }                                                         \
190         if (NULL != Context->TransferBuffer) {                          \
191                 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,       \
192                                                                 Context->TransferBuffer,        \
193                                                                 Context->data_dma);                     \
194                 Context->TransferBuffer = NULL; }
195
196         UCHAR                   i, acidx;
197         NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
198         PTX_CONTEXT             pNullContext   = &(pAd->NullContext);
199         PTX_CONTEXT             pPsPollContext = &(pAd->PsPollContext);
200         PTX_CONTEXT             pRTSContext    = &(pAd->RTSContext);
201         PTX_CONTEXT             pMLMEContext = NULL;
202 //      PHT_TX_CONTEXT  pHTTXContext = NULL;
203         POS_COOKIE              pObj = (POS_COOKIE) pAd->OS_Cookie;
204         PVOID                   RingBaseVa;
205 //      RTMP_TX_RING    *pTxRing;
206         RTMP_MGMT_RING  *pMgmtRing;
207
208         DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
209         pObj = pObj;
210
211         // Init 4 set of Tx parameters
212         for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
213         {
214                 // Initialize all Transmit releated queues
215                 InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
216
217                 // Next Local tx ring pointer waiting for buck out
218                 pAd->NextBulkOutIndex[acidx] = acidx;
219                 pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
220                 //pAd->DataBulkDoneIdx[acidx] = 0;
221         }
222
223         //pAd->NextMLMEIndex    = 0;
224         //pAd->PushMgmtIndex    = 0;
225         //pAd->PopMgmtIndex     = 0;
226         //InterlockedExchange(&pAd->MgmtQueueSize, 0);
227         //InterlockedExchange(&pAd->TxCount, 0);
228
229         //pAd->PrioRingFirstIndex       = 0;
230         //pAd->PrioRingTxCnt            = 0;
231
232         do
233         {
234                 //
235                 // TX_RING_SIZE, 4 ACs
236                 //
237                 for(acidx=0; acidx<4; acidx++)
238                 {
239                         PHT_TX_CONTEXT  pHTTXContext = &(pAd->TxContext[acidx]);
240
241                         NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
242                         //Allocate URB
243                         LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
244                                                         ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
245                                                         done,
246                                                         ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
247                                                         out1);
248
249                         NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
250                         pHTTXContext->pAd = pAd;
251                         pHTTXContext->pIrp = NULL;
252                         pHTTXContext->IRPPending = FALSE;
253                         pHTTXContext->NextBulkOutPosition = 0;
254                         pHTTXContext->ENextBulkOutPosition = 0;
255                         pHTTXContext->CurWritePosition = 0;
256                         pHTTXContext->CurWriteRealPos = 0;
257                         pHTTXContext->BulkOutSize = 0;
258                         pHTTXContext->BulkOutPipeId = acidx;
259                         pHTTXContext->bRingEmpty = TRUE;
260                         pHTTXContext->bCopySavePad = FALSE;
261
262                         pAd->BulkOutPending[acidx] = FALSE;
263                 }
264
265
266                 //
267                 // MGMT_RING_SIZE
268                 //
269 #if 0
270                 for(i=0; i<MGMT_RING_SIZE; i++) // 8
271                 {
272                         PTX_CONTEXT     pMLMEContext = &(pAd->MLMEContext[i]);
273
274
275                         NdisZeroMemory(pMLMEContext, sizeof(TX_CONTEXT));
276
277                         //Allocate URB
278                         LM_USB_ALLOC(pObj, pMLMEContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
279                                                         ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i),
280                                                         out2,
281                                                         ("<-- ERROR in Alloc TX MLMEContext[%d] TX_BUFFER !! \n", i),
282                                                         out2);
283
284                         pMLMEContext->pAd = pAd;
285                         pMLMEContext->pIrp = NULL;
286                         pMLMEContext->InUse = FALSE;
287                         pMLMEContext->IRPPending = FALSE;
288                 }
289 #else
290                 // Allocate MGMT ring descriptor's memory
291                 pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
292                 RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
293                 if (pAd->MgmtDescRing.AllocVa == NULL)
294                 {
295                         DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
296                         Status = NDIS_STATUS_RESOURCES;
297                         goto out1;
298                 }
299                 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
300                 RingBaseVa     = pAd->MgmtDescRing.AllocVa;
301
302                 // Initialize MGMT Ring and associated buffer memory
303                 pMgmtRing = &pAd->MgmtRing;
304                 for (i = 0; i < MGMT_RING_SIZE; i++)
305                 {
306                         // link the pre-allocated Mgmt buffer to MgmtRing.Cell
307                         pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
308                         pMgmtRing->Cell[i].AllocVa = RingBaseVa;
309                         pMgmtRing->Cell[i].pNdisPacket = NULL;
310                         pMgmtRing->Cell[i].pNextNdisPacket = NULL;
311
312                         //Allocate URB for MLMEContext
313                         pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
314                         pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
315                         if (pMLMEContext->pUrb == NULL)
316                         {
317                                 DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
318                                 Status = NDIS_STATUS_RESOURCES;
319                                 goto out2;
320                         }
321                         pMLMEContext->pAd = pAd;
322                         pMLMEContext->pIrp = NULL;
323                         pMLMEContext->TransferBuffer = NULL;
324                         pMLMEContext->InUse = FALSE;
325                         pMLMEContext->IRPPending = FALSE;
326                         pMLMEContext->bWaitingBulkOut = FALSE;
327                         pMLMEContext->BulkOutSize = 0;
328                         pMLMEContext->SelfIdx = i;
329
330                         // Offset to next ring descriptor address
331                         RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
332                 }
333                 DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
334
335                 //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
336                 pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
337                 pAd->MgmtRing.TxCpuIdx = 0;
338                 pAd->MgmtRing.TxDmaIdx = 0;
339 #endif
340
341                 //
342                 // BEACON_RING_SIZE
343                 //
344                 for(i=0; i<BEACON_RING_SIZE; i++) // 2
345                 {
346                         PTX_CONTEXT     pBeaconContext = &(pAd->BeaconContext[i]);
347
348
349                         NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
350
351                         //Allocate URB
352                         LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
353                                                         ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
354                                                         out2,
355                                                         ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
356                                                         out3);
357
358                         pBeaconContext->pAd = pAd;
359                         pBeaconContext->pIrp = NULL;
360                         pBeaconContext->InUse = FALSE;
361                         pBeaconContext->IRPPending = FALSE;
362                 }
363
364                 //
365                 // NullContext
366                 //
367                 NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
368
369                 //Allocate URB
370                 LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
371                                                 ("<-- ERROR in Alloc TX NullContext urb!! \n"),
372                                                 out3,
373                                                 ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
374                                                 out4);
375
376                 pNullContext->pAd = pAd;
377                 pNullContext->pIrp = NULL;
378                 pNullContext->InUse = FALSE;
379                 pNullContext->IRPPending = FALSE;
380
381                 //
382                 // RTSContext
383                 //
384                 NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
385
386                 //Allocate URB
387                 LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
388                                                 ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
389                                                 out4,
390                                                 ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
391                                                 out5);
392
393                 pRTSContext->pAd = pAd;
394                 pRTSContext->pIrp = NULL;
395                 pRTSContext->InUse = FALSE;
396                 pRTSContext->IRPPending = FALSE;
397
398                 //
399                 // PsPollContext
400                 //
401                 //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
402                 //Allocate URB
403                 LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
404                                                 ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
405                                                 out5,
406                                                 ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
407                                                 out6);
408
409                 pPsPollContext->pAd = pAd;
410                 pPsPollContext->pIrp = NULL;
411                 pPsPollContext->InUse = FALSE;
412                 pPsPollContext->IRPPending = FALSE;
413                 pPsPollContext->bAggregatible = FALSE;
414                 pPsPollContext->LastOne = TRUE;
415
416         }   while (FALSE);
417
418
419 done:
420         DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n"));
421
422         return Status;
423
424         /* --------------------------- ERROR HANDLE --------------------------- */
425 out6:
426         LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
427
428 out5:
429         LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
430
431 out4:
432         LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
433
434 out3:
435         for(i=0; i<BEACON_RING_SIZE; i++)
436         {
437                 PTX_CONTEXT     pBeaconContext = &(pAd->BeaconContext[i]);
438                 if (pBeaconContext)
439                         LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
440         }
441
442 out2:
443         if (pAd->MgmtDescRing.AllocVa)
444         {
445                 pMgmtRing = &pAd->MgmtRing;
446         for(i=0; i<MGMT_RING_SIZE; i++)
447         {
448                 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
449                 if (pMLMEContext)
450                         LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
451         }
452                 NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
453                 pAd->MgmtDescRing.AllocVa = NULL;
454         }
455
456 out1:
457         for (acidx = 0; acidx < 4; acidx++)
458         {
459                 PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
460                 if (pTxContext)
461                         LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
462         }
463
464         // Here we didn't have any pre-allocated memory need to free.
465
466         return Status;
467 }
468
469
470 /*
471 ========================================================================
472 Routine Description:
473     Allocate DMA memory blocks for send, receive.
474
475 Arguments:
476     pAd                                 Pointer to our adapter
477
478 Return Value:
479         NDIS_STATUS_SUCCESS
480         NDIS_STATUS_FAILURE
481         NDIS_STATUS_RESOURCES
482
483 Note:
484 ========================================================================
485 */
486 NDIS_STATUS     RTMPAllocTxRxRingMemory(
487         IN      PRTMP_ADAPTER   pAd)
488 {
489 //      COUNTER_802_11  pCounter = &pAd->WlanCounters;
490         NDIS_STATUS             Status;
491         INT                             num;
492
493
494         DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
495
496
497         do
498         {
499                 // Init the CmdQ and CmdQLock
500                 NdisAllocateSpinLock(&pAd->CmdQLock);
501                 NdisAcquireSpinLock(&pAd->CmdQLock);
502                 RTUSBInitializeCmdQ(&pAd->CmdQ);
503                 NdisReleaseSpinLock(&pAd->CmdQLock);
504
505
506                 NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
507                 //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
508                 NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
509                 NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
510                 NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
511                 NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
512                 NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
513                 NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
514                 NdisAllocateSpinLock(&pAd->BulkInLock);
515
516                 for (num = 0; num < NUM_OF_TX_RING; num++)
517                 {
518                         NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
519                 }
520
521 #ifdef RALINK_ATE
522                 NdisAllocateSpinLock(&pAd->GenericLock);
523 #endif // RALINK_ATE //
524
525 //              NdisAllocateSpinLock(&pAd->MemLock);    // Not used in RT28XX
526
527 //              NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
528 //              NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
529
530 //              for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
531 //              {
532 //                      NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
533 //              }
534
535                 //
536                 // Init Mac Table
537                 //
538 //              MacTableInitialize(pAd);
539
540                 //
541                 // Init send data structures and related parameters
542                 //
543                 Status = NICInitTransmit(pAd);
544                 if (Status != NDIS_STATUS_SUCCESS)
545                         break;
546
547                 //
548                 // Init receive data structures and related parameters
549                 //
550                 Status = NICInitRecv(pAd);
551                 if (Status != NDIS_STATUS_SUCCESS)
552                         break;
553
554                 pAd->PendingIoCount = 1;
555
556         } while (FALSE);
557
558         NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
559         pAd->FragFrame.pFragPacket =  RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
560
561         if (pAd->FragFrame.pFragPacket == NULL)
562         {
563                 Status = NDIS_STATUS_RESOURCES;
564         }
565
566         DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
567         return Status;
568 }
569
570
571 /*
572 ========================================================================
573 Routine Description:
574         Calls USB_InterfaceStop and frees memory allocated for the URBs
575     calls NdisMDeregisterDevice and frees the memory
576     allocated in VNetInitialize for the Adapter Object
577
578 Arguments:
579         *pAd                            the raxx interface data pointer
580
581 Return Value:
582         None
583
584 Note:
585 ========================================================================
586 */
587 VOID    RTMPFreeTxRxRingMemory(
588         IN      PRTMP_ADAPTER   pAd)
589 {
590 #define LM_URB_FREE(pObj, Context, BufferSize)                          \
591         if (NULL != Context->pUrb) {                                                    \
592                 RTUSB_UNLINK_URB(Context->pUrb);                                        \
593                 RTUSB_FREE_URB(Context->pUrb);                                          \
594                 Context->pUrb = NULL; }                                                         \
595         if (NULL != Context->TransferBuffer) {                                  \
596                 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,       \
597                                                                 Context->TransferBuffer,        \
598                                                                 Context->data_dma);                     \
599                 Context->TransferBuffer = NULL; }
600
601
602         UINT                i, acidx;
603         PTX_CONTEXT                     pNullContext   = &pAd->NullContext;
604         PTX_CONTEXT                     pPsPollContext = &pAd->PsPollContext;
605         PTX_CONTEXT                     pRTSContext    = &pAd->RTSContext;
606 //      PHT_TX_CONTEXT          pHTTXContext;
607         //PRTMP_REORDERBUF      pReorderBuf;
608         POS_COOKIE                      pObj = (POS_COOKIE) pAd->OS_Cookie;
609 //      RTMP_TX_RING            *pTxRing;
610
611         DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
612         pObj = pObj;
613
614         // Free all resources for the RECEIVE buffer queue.
615         for(i=0; i<(RX_RING_SIZE); i++)
616         {
617                 PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
618                 if (pRxContext)
619                         LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
620         }
621
622         // Free PsPoll frame resource
623         LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
624
625         // Free NULL frame resource
626         LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
627
628         // Free RTS frame resource
629         LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
630
631
632         // Free beacon frame resource
633         for(i=0; i<BEACON_RING_SIZE; i++)
634         {
635                 PTX_CONTEXT     pBeaconContext = &(pAd->BeaconContext[i]);
636                 if (pBeaconContext)
637                         LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
638         }
639
640
641         // Free mgmt frame resource
642         for(i = 0; i < MGMT_RING_SIZE; i++)
643         {
644                 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
645                 //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
646                 if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
647                 {
648                         RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
649                         pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
650                         pMLMEContext->TransferBuffer = NULL;
651                 }
652
653                 if (pMLMEContext)
654                 {
655                         if (NULL != pMLMEContext->pUrb)
656                         {
657                                 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
658                                 RTUSB_FREE_URB(pMLMEContext->pUrb);
659                                 pMLMEContext->pUrb = NULL;
660                         }
661                 }
662         }
663         if (pAd->MgmtDescRing.AllocVa)
664                 NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
665
666
667         // Free Tx frame resource
668         for (acidx = 0; acidx < 4; acidx++)
669                 {
670                 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
671                         if (pHTTXContext)
672                                 LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
673                 }
674
675         if (pAd->FragFrame.pFragPacket)
676                 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
677
678         for(i=0; i<6; i++)
679         {
680                 NdisFreeSpinLock(&pAd->BulkOutLock[i]);
681         }
682
683         NdisFreeSpinLock(&pAd->BulkInLock);
684         NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
685
686         NdisFreeSpinLock(&pAd->CmdQLock);
687 #ifdef RALINK_ATE
688         NdisFreeSpinLock(&pAd->GenericLock);
689 #endif // RALINK_ATE //
690         // Clear all pending bulk-out request flags.
691         RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
692
693 //      NdisFreeSpinLock(&pAd->MacTabLock);
694
695 //      for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
696 //      {
697 //              NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
698 //      }
699
700         DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n"));
701 }
702
703
704 /*
705 ========================================================================
706 Routine Description:
707     Allocate memory for adapter control block.
708
709 Arguments:
710     pAd                                 Pointer to our adapter
711
712 Return Value:
713         NDIS_STATUS_SUCCESS
714         NDIS_STATUS_FAILURE
715         NDIS_STATUS_RESOURCES
716
717 Note:
718 ========================================================================
719 */
720 NDIS_STATUS AdapterBlockAllocateMemory(
721         IN PVOID        handle,
722         OUT     PVOID   *ppAd)
723 {
724         PUSB_DEV        usb_dev;
725         POS_COOKIE      pObj = (POS_COOKIE) handle;
726
727
728         usb_dev = pObj->pUsb_Dev;
729
730         pObj->MLMEThr_pid               = THREAD_PID_INIT_VALUE;
731         pObj->RTUSBCmdThr_pid   = THREAD_PID_INIT_VALUE;
732
733         *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
734
735         if (*ppAd)
736         {
737                 NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
738                 ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
739                 return (NDIS_STATUS_SUCCESS);
740         }
741         else
742         {
743                 return (NDIS_STATUS_FAILURE);
744         }
745 }
746
747
748 /*
749 ========================================================================
750 Routine Description:
751     Create kernel threads & tasklets.
752
753 Arguments:
754     *net_dev                    Pointer to wireless net device interface
755
756 Return Value:
757         NDIS_STATUS_SUCCESS
758         NDIS_STATUS_FAILURE
759
760 Note:
761 ========================================================================
762 */
763 NDIS_STATUS      CreateThreads(
764         IN      struct net_device *net_dev)
765 {
766         PRTMP_ADAPTER pAd = net_dev->ml_priv;
767         POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
768         pid_t pid_number = -1;
769
770         //init_MUTEX(&(pAd->usbdev_semaphore));
771
772         init_MUTEX_LOCKED(&(pAd->mlme_semaphore));
773         init_completion (&pAd->mlmeComplete);
774
775         init_MUTEX_LOCKED(&(pAd->RTUSBCmd_semaphore));
776         init_completion (&pAd->CmdQComplete);
777
778         init_MUTEX_LOCKED(&(pAd->RTUSBTimer_semaphore));
779         init_completion (&pAd->TimerQComplete);
780
781         // Creat MLME Thread
782         pObj->MLMEThr_pid= THREAD_PID_INIT_VALUE;
783         pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
784         if (pid_number < 0)
785         {
786                 printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
787                 return NDIS_STATUS_FAILURE;
788         }
789         pObj->MLMEThr_pid = GET_PID(pid_number);
790         // Wait for the thread to start
791         wait_for_completion(&(pAd->mlmeComplete));
792
793         // Creat Command Thread
794         pObj->RTUSBCmdThr_pid= THREAD_PID_INIT_VALUE;
795         pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
796         if (pid_number < 0)
797         {
798                 printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
799                 return NDIS_STATUS_FAILURE;
800         }
801         pObj->RTUSBCmdThr_pid = GET_PID(pid_number);
802         wait_for_completion(&(pAd->CmdQComplete));
803
804         pObj->TimerQThr_pid= THREAD_PID_INIT_VALUE;
805         pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
806         if (pid_number < 0)
807         {
808                 printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
809                 return NDIS_STATUS_FAILURE;
810         }
811         pObj->TimerQThr_pid = GET_PID(pid_number);
812         // Wait for the thread to start
813         wait_for_completion(&(pAd->TimerQComplete));
814
815         // Create receive tasklet
816         tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd);
817         tasklet_init(&pObj->mgmt_dma_done_task, rt2870_mgmt_dma_done_tasklet, (unsigned long)pAd);
818         tasklet_init(&pObj->ac0_dma_done_task, rt2870_ac0_dma_done_tasklet, (unsigned long)pAd);
819         tasklet_init(&pObj->ac1_dma_done_task, rt2870_ac1_dma_done_tasklet, (unsigned long)pAd);
820         tasklet_init(&pObj->ac2_dma_done_task, rt2870_ac2_dma_done_tasklet, (unsigned long)pAd);
821         tasklet_init(&pObj->ac3_dma_done_task, rt2870_ac3_dma_done_tasklet, (unsigned long)pAd);
822         tasklet_init(&pObj->hcca_dma_done_task, rt2870_hcca_dma_done_tasklet, (unsigned long)pAd);
823         tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
824         tasklet_init(&pObj->null_frame_complete_task, rt2870_null_frame_complete_tasklet, (unsigned long)pAd);
825         tasklet_init(&pObj->rts_frame_complete_task, rt2870_rts_frame_complete_tasklet, (unsigned long)pAd);
826         tasklet_init(&pObj->pspoll_frame_complete_task, rt2870_pspoll_frame_complete_tasklet, (unsigned long)pAd);
827
828         return NDIS_STATUS_SUCCESS;
829 }
830
831
832 #ifdef CONFIG_STA_SUPPORT
833 /*
834 ========================================================================
835 Routine Description:
836         As STA's BSSID is a WC too, it uses shared key table.
837         This function write correct unicast TX key to ASIC WCID.
838         And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
839         Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
840         Caller guarantee WEP calls this function when set Txkey,  default key index=0~3.
841
842 Arguments:
843         pAd                                     Pointer to our adapter
844         pKey                                    Pointer to the where the key stored
845
846 Return Value:
847         NDIS_SUCCESS                    Add key successfully
848
849 Note:
850 ========================================================================
851 */
852 VOID    RTMPAddBSSIDCipher(
853         IN      PRTMP_ADAPTER           pAd,
854         IN      UCHAR                           Aid,
855         IN      PNDIS_802_11_KEY        pKey,
856         IN  UCHAR                       CipherAlg)
857 {
858         PUCHAR          pTxMic, pRxMic;
859         BOOLEAN         bKeyRSC, bAuthenticator; // indicate the receive SC set by KeyRSC value
860 //      UCHAR           CipherAlg;
861         UCHAR           i;
862         ULONG           WCIDAttri;
863         USHORT          offset;
864         UCHAR           KeyIdx, IVEIV[8];
865         UINT32          Value;
866
867         DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid));
868
869         // Bit 29 of Add-key KeyRSC
870         bKeyRSC            = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
871
872         // Bit 28 of Add-key Authenticator
873         bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
874         KeyIdx = (UCHAR)pKey->KeyIndex&0xff;
875
876         if (KeyIdx > 4)
877                 return;
878
879
880         if (pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg == CIPHER_TKIP)
881         {       if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
882                 {
883                         // for WPA-None Tx, Rx MIC is the same
884                         pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
885                         pRxMic = pTxMic;
886                 }
887                 else if (bAuthenticator == TRUE)
888                 {
889                         pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
890                         pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
891                 }
892                 else
893                 {
894                         pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
895                         pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
896                 }
897
898                 offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x10;
899                 for (i=0; i<8; )
900                 {
901                         Value = *(pTxMic+i);
902                         Value += (*(pTxMic+i+1)<<8);
903                         Value += (*(pTxMic+i+2)<<16);
904                         Value += (*(pTxMic+i+3)<<24);
905                         RTUSBWriteMACRegister(pAd, offset+i, Value);
906                         i+=4;
907                 }
908
909                 offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x18;
910                 for (i=0; i<8; )
911                 {
912                         Value = *(pRxMic+i);
913                         Value += (*(pRxMic+i+1)<<8);
914                         Value += (*(pRxMic+i+2)<<16);
915                         Value += (*(pRxMic+i+3)<<24);
916                         RTUSBWriteMACRegister(pAd, offset+i, Value);
917                         i+=4;
918                 }
919
920                 // Only Key lenth equal to TKIP key have these
921                 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxMic, pRxMic, 8);
922                 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.TxMic, pTxMic, 8);
923
924                 DBGPRINT(RT_DEBUG_TRACE,
925                                 ("      TxMIC  = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
926                                 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],
927                                 pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
928                 DBGPRINT(RT_DEBUG_TRACE,
929                                 ("      RxMIC  = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
930                                 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],
931                                 pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
932         }
933
934         // 2. Record Security Key.
935         pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen= (UCHAR)pKey->KeyLength;
936         NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
937
938         // 3. Check RxTsc. And used to init to ASIC IV.
939         if (bKeyRSC == TRUE)
940                 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, &pKey->KeyRSC, 6);
941         else
942                 NdisZeroMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, 6);
943
944         // 4. Init TxTsc to one based on WiFi WPA specs
945         pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[0] = 1;
946         pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[1] = 0;
947         pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[2] = 0;
948         pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[3] = 0;
949         pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[4] = 0;
950         pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[5] = 0;
951
952         CipherAlg = pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg;
953
954         offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE);
955         RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial,
956                                 ((pKey->KeyLength == LEN_TKIP_KEY) ? 16 : (USHORT)pKey->KeyLength));
957
958         offset = SHARED_KEY_TABLE_BASE + (KeyIdx * HW_KEY_ENTRY_SIZE);
959         RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, (USHORT)pKey->KeyLength);
960
961         offset = PAIRWISE_IVEIV_TABLE_BASE + (Aid * HW_IVEIV_ENTRY_SIZE);
962         NdisZeroMemory(IVEIV, 8);
963
964         // IV/EIV
965         if ((CipherAlg == CIPHER_TKIP) ||
966                 (CipherAlg == CIPHER_TKIP_NO_MIC) ||
967                 (CipherAlg == CIPHER_AES))
968         {
969                 IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
970         }
971         // default key idx needs to set.
972         // in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key.
973         else
974         {
975                 IVEIV[3] |= (KeyIdx<< 6);
976         }
977         RTUSBMultiWrite(pAd, (USHORT) offset, IVEIV, 8);
978
979         // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
980         if ((CipherAlg == CIPHER_TKIP) ||
981                 (CipherAlg == CIPHER_TKIP_NO_MIC) ||
982                 (CipherAlg == CIPHER_AES))
983         {
984                 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
985         }
986         else
987                 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
988
989         offset = MAC_WCID_ATTRIBUTE_BASE + (Aid* HW_WCID_ATTRI_SIZE);
990         RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
991         RTUSBReadMACRegister(pAd, offset, &Value);
992
993         DBGPRINT(RT_DEBUG_TRACE, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n",
994                         offset, WCIDAttri));
995
996         // pAddr
997         // Add Bssid mac address at linkup. not here.  check!
998         /*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE);
999         *for (i=0; i<MAC_ADDR_LEN; i++)
1000         {
1001                 RTMP_IO_WRITE8(pAd, offset+i, pKey->BSSID[i]);
1002         }
1003         */
1004
1005         DBGPRINT(RT_DEBUG_ERROR, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n",
1006                         CipherName[CipherAlg], pKey->KeyLength));
1007         DBGPRINT(RT_DEBUG_TRACE, ("Key [idx=%x] [KeyLen = %d]\n",
1008                         pKey->KeyIndex, pKey->KeyLength));
1009         for(i=0; i<pKey->KeyLength; i++)
1010                 DBGPRINT_RAW(RT_DEBUG_TRACE,(" %x:", pKey->KeyMaterial[i]));
1011         DBGPRINT(RT_DEBUG_TRACE,("       \n"));
1012 }
1013 #endif // CONFIG_STA_SUPPORT //
1014
1015 /*
1016 ========================================================================
1017 Routine Description:
1018     Get a received packet.
1019
1020 Arguments:
1021         pAd                                     device control block
1022         pSaveRxD                        receive descriptor information
1023         *pbReschedule           need reschedule flag
1024         *pRxPending                     pending received packet flag
1025
1026 Return Value:
1027     the recieved packet
1028
1029 Note:
1030 ========================================================================
1031 */
1032 #define RT2870_RXDMALEN_FIELD_SIZE                      4
1033 PNDIS_PACKET GetPacketFromRxRing(
1034         IN              PRTMP_ADAPTER           pAd,
1035         OUT             PRT28XX_RXD_STRUC       pSaveRxD,
1036         OUT             BOOLEAN                         *pbReschedule,
1037         IN OUT  UINT32                          *pRxPending)
1038 {
1039         PRX_CONTEXT             pRxContext;
1040         PNDIS_PACKET    pSkb;
1041         PUCHAR                  pData;
1042         ULONG                   ThisFrameLen;
1043         ULONG                   RxBufferLength;
1044         PRXWI_STRUC             pRxWI;
1045
1046         pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
1047         if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
1048                 return NULL;
1049
1050         RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
1051         if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
1052         {
1053                 goto label_null;
1054         }
1055
1056         pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
1057         // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
1058         ThisFrameLen = *pData + (*(pData+1)<<8);
1059     if (ThisFrameLen == 0)
1060         {
1061                 DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
1062                                                                 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
1063                 goto label_null;
1064         }
1065         if ((ThisFrameLen&0x3) != 0)
1066         {
1067                 DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
1068                                                                 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
1069                 goto label_null;
1070         }
1071
1072         if ((ThisFrameLen + 8)> RxBufferLength) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
1073         {
1074                 DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
1075                                                 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));
1076
1077                 // error frame. finish this loop
1078                 goto label_null;
1079         }
1080
1081         // skip USB frame length field
1082         pData += RT2870_RXDMALEN_FIELD_SIZE;
1083         pRxWI = (PRXWI_STRUC)pData;
1084 #ifdef RT_BIG_ENDIAN
1085         RTMPWIEndianChange(pData, TYPE_RXWI);
1086 #endif // RT_BIG_ENDIAN //
1087         if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
1088         {
1089                 DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
1090                                                                         __func__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
1091                 goto label_null;
1092         }
1093 #ifdef RT_BIG_ENDIAN
1094         RTMPWIEndianChange(pData, TYPE_RXWI);
1095 #endif // RT_BIG_ENDIAN //
1096
1097         // allocate a rx packet
1098         pSkb = dev_alloc_skb(ThisFrameLen);
1099         if (pSkb == NULL)
1100         {
1101                 DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __func__));
1102                 goto label_null;
1103         }
1104
1105         // copy the rx packet
1106         memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
1107         RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
1108         RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
1109
1110         // copy RxD
1111         *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
1112 #ifdef RT_BIG_ENDIAN
1113         RTMPDescriptorEndianChange((PUCHAR)pSaveRxD, TYPE_RXINFO);
1114 #endif // RT_BIG_ENDIAN //
1115
1116         // update next packet read position.
1117         pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
1118
1119         return pSkb;
1120
1121 label_null:
1122
1123         return NULL;
1124 }
1125
1126
1127 /*
1128 ========================================================================
1129 Routine Description:
1130     Handle received packets.
1131
1132 Arguments:
1133         data                            - URB information pointer
1134
1135 Return Value:
1136     None
1137
1138 Note:
1139 ========================================================================
1140 */
1141 static void rx_done_tasklet(unsigned long data)
1142 {
1143         purbb_t                         pUrb;
1144         PRX_CONTEXT                     pRxContext;
1145         PRTMP_ADAPTER           pAd;
1146         NTSTATUS                        Status;
1147         unsigned int            IrqFlags;
1148
1149         pUrb            = (purbb_t)data;
1150         pRxContext      = (PRX_CONTEXT)pUrb->context;
1151         pAd             = pRxContext->pAd;
1152         Status = pUrb->status;
1153
1154
1155         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1156         pRxContext->InUse = FALSE;
1157         pRxContext->IRPPending = FALSE;
1158         pRxContext->BulkInOffset += pUrb->actual_length;
1159         //NdisInterlockedDecrement(&pAd->PendingRx);
1160         pAd->PendingRx--;
1161
1162         if (Status == USB_ST_NOERROR)
1163         {
1164                 pAd->BulkInComplete++;
1165                 pAd->NextRxBulkInPosition = 0;
1166                 if (pRxContext->BulkInOffset)   // As jan's comment, it may bulk-in success but size is zero.
1167                 {
1168                         pRxContext->Readable = TRUE;
1169                         INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1170                 }
1171                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1172         }
1173         else     // STATUS_OTHER
1174         {
1175                 pAd->BulkInCompleteFail++;
1176                 // Still read this packet although it may comtain wrong bytes.
1177                 pRxContext->Readable = FALSE;
1178                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1179
1180                 // Parsing all packets. because after reset, the index will reset to all zero.
1181                 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1182                                                                         fRTMP_ADAPTER_BULKIN_RESET |
1183                                                                         fRTMP_ADAPTER_HALT_IN_PROGRESS |
1184                                                                         fRTMP_ADAPTER_NIC_NOT_EXIST))))
1185                 {
1186
1187                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
1188                                                         Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
1189
1190                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1191                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
1192                 }
1193         }
1194
1195         ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1196
1197 #ifdef RALINK_ATE
1198         if (ATE_ON(pAd))
1199     {
1200                 // If the driver is in ATE mode and Rx frame is set into here.
1201                 if (pAd->ContinBulkIn == TRUE)
1202                 {
1203                         RTUSBBulkReceive(pAd);
1204                 }
1205         }
1206         else
1207 #endif // RALINK_ATE //
1208         RTUSBBulkReceive(pAd);
1209
1210         return;
1211
1212 }
1213
1214
1215 static void rt2870_mgmt_dma_done_tasklet(unsigned long data)
1216 {
1217         PRTMP_ADAPTER   pAd;
1218         PTX_CONTEXT             pMLMEContext;
1219         int                             index;
1220         PNDIS_PACKET    pPacket;
1221         purbb_t                 pUrb;
1222         NTSTATUS                Status;
1223         unsigned long   IrqFlags;
1224
1225
1226         pUrb                    = (purbb_t)data;
1227         pMLMEContext    = (PTX_CONTEXT)pUrb->context;
1228         pAd                     = pMLMEContext->pAd;
1229         Status                  = pUrb->status;
1230         index                   = pMLMEContext->SelfIdx;
1231
1232         ASSERT((pAd->MgmtRing.TxDmaIdx == index));
1233
1234         RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1235
1236
1237         if (Status != USB_ST_NOERROR)
1238         {
1239                 //Bulk-Out fail status handle
1240                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1241                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1242                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1243                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1244                 {
1245                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1246                         // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
1247                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1248                         pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1249                 }
1250         }
1251
1252         pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1253         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1254
1255         RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1256         // Reset MLME context flags
1257         pMLMEContext->IRPPending = FALSE;
1258         pMLMEContext->InUse = FALSE;
1259         pMLMEContext->bWaitingBulkOut = FALSE;
1260         pMLMEContext->BulkOutSize = 0;
1261
1262         pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
1263         pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
1264
1265         // Increase MgmtRing Index
1266         INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
1267         pAd->MgmtRing.TxSwFreeIdx++;
1268         RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1269
1270         // No-matter success or fail, we free the mgmt packet.
1271         if (pPacket)
1272                 RTMPFreeNdisPacket(pAd, pPacket);
1273
1274         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1275                                                                 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1276                                                                 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1277         {
1278                 // do nothing and return directly.
1279         }
1280         else
1281         {
1282                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) &&
1283                         ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
1284                 {       // For Mgmt Bulk-Out failed, ignore it now.
1285                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1286                 }
1287                 else
1288                 {
1289
1290                         // Always call Bulk routine, even reset bulk.
1291                         // The protectioon of rest bulk should be in BulkOut routine
1292                         if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
1293                         {
1294                                 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
1295                         }
1296                                 RTUSBKickBulkOut(pAd);
1297                         }
1298                 }
1299
1300 }
1301
1302
1303 static void rt2870_hcca_dma_done_tasklet(unsigned long data)
1304 {
1305         PRTMP_ADAPTER           pAd;
1306         PHT_TX_CONTEXT          pHTTXContext;
1307         UCHAR                           BulkOutPipeId = 4;
1308         purbb_t                         pUrb;
1309
1310
1311         DBGPRINT_RAW(RT_DEBUG_ERROR, ("--->hcca_dma_done_tasklet\n"));
1312
1313
1314         pUrb                    = (purbb_t)data;
1315         pHTTXContext    = (PHT_TX_CONTEXT)pUrb->context;
1316         pAd                             = pHTTXContext->pAd;
1317
1318         rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1319
1320         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1321                                                                 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1322                                                                 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1323         {
1324                 // do nothing and return directly.
1325         }
1326         else
1327         {
1328                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1329                 {
1330                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1331                 }
1332                 else
1333                 {       pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1334                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1335                                 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1336                                 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1337                                 (pHTTXContext->bCurWriting == FALSE))
1338                         {
1339                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1340                         }
1341
1342                         RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
1343                         RTUSBKickBulkOut(pAd);
1344                 }
1345         }
1346
1347         DBGPRINT_RAW(RT_DEBUG_ERROR, ("<---hcca_dma_done_tasklet\n"));
1348
1349                 return;
1350 }
1351
1352
1353 static void rt2870_ac3_dma_done_tasklet(unsigned long data)
1354 {
1355         PRTMP_ADAPTER           pAd;
1356         PHT_TX_CONTEXT          pHTTXContext;
1357         UCHAR                           BulkOutPipeId = 3;
1358         purbb_t                         pUrb;
1359
1360
1361         pUrb                    = (purbb_t)data;
1362         pHTTXContext    = (PHT_TX_CONTEXT)pUrb->context;
1363         pAd                             = pHTTXContext->pAd;
1364
1365         rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1366
1367         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1368                                                                 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1369                                                                 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1370         {
1371                 // do nothing and return directly.
1372         }
1373         else
1374         {
1375                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1376                 {
1377                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1378                 }
1379                 else
1380                 {       pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1381                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1382                                 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1383                                 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1384                                 (pHTTXContext->bCurWriting == FALSE))
1385                         {
1386                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1387                         }
1388
1389                         RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3);
1390                         RTUSBKickBulkOut(pAd);
1391                 }
1392         }
1393
1394
1395                 return;
1396 }
1397
1398
1399 static void rt2870_ac2_dma_done_tasklet(unsigned long data)
1400 {
1401         PRTMP_ADAPTER           pAd;
1402         PHT_TX_CONTEXT          pHTTXContext;
1403         UCHAR                           BulkOutPipeId = 2;
1404         purbb_t                         pUrb;
1405
1406
1407         pUrb                    = (purbb_t)data;
1408         pHTTXContext    = (PHT_TX_CONTEXT)pUrb->context;
1409         pAd                             = pHTTXContext->pAd;
1410
1411         rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1412
1413         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1414                                                                 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1415                                                                 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1416         {
1417                 // do nothing and return directly.
1418         }
1419         else
1420         {
1421                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1422                 {
1423                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1424                 }
1425                 else
1426                 {       pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1427                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1428                                 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1429                                 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1430                                 (pHTTXContext->bCurWriting == FALSE))
1431                         {
1432                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1433                         }
1434
1435                         RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2);
1436                         RTUSBKickBulkOut(pAd);
1437                 }
1438         }
1439
1440                 return;
1441 }
1442
1443
1444 static void rt2870_ac1_dma_done_tasklet(unsigned long data)
1445 {
1446         PRTMP_ADAPTER           pAd;
1447         PHT_TX_CONTEXT          pHTTXContext;
1448         UCHAR                           BulkOutPipeId = 1;
1449         purbb_t                         pUrb;
1450
1451
1452         pUrb                    = (purbb_t)data;
1453         pHTTXContext    = (PHT_TX_CONTEXT)pUrb->context;
1454         pAd                             = pHTTXContext->pAd;
1455
1456         rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1457
1458         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1459                                                                 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1460                                                                 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1461         {
1462                 // do nothing and return directly.
1463         }
1464         else
1465         {
1466                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1467                 {
1468                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1469                 }
1470                 else
1471                 {       pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1472                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1473                                 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1474                                 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1475                                 (pHTTXContext->bCurWriting == FALSE))
1476                         {
1477                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1478                         }
1479
1480                         RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
1481                         RTUSBKickBulkOut(pAd);
1482                 }
1483         }
1484
1485
1486         return;
1487 }
1488
1489
1490 static void rt2870_ac0_dma_done_tasklet(unsigned long data)
1491 {
1492         PRTMP_ADAPTER           pAd;
1493         PHT_TX_CONTEXT          pHTTXContext;
1494         UCHAR                           BulkOutPipeId = 0;
1495         purbb_t                         pUrb;
1496
1497
1498         pUrb                    = (purbb_t)data;
1499         pHTTXContext    = (PHT_TX_CONTEXT)pUrb->context;
1500         pAd                             = pHTTXContext->pAd;
1501
1502         rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1503
1504         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1505                                                                 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1506                                                                 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1507         {
1508                 // do nothing and return directly.
1509         }
1510         else
1511         {
1512                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1513                 {
1514                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1515                 }
1516                 else
1517                 {       pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1518                         if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1519                                 /*  ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1520                                 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1521                                 (pHTTXContext->bCurWriting == FALSE))
1522                         {
1523                                 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1524                         }
1525
1526                         RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
1527                         RTUSBKickBulkOut(pAd);
1528                 }
1529         }
1530
1531
1532         return;
1533
1534 }
1535
1536
1537 static void rt2870_null_frame_complete_tasklet(unsigned long data)
1538 {
1539         PRTMP_ADAPTER   pAd;
1540         PTX_CONTEXT             pNullContext;
1541         purbb_t                 pUrb;
1542         NTSTATUS                Status;
1543         unsigned long   irqFlag;
1544
1545
1546         pUrb                    = (purbb_t)data;
1547         pNullContext    = (PTX_CONTEXT)pUrb->context;
1548         pAd                     = pNullContext->pAd;
1549         Status                  = pUrb->status;
1550
1551         // Reset Null frame context flags
1552         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
1553         pNullContext->IRPPending        = FALSE;
1554         pNullContext->InUse             = FALSE;
1555         pAd->BulkOutPending[0] = FALSE;
1556         pAd->watchDogTxPendingCnt[0] = 0;
1557
1558         if (Status == USB_ST_NOERROR)
1559         {
1560                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1561
1562                 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1563         }
1564         else    // STATUS_OTHER
1565         {
1566                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1567                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1568                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1569                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1570                 {
1571                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
1572                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1573                         pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1574                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1575                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1576                 }
1577                 else
1578                 {
1579                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1580                 }
1581         }
1582
1583         // Always call Bulk routine, even reset bulk.
1584         // The protectioon of rest bulk should be in BulkOut routine
1585         RTUSBKickBulkOut(pAd);
1586
1587 }
1588
1589
1590 static void rt2870_rts_frame_complete_tasklet(unsigned long data)
1591 {
1592         PRTMP_ADAPTER   pAd;
1593         PTX_CONTEXT             pRTSContext;
1594         purbb_t                 pUrb;
1595         NTSTATUS                Status;
1596         unsigned long   irqFlag;
1597
1598
1599         pUrb            = (purbb_t)data;
1600         pRTSContext     = (PTX_CONTEXT)pUrb->context;
1601         pAd                     = pRTSContext->pAd;
1602         Status          = pUrb->status;
1603
1604         // Reset RTS frame context flags
1605         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
1606         pRTSContext->IRPPending = FALSE;
1607         pRTSContext->InUse              = FALSE;
1608
1609         if (Status == USB_ST_NOERROR)
1610         {
1611                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1612                 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1613         }
1614         else    // STATUS_OTHER
1615         {
1616                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1617                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1618                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1619                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1620                 {
1621                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
1622                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1623                         pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1624                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1625                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1626                 }
1627                 else
1628                 {
1629                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1630                 }
1631         }
1632
1633         RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
1634         pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
1635         RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
1636
1637         // Always call Bulk routine, even reset bulk.
1638         // The protectioon of rest bulk should be in BulkOut routine
1639         RTUSBKickBulkOut(pAd);
1640
1641 }
1642
1643
1644 static void rt2870_pspoll_frame_complete_tasklet(unsigned long data)
1645 {
1646         PRTMP_ADAPTER   pAd;
1647         PTX_CONTEXT             pPsPollContext;
1648         purbb_t                 pUrb;
1649         NTSTATUS                Status;
1650
1651
1652         pUrb                    = (purbb_t)data;
1653         pPsPollContext  = (PTX_CONTEXT)pUrb->context;
1654         pAd                             = pPsPollContext->pAd;
1655         Status                  = pUrb->status;
1656
1657         // Reset PsPoll context flags
1658         pPsPollContext->IRPPending      = FALSE;
1659         pPsPollContext->InUse           = FALSE;
1660         pAd->watchDogTxPendingCnt[0] = 0;
1661
1662         if (Status == USB_ST_NOERROR)
1663         {
1664                 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1665         }
1666         else // STATUS_OTHER
1667         {
1668                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1669                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1670                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1671                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1672                 {
1673                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
1674                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1675                         pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1676                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1677                 }
1678         }
1679
1680         RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
1681         pAd->BulkOutPending[0] = FALSE;
1682         RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
1683
1684         // Always call Bulk routine, even reset bulk.
1685         // The protectioon of rest bulk should be in BulkOut routine
1686         RTUSBKickBulkOut(pAd);
1687
1688 }
1689
1690
1691 static void rt2870_dataout_complete_tasklet(unsigned long data)
1692 {
1693         PRTMP_ADAPTER           pAd;
1694         purbb_t                         pUrb;
1695         POS_COOKIE                      pObj;
1696         PHT_TX_CONTEXT          pHTTXContext;
1697         UCHAR                           BulkOutPipeId;
1698         NTSTATUS                        Status;
1699         unsigned long           IrqFlags;
1700
1701
1702         pUrb                    = (purbb_t)data;
1703         pHTTXContext    = (PHT_TX_CONTEXT)pUrb->context;
1704         pAd                             = pHTTXContext->pAd;
1705         pObj                    = (POS_COOKIE) pAd->OS_Cookie;
1706         Status                  = pUrb->status;
1707
1708         // Store BulkOut PipeId
1709         BulkOutPipeId = pHTTXContext->BulkOutPipeId;
1710         pAd->BulkOutDataOneSecCount++;
1711
1712         //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
1713         //              pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
1714
1715         RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1716         pAd->BulkOutPending[BulkOutPipeId] = FALSE;
1717         pHTTXContext->IRPPending = FALSE;
1718         pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
1719
1720         if (Status == USB_ST_NOERROR)
1721         {
1722                 pAd->BulkOutComplete++;
1723
1724                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1725
1726                 pAd->Counters8023.GoodTransmits++;
1727                 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1728                 FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
1729                 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1730
1731
1732         }
1733         else    // STATUS_OTHER
1734         {
1735                 PUCHAR  pBuf;
1736
1737                 pAd->BulkOutCompleteOther++;
1738
1739                 pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
1740
1741                 if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1742                                                                         fRTMP_ADAPTER_HALT_IN_PROGRESS |
1743                                                                         fRTMP_ADAPTER_NIC_NOT_EXIST |
1744                                                                         fRTMP_ADAPTER_BULKOUT_RESET)))
1745                 {
1746                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1747                         pAd->bulkResetPipeid = BulkOutPipeId;
1748                         pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
1749                 }
1750                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1751
1752                 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
1753                 DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
1754                 DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
1755                 //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
1756
1757         }
1758
1759         //
1760         // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
1761         // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
1762         //
1763         //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1764         if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
1765                 (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
1766                 !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
1767         {
1768                 // Indicate There is data avaliable
1769                 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
1770         }
1771         //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1772
1773         // Always call Bulk routine, even reset bulk.
1774         // The protection of rest bulk should be in BulkOut routine
1775         RTUSBKickBulkOut(pAd);
1776 }
1777
1778 /* End of 2870_rtmp_init.c */