2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 06-25-2004 created
40 #include "../rt_config.h"
41 // Match total 6 bulkout endpoint to corresponding queue.
42 UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT};
44 //static BOOLEAN SingleBulkOut = FALSE;
46 void RTUSB_FILL_BULK_URB (struct urb *pUrb,
47 struct usb_device *pUsb_Dev,
48 unsigned int bulkpipe,
51 usb_complete_t Complete,
55 usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
61 IN PTX_CONTEXT pTxContext,
62 IN UCHAR BulkOutPipeId,
63 IN usb_complete_t Func)
67 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
69 pUrb = pTxContext->pUrb;
72 // Store BulkOut PipeId
73 pTxContext->BulkOutPipeId = BulkOutPipeId;
75 if (pTxContext->bAggregatible)
77 pSrc = &pTxContext->TransferBuffer->Aggregation[2];
81 pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
85 //Initialize a tx bulk urb
86 RTUSB_FILL_BULK_URB(pUrb,
88 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
90 pTxContext->BulkOutSize,
94 if (pTxContext->bAggregatible)
95 pUrb->transfer_dma = (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
97 pUrb->transfer_dma = pTxContext->data_dma;
99 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
103 VOID RTUSBInitHTTxDesc(
104 IN PRTMP_ADAPTER pAd,
105 IN PHT_TX_CONTEXT pTxContext,
106 IN UCHAR BulkOutPipeId,
107 IN ULONG BulkOutSize,
108 IN usb_complete_t Func)
112 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
114 pUrb = pTxContext->pUrb;
117 // Store BulkOut PipeId
118 pTxContext->BulkOutPipeId = BulkOutPipeId;
120 pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
123 //Initialize a tx bulk urb
124 RTUSB_FILL_BULK_URB(pUrb,
126 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
132 pUrb->transfer_dma = (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
133 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
137 VOID RTUSBInitRxDesc(
138 IN PRTMP_ADAPTER pAd,
139 IN PRX_CONTEXT pRxContext)
142 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
146 pUrb = pRxContext->pUrb;
149 if ( pAd->BulkInMaxPacketSize == 64)
152 RX_bulk_size = MAX_RXBULK_SIZE;
154 //Initialize a rx bulk urb
155 RTUSB_FILL_BULK_URB(pUrb,
157 usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
158 &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
159 RX_bulk_size - (pAd->NextRxBulkInPosition),
160 (usb_complete_t)RTUSBBulkRxComplete,
163 pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
164 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
170 ========================================================================
180 ========================================================================
183 #define BULK_OUT_LOCK(pLock, IrqFlags) \
184 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
185 RTMP_IRQ_LOCK((pLock), IrqFlags);
187 #define BULK_OUT_UNLOCK(pLock, IrqFlags) \
188 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
189 RTMP_IRQ_UNLOCK((pLock), IrqFlags);
192 VOID RTUSBBulkOutDataPacket(
193 IN PRTMP_ADAPTER pAd,
194 IN UCHAR BulkOutPipeId,
198 PHT_TX_CONTEXT pHTTXContext;
201 PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL;
203 ULONG TmpBulkEndPos, ThisBulkSize;
204 unsigned long IrqFlags = 0, IrqFlags2 = 0;
205 PUCHAR pWirelessPkt, pAppendant;
206 BOOLEAN bTxQLastRound = FALSE;
207 UCHAR allzero[4]= {0x0,0x0,0x0,0x0};
209 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
210 if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
212 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
215 pAd->BulkOutPending[BulkOutPipeId] = TRUE;
217 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
220 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
221 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
224 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
227 pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
229 BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
230 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
231 || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
233 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
235 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
236 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
239 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
240 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
242 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
247 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
248 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
250 //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
251 // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
252 // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
253 pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
255 TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
256 pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
258 if ((pHTTXContext->bCopySavePad == TRUE))
260 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
262 DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n",
263 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
264 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
266 NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
267 pHTTXContext->bCopySavePad = FALSE;
268 if (pAd->bForcePrintTX == TRUE)
269 DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
274 pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
275 pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
277 if (pAd->bForcePrintTX == TRUE)
278 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU));
280 // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
281 //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))
282 if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK))
284 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
286 // Limit BulkOut size to about 4k bytes.
287 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
290 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
292 // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
293 // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
294 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
301 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
302 { // Limit BulkOut size to about 24k bytes.
303 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
306 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
307 { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
308 // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
309 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
314 if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
316 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
320 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
321 if (pTxInfo->QSEL != FIFO_EDCA)
323 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL);
324 printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
325 hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
328 if (pTxInfo->USBDMATxPktLen <= 8)
330 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
331 DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
332 pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
334 DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n",
335 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
336 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
338 pAd->bForcePrintTX = TRUE;
339 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
340 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
341 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
342 //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
346 // Increase Total transmit byte counter
347 pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount;
348 pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount;
350 pLastTxInfo = pTxInfo;
352 // Make sure we use EDCA QUEUE.
353 pTxInfo->QSEL = FIFO_EDCA; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
354 ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
355 TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
357 if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
358 pTxInfo->USBDMANextVLD = 1;
360 if (pTxInfo->SwUseLastRound == 1)
362 if (pHTTXContext->CurWritePosition == 8)
363 pTxInfo->USBDMANextVLD = 0;
364 pTxInfo->SwUseLastRound = 0;
366 bTxQLastRound = TRUE;
367 pHTTXContext->ENextBulkOutPosition = 8;
373 // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
376 pLastTxInfo->USBDMANextVLD = 0;
380 We need to copy SavedPad when following condition matched!
381 1. Not the last round of the TxQueue and
382 2. any match of following cases:
383 (1). The End Position of this bulk out is reach to the Currenct Write position and
384 the TxInfo and related header already write to the CurWritePosition.
385 =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
387 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
388 =>(ENextBulkOutPosition != CurWritePosition)
390 if ((bTxQLastRound == FALSE) &&
391 (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
392 (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
395 NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
396 pHTTXContext->bCopySavePad = TRUE;
397 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
399 PUCHAR pBuf = &pHTTXContext->SavedPad[0];
400 DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
401 pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
402 pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
404 pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
405 DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7]));
407 //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
410 if (pAd->bForcePrintTX == TRUE)
411 DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
412 //DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));
414 // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
415 pAppendant = &pWirelessPkt[TmpBulkEndPos];
416 NdisZeroMemory(pAppendant, 8);
418 pHTTXContext->LastOne = TRUE;
419 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
421 pHTTXContext->BulkOutSize = ThisBulkSize;
423 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
424 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
426 // Init Tx context descriptor
427 RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
429 pUrb = pHTTXContext->pUrb;
430 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
432 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
434 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
435 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
436 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
437 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
442 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
443 pHTTXContext->IRPPending = TRUE;
444 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
450 VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
452 PHT_TX_CONTEXT pHTTXContext;
458 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
459 pAd = pHTTXContext->pAd;
460 pObj = (POS_COOKIE) pAd->OS_Cookie;
462 // Store BulkOut PipeId
463 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
464 pAd->BulkOutDataOneSecCount++;
466 switch (BulkOutPipeId)
469 pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
470 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
473 pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
474 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
477 pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
478 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
481 pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
482 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
485 pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
486 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
493 ========================================================================
501 Note: NULL frame use BulkOutPipeId = 0
503 ========================================================================
505 VOID RTUSBBulkOutNullFrame(
506 IN PRTMP_ADAPTER pAd)
508 PTX_CONTEXT pNullContext = &(pAd->NullContext);
511 unsigned long IrqFlags;
513 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
514 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
516 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
519 pAd->BulkOutPending[0] = TRUE;
520 pAd->watchDogTxPendingCnt[0] = 1;
521 pNullContext->IRPPending = TRUE;
522 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
524 // Increase Total transmit byte counter
525 pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
528 // Clear Null frame bulk flag
529 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
531 // Init Tx context descriptor
532 RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
534 pUrb = pNullContext->pUrb;
535 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
537 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
538 pAd->BulkOutPending[0] = FALSE;
539 pAd->watchDogTxPendingCnt[0] = 0;
540 pNullContext->IRPPending = FALSE;
541 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
543 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
549 // NULL frame use BulkOutPipeId = 0
550 VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
553 PTX_CONTEXT pNullContext;
558 pNullContext = (PTX_CONTEXT)pUrb->context;
559 pAd = pNullContext->pAd;
560 Status = pUrb->status;
562 pObj = (POS_COOKIE) pAd->OS_Cookie;
563 pObj->null_frame_complete_task.data = (unsigned long)pUrb;
564 tasklet_hi_schedule(&pObj->null_frame_complete_task);
568 ========================================================================
576 Note: MLME use BulkOutPipeId = 0
578 ========================================================================
580 VOID RTUSBBulkOutMLMEPacket(
581 IN PRTMP_ADAPTER pAd,
584 PTX_CONTEXT pMLMEContext;
587 unsigned long IrqFlags;
589 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
590 pUrb = pMLMEContext->pUrb;
592 if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
593 (pMLMEContext->InUse == FALSE) ||
594 (pMLMEContext->bWaitingBulkOut == FALSE))
598 // Clear MLME bulk flag
599 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
605 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
606 if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
608 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
612 pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
613 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
614 pMLMEContext->IRPPending = TRUE;
615 pMLMEContext->bWaitingBulkOut = FALSE;
616 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
618 // Increase Total transmit byte counter
619 pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
621 // Clear MLME bulk flag
622 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
624 // Init Tx context descriptor
625 RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
627 //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
628 pUrb->transfer_dma = 0;
629 pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
631 pUrb = pMLMEContext->pUrb;
632 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
634 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
635 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
636 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
637 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
638 pMLMEContext->IRPPending = FALSE;
639 pMLMEContext->bWaitingBulkOut = TRUE;
640 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
645 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
646 // printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
650 VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
652 PTX_CONTEXT pMLMEContext;
658 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
659 pMLMEContext = (PTX_CONTEXT)pUrb->context;
660 pAd = pMLMEContext->pAd;
661 pObj = (POS_COOKIE)pAd->OS_Cookie;
662 Status = pUrb->status;
663 index = pMLMEContext->SelfIdx;
665 pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
666 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
671 ========================================================================
679 Note: PsPoll use BulkOutPipeId = 0
681 ========================================================================
683 VOID RTUSBBulkOutPsPoll(
684 IN PRTMP_ADAPTER pAd)
686 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
689 unsigned long IrqFlags;
691 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
692 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
694 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
697 pAd->BulkOutPending[0] = TRUE;
698 pAd->watchDogTxPendingCnt[0] = 1;
699 pPsPollContext->IRPPending = TRUE;
700 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
703 // Clear PS-Poll bulk flag
704 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
706 // Init Tx context descriptor
707 RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
709 pUrb = pPsPollContext->pUrb;
710 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
712 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
713 pAd->BulkOutPending[0] = FALSE;
714 pAd->watchDogTxPendingCnt[0] = 0;
715 pPsPollContext->IRPPending = FALSE;
716 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
718 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
724 // PS-Poll frame use BulkOutPipeId = 0
725 VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
728 PTX_CONTEXT pPsPollContext;
733 pPsPollContext= (PTX_CONTEXT)pUrb->context;
734 pAd = pPsPollContext->pAd;
735 Status = pUrb->status;
737 pObj = (POS_COOKIE) pAd->OS_Cookie;
738 pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
739 tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
742 VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
744 PRX_CONTEXT pRxContext;
747 unsigned long IrqFlags;
749 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
750 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
751 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
753 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
756 pRxContext->InUse = TRUE;
757 pRxContext->IRPPending = TRUE;
760 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
762 // Init Rx context descriptor
763 NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
764 RTUSBInitRxDesc(pAd, pRxContext);
766 pUrb = pRxContext->pUrb;
767 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
770 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
771 pRxContext->InUse = FALSE;
772 pRxContext->IRPPending = FALSE;
775 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
776 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
780 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
781 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
787 ========================================================================
790 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
791 to USB. It checks if an Rx Descriptor is available and passes the
792 the coresponding buffer to be filled. If no descriptor is available
793 fails the request. When setting the completion routine we pass our
794 Adapter Object as Context.
799 TRUE found matched tuple cache
800 FALSE no matched found
804 ========================================================================
806 #define fRTMP_ADAPTER_NEED_STOP_RX \
807 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
808 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
809 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
811 #define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
812 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
813 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
814 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
816 VOID RTUSBBulkReceive(
817 IN PRTMP_ADAPTER pAd)
819 PRX_CONTEXT pRxContext;
820 unsigned long IrqFlags;
824 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
830 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
831 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
832 if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
833 (pRxContext->bRxHandling == FALSE))
835 pRxContext->bRxHandling = TRUE;
836 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
838 // read RxContext, Since not
839 STARxDoneInterruptHandle(pAd, TRUE);
841 // Finish to handle this bulkIn buffer.
842 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
843 pRxContext->BulkInOffset = 0;
844 pRxContext->Readable = FALSE;
845 pRxContext->bRxHandling = FALSE;
846 pAd->ReadPosition = 0;
847 pAd->TransferBufferLength = 0;
848 INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
849 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
854 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
859 if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
866 ========================================================================
869 This routine process Rx Irp and call rx complete function.
872 DeviceObject Pointer to the device object for next lower
873 device. DeviceObject passed in here belongs to
874 the next lower driver in the stack because we
875 were invoked via IoCallDriver in USB_RxPacket
876 AND it is not OUR device object
877 Irp Ptr to completed IRP
878 Context Ptr to our Adapter object (context specified
879 in IoSetCompletionRoutine
882 Always returns STATUS_MORE_PROCESSING_REQUIRED
885 Always returns STATUS_MORE_PROCESSING_REQUIRED
886 ========================================================================
888 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
890 // use a receive tasklet to handle received packets;
891 // or sometimes hardware IRQ will be disabled here, so we can not
892 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
893 PRX_CONTEXT pRxContext;
898 pRxContext = (PRX_CONTEXT)pUrb->context;
899 pAd = pRxContext->pAd;
900 pObj = (POS_COOKIE) pAd->OS_Cookie;
902 pObj->rx_done_task.data = (unsigned long)pUrb;
903 tasklet_hi_schedule(&pObj->rx_done_task);
910 ========================================================================
920 ========================================================================
922 VOID RTUSBKickBulkOut(
923 IN PRTMP_ADAPTER pAd)
925 // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
926 if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
929 // 2. PS-Poll frame is next
930 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
932 RTUSBBulkOutPsPoll(pAd);
935 // 5. Mlme frame is next
936 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
937 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
939 RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
942 // 6. Data frame normal is next
943 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
945 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
946 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
949 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
952 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
954 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
955 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
958 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
961 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
963 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
964 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
967 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
970 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
972 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
973 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
976 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
980 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
981 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5))
983 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
984 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
991 // 7. Null frame is the last
992 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
994 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
996 RTUSBBulkOutNullFrame(pAd);
1000 // 8. No data avaliable
1009 ========================================================================
1011 Routine Description:
1012 Call from Reset action after BulkOut failed.
1019 ========================================================================
1021 VOID RTUSBCleanUpDataBulkOutQueue(
1022 IN PRTMP_ADAPTER pAd)
1025 PHT_TX_CONTEXT pTxContext;
1027 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1029 for (Idx = 0; Idx < 4; Idx++)
1031 pTxContext = &pAd->TxContext[Idx];
1033 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1034 pTxContext->LastOne = FALSE;
1035 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1036 pAd->BulkOutPending[Idx] = FALSE;
1037 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1040 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1044 ========================================================================
1046 Routine Description:
1054 ========================================================================
1056 VOID RTUSBCleanUpMLMEBulkOutQueue(
1057 IN PRTMP_ADAPTER pAd)
1059 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
1060 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1065 ========================================================================
1067 Routine Description:
1076 ========================================================================
1078 VOID RTUSBCancelPendingIRPs(
1079 IN PRTMP_ADAPTER pAd)
1081 RTUSBCancelPendingBulkInIRP(pAd);
1082 RTUSBCancelPendingBulkOutIRP(pAd);
1086 ========================================================================
1088 Routine Description:
1096 ========================================================================
1098 VOID RTUSBCancelPendingBulkInIRP(
1099 IN PRTMP_ADAPTER pAd)
1101 PRX_CONTEXT pRxContext;
1104 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
1105 for ( i = 0; i < (RX_RING_SIZE); i++)
1107 pRxContext = &(pAd->RxContext[i]);
1108 if(pRxContext->IRPPending == TRUE)
1110 RTUSB_UNLINK_URB(pRxContext->pUrb);
1111 pRxContext->IRPPending = FALSE;
1112 pRxContext->InUse = FALSE;
1113 //NdisInterlockedDecrement(&pAd->PendingRx);
1117 DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1122 ========================================================================
1124 Routine Description:
1132 ========================================================================
1134 VOID RTUSBCancelPendingBulkOutIRP(
1135 IN PRTMP_ADAPTER pAd)
1137 PHT_TX_CONTEXT pHTTXContext;
1138 PTX_CONTEXT pMLMEContext;
1139 PTX_CONTEXT pBeaconContext;
1140 PTX_CONTEXT pNullContext;
1141 PTX_CONTEXT pPsPollContext;
1142 PTX_CONTEXT pRTSContext;
1144 // unsigned int IrqFlags;
1145 // NDIS_SPIN_LOCK *pLock;
1146 // BOOLEAN *pPending;
1149 // pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
1150 // pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
1152 for (Idx = 0; Idx < 4; Idx++)
1154 pHTTXContext = &(pAd->TxContext[Idx]);
1156 if (pHTTXContext->IRPPending == TRUE)
1159 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1160 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1161 // when the last IRP on the list has been cancelled; that's how we exit this loop
1164 RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1166 // Sleep 200 microseconds to give cancellation time to work
1170 pAd->BulkOutPending[Idx] = FALSE;
1173 //RTMP_IRQ_LOCK(pLock, IrqFlags);
1174 for (i = 0; i < MGMT_RING_SIZE; i++)
1176 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
1177 if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
1180 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1181 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1182 // when the last IRP on the list has been cancelled; that's how we exit this loop
1185 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1186 pMLMEContext->IRPPending = FALSE;
1188 // Sleep 200 microsecs to give cancellation time to work
1192 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1193 //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
1196 for (i = 0; i < BEACON_RING_SIZE; i++)
1198 pBeaconContext = &(pAd->BeaconContext[i]);
1200 if(pBeaconContext->IRPPending == TRUE)
1203 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1204 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1205 // when the last IRP on the list has been cancelled; that's how we exit this loop
1208 RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1210 // Sleep 200 microsecs to give cancellation time to work
1215 pNullContext = &(pAd->NullContext);
1216 if (pNullContext->IRPPending == TRUE)
1217 RTUSB_UNLINK_URB(pNullContext->pUrb);
1219 pRTSContext = &(pAd->RTSContext);
1220 if (pRTSContext->IRPPending == TRUE)
1221 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1223 pPsPollContext = &(pAd->PsPollContext);
1224 if (pPsPollContext->IRPPending == TRUE)
1225 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1227 for (Idx = 0; Idx < 4; Idx++)
1229 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1230 pAd->BulkOutPending[Idx] = FALSE;
1231 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);