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