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