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