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