Staging: add rt2870 wireless driver
[linux-2.6/mini2440.git] / drivers / staging / rt2870 / common / rtusb_bulk.c
blob3c6ba1b9deb1b05731d32f32a40dff0115aefbb6
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
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. *
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 *************************************************************************
27 Module Name:
28 rtusb_bulk.c
30 Abstract:
32 Revision History:
33 Who When What
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,
49 void *pTransferBuf,
50 int BufSize,
51 usb_complete_t Complete,
52 void *pContext)
55 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
56 usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
57 #else
58 FILL_BULK_URB(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);
59 #endif
63 VOID RTUSBInitTxDesc(
64 IN PRTMP_ADAPTER pAd,
65 IN PTX_CONTEXT pTxContext,
66 IN UCHAR BulkOutPipeId,
67 IN usb_complete_t Func)
69 PURB pUrb;
70 PUCHAR pSrc = NULL;
71 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
73 pUrb = pTxContext->pUrb;
74 ASSERT(pUrb);
76 // Store BulkOut PipeId
77 pTxContext->BulkOutPipeId = BulkOutPipeId;
79 if (pTxContext->bAggregatible)
81 pSrc = &pTxContext->TransferBuffer->Aggregation[2];
83 else
85 pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
89 //Initialize a tx bulk urb
90 RTUSB_FILL_BULK_URB(pUrb,
91 pObj->pUsb_Dev,
92 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
93 pSrc,
94 pTxContext->BulkOutSize,
95 Func,
96 pTxContext);
98 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
99 if (pTxContext->bAggregatible)
100 pUrb->transfer_dma = (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
101 else
102 pUrb->transfer_dma = pTxContext->data_dma;
104 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
105 #endif
109 VOID RTUSBInitHTTxDesc(
110 IN PRTMP_ADAPTER pAd,
111 IN PHT_TX_CONTEXT pTxContext,
112 IN UCHAR BulkOutPipeId,
113 IN ULONG BulkOutSize,
114 IN usb_complete_t Func)
116 PURB pUrb;
117 PUCHAR pSrc = NULL;
118 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
120 pUrb = pTxContext->pUrb;
121 ASSERT(pUrb);
123 // Store BulkOut PipeId
124 pTxContext->BulkOutPipeId = BulkOutPipeId;
126 pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
129 //Initialize a tx bulk urb
130 RTUSB_FILL_BULK_URB(pUrb,
131 pObj->pUsb_Dev,
132 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
133 pSrc,
134 BulkOutSize,
135 Func,
136 pTxContext);
138 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
139 pUrb->transfer_dma = (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
140 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
141 #endif
145 VOID RTUSBInitRxDesc(
146 IN PRTMP_ADAPTER pAd,
147 IN PRX_CONTEXT pRxContext)
149 PURB pUrb;
150 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
151 ULONG RX_bulk_size;
154 pUrb = pRxContext->pUrb;
155 ASSERT(pUrb);
157 if ( pAd->BulkInMaxPacketSize == 64)
158 RX_bulk_size = 4096;
159 else
160 RX_bulk_size = MAX_RXBULK_SIZE;
162 //Initialize a rx bulk urb
163 RTUSB_FILL_BULK_URB(pUrb,
164 pObj->pUsb_Dev,
165 usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
166 &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
167 RX_bulk_size - (pAd->NextRxBulkInPosition),
168 (usb_complete_t)RTUSBBulkRxComplete,
169 (void *)pRxContext);
171 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
172 pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
173 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
174 #endif
180 ========================================================================
182 Routine Description:
184 Arguments:
186 Return Value:
188 Note:
190 ========================================================================
193 #define BULK_OUT_LOCK(pLock, IrqFlags) \
194 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
195 RTMP_IRQ_LOCK((pLock), IrqFlags);
197 #define BULK_OUT_UNLOCK(pLock, IrqFlags) \
198 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
199 RTMP_IRQ_UNLOCK((pLock), IrqFlags);
202 VOID RTUSBBulkOutDataPacket(
203 IN PRTMP_ADAPTER pAd,
204 IN UCHAR BulkOutPipeId,
205 IN UCHAR Index)
208 PHT_TX_CONTEXT pHTTXContext;
209 PURB pUrb;
210 int ret = 0;
211 PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL;
212 PTXWI_STRUC pTxWI;
213 ULONG TmpBulkEndPos, ThisBulkSize;
214 unsigned long IrqFlags = 0, IrqFlags2 = 0;
215 PUCHAR pWirelessPkt, pAppendant;
216 BOOLEAN bTxQLastRound = FALSE;
217 UCHAR allzero[4]= {0x0,0x0,0x0,0x0};
219 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
220 if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
222 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
223 return;
225 pAd->BulkOutPending[BulkOutPipeId] = TRUE;
227 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
230 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
231 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
232 return;
234 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
237 pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
239 BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
240 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
241 || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
243 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
245 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
246 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
248 // Clear Data flag
249 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
250 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
252 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
253 return;
256 // Clear Data flag
257 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
258 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
260 //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
261 // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
262 // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
263 pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
264 ThisBulkSize = 0;
265 TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
266 pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
268 if ((pHTTXContext->bCopySavePad == TRUE))
270 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
272 DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n",
273 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
274 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
276 NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
277 pHTTXContext->bCopySavePad = FALSE;
278 if (pAd->bForcePrintTX == TRUE)
279 DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
284 pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
285 pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
287 if (pAd->bForcePrintTX == TRUE)
288 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU));
290 // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
291 //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))
292 if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK))
294 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
296 // Limit BulkOut size to about 4k bytes.
297 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
298 break;
300 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
302 // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
303 // 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.
304 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
305 break;
308 // end Iverson
309 else
311 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
312 { // Limit BulkOut size to about 24k bytes.
313 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
314 break;
316 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
317 { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
318 // 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.
319 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
320 break;
324 if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
326 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
327 break;
330 if (pTxInfo->QSEL != FIFO_EDCA)
332 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __FUNCTION__, pTxInfo->QSEL);
333 printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
334 hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
337 if (pTxInfo->USBDMATxPktLen <= 8)
339 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
340 DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
341 pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
343 DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n",
344 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
345 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
347 pAd->bForcePrintTX = TRUE;
348 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
349 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
350 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
351 //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
352 return;
355 // Increase Total transmit byte counter
356 pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount;
357 pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount;
359 pLastTxInfo = pTxInfo;
361 // Make sure we use EDCA QUEUE.
362 pTxInfo->QSEL = FIFO_EDCA;
363 ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
364 TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
366 if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
367 pTxInfo->USBDMANextVLD = 1;
369 if (pTxInfo->SwUseLastRound == 1)
371 if (pHTTXContext->CurWritePosition == 8)
372 pTxInfo->USBDMANextVLD = 0;
373 pTxInfo->SwUseLastRound = 0;
375 bTxQLastRound = TRUE;
376 pHTTXContext->ENextBulkOutPosition = 8;
378 #ifdef RT_BIG_ENDIAN
379 RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
380 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
381 #endif // RT_BIG_ENDIAN //
383 break;
386 #ifdef RT_BIG_ENDIAN
387 RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
388 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
389 #endif // RT_BIG_ENDIAN //
391 }while (TRUE);
393 // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
394 if (pLastTxInfo)
396 #ifdef RT_BIG_ENDIAN
397 RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
398 #endif // RT_BIG_ENDIAN //
399 pLastTxInfo->USBDMANextVLD = 0;
400 #ifdef RT_BIG_ENDIAN
401 RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
402 #endif // RT_BIG_ENDIAN //
406 We need to copy SavedPad when following condition matched!
407 1. Not the last round of the TxQueue and
408 2. any match of following cases:
409 (1). The End Position of this bulk out is reach to the Currenct Write position and
410 the TxInfo and related header already write to the CurWritePosition.
411 =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
413 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
414 =>(ENextBulkOutPosition != CurWritePosition)
416 if ((bTxQLastRound == FALSE) &&
417 (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
418 (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
421 NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
422 pHTTXContext->bCopySavePad = TRUE;
423 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
425 PUCHAR pBuf = &pHTTXContext->SavedPad[0];
426 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",
427 pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
428 pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
430 pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
431 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]));
433 //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
436 if (pAd->bForcePrintTX == TRUE)
437 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));
438 //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));
440 // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
441 pAppendant = &pWirelessPkt[TmpBulkEndPos];
442 NdisZeroMemory(pAppendant, 8);
443 ThisBulkSize += 4;
444 pHTTXContext->LastOne = TRUE;
445 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
446 ThisBulkSize += 4;
447 pHTTXContext->BulkOutSize = ThisBulkSize;
449 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
450 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
452 // Init Tx context descriptor
453 RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
455 pUrb = pHTTXContext->pUrb;
456 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
458 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
460 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
461 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
462 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
463 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
465 return;
468 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
469 pHTTXContext->IRPPending = TRUE;
470 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
471 pAd->BulkOutReq++;
476 VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
478 #if 0 // sample, IRQ LOCK
479 PRTMP_ADAPTER pAd;
480 POS_COOKIE pObj;
481 PHT_TX_CONTEXT pHTTXContext;
482 UCHAR BulkOutPipeId;
483 NTSTATUS Status;
484 unsigned long IrqFlags;
486 DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutDataPacketComplete\n"));
488 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
489 pAd = pHTTXContext->pAd;
490 pObj = (POS_COOKIE) pAd->OS_Cookie;
491 Status = pUrb->status;
493 // Store BulkOut PipeId
494 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
495 pAd->BulkOutDataOneSecCount++;
497 //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
498 // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
500 RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
501 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
502 pHTTXContext->IRPPending = FALSE;
503 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
505 if (Status == USB_ST_NOERROR)
507 pAd->BulkOutComplete++;
509 pAd->Counters8023.GoodTransmits++;
510 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
511 FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
512 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
516 else // STATUS_OTHER
518 PUCHAR pBuf;
520 pAd->BulkOutCompleteOther++;
522 pBuf = &pHTTXContext->TransferBuffer->WirelessPacket[pHTTXContext->NextBulkOutPosition];
524 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
525 DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
526 DBGPRINT_RAW(RT_DEBUG_ERROR, (">>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]));
527 //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
529 if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
530 fRTMP_ADAPTER_HALT_IN_PROGRESS |
531 fRTMP_ADAPTER_NIC_NOT_EXIST |
532 fRTMP_ADAPTER_BULKOUT_RESET)))
534 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
535 pAd->bulkResetPipeid = BulkOutPipeId;
540 // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
541 // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
543 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
544 if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
545 (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
546 !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
548 // Indicate There is data avaliable
549 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
551 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
553 // Always call Bulk routine, even reset bulk.
554 // The protection of rest bulk should be in BulkOut routine
555 RTUSBKickBulkOut(pAd);
558 //DBGPRINT(RT_DEBUG_LOUD,("Done-A(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d\n", BulkOutPipeId, in_interrupt(),
559 // pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
561 switch (BulkOutPipeId)
563 case 0:
564 pObj->ac0_dma_done_task.data = (unsigned long)pAd;
565 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
566 break;
567 case 1:
568 pObj->ac1_dma_done_task.data = (unsigned long)pAd;
569 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
570 break;
571 case 2:
572 pObj->ac2_dma_done_task.data = (unsigned long)pAd;
573 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
574 break;
575 case 3:
576 pObj->ac3_dma_done_task.data = (unsigned long)pAd;
577 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
578 break;
579 case 4:
580 pObj->hcca_dma_done_task.data = (unsigned long)pAd;
581 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
582 break;
584 #else
587 PHT_TX_CONTEXT pHTTXContext;
588 PRTMP_ADAPTER pAd;
589 POS_COOKIE pObj;
590 UCHAR BulkOutPipeId;
593 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
594 pAd = pHTTXContext->pAd;
595 pObj = (POS_COOKIE) pAd->OS_Cookie;
597 // Store BulkOut PipeId
598 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
599 pAd->BulkOutDataOneSecCount++;
601 switch (BulkOutPipeId)
603 case 0:
604 pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
605 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
606 break;
607 case 1:
608 pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
609 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
610 break;
611 case 2:
612 pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
613 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
614 break;
615 case 3:
616 pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
617 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
618 break;
619 case 4:
620 pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
621 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
622 break;
625 #endif
632 ========================================================================
634 Routine Description:
636 Arguments:
638 Return Value:
640 Note: NULL frame use BulkOutPipeId = 0
642 ========================================================================
644 VOID RTUSBBulkOutNullFrame(
645 IN PRTMP_ADAPTER pAd)
647 PTX_CONTEXT pNullContext = &(pAd->NullContext);
648 PURB pUrb;
649 int ret = 0;
650 unsigned long IrqFlags;
652 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
653 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
655 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
656 return;
658 pAd->BulkOutPending[0] = TRUE;
659 pAd->watchDogTxPendingCnt[0] = 1;
660 pNullContext->IRPPending = TRUE;
661 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
663 // Increase Total transmit byte counter
664 pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
667 // Clear Null frame bulk flag
668 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
670 #ifdef RT_BIG_ENDIAN
671 RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO);
672 #endif // RT_BIG_ENDIAN //
674 // Init Tx context descriptor
675 RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
677 pUrb = pNullContext->pUrb;
678 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
680 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
681 pAd->BulkOutPending[0] = FALSE;
682 pAd->watchDogTxPendingCnt[0] = 0;
683 pNullContext->IRPPending = FALSE;
684 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
686 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
687 return;
692 // NULL frame use BulkOutPipeId = 0
693 VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
695 PRTMP_ADAPTER pAd;
696 PTX_CONTEXT pNullContext;
697 NTSTATUS Status;
698 #if 0 // sample, IRQ LOCK
699 unsigned long IrqFlags;
700 #endif
701 POS_COOKIE pObj;
704 pNullContext = (PTX_CONTEXT)pUrb->context;
705 pAd = pNullContext->pAd;
706 Status = pUrb->status;
708 #if 0 // sample, IRQ LOCK
709 // Reset Null frame context flags
710 pNullContext->IRPPending = FALSE;
711 pNullContext->InUse = FALSE;
713 if (Status == USB_ST_NOERROR)
715 // Don't worry about the queue is empty or not, this function will check itself
716 //RTMPUSBDeQueuePacket(pAd, 0);
717 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
719 else // STATUS_OTHER
721 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
722 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
723 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
724 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
726 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed\n"));
727 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
728 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
732 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
733 pAd->BulkOutPending[0] = FALSE;
734 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
736 // Always call Bulk routine, even reset bulk.
737 // The protectioon of rest bulk should be in BulkOut routine
738 RTUSBKickBulkOut(pAd);
739 #else
741 pObj = (POS_COOKIE) pAd->OS_Cookie;
742 pObj->null_frame_complete_task.data = (unsigned long)pUrb;
743 tasklet_hi_schedule(&pObj->null_frame_complete_task);
744 #endif
748 #if 0 // For RT2870, RTS frame not used now, but maybe will use it latter.
750 ========================================================================
752 Routine Description:
754 Arguments:
756 Return Value:
758 Note: RTS frame use BulkOutPipeId = 0
760 ========================================================================
762 VOID RTUSBBulkOutRTSFrame(
763 IN PRTMP_ADAPTER pAd)
765 PTX_CONTEXT pRTSContext = &(pAd->RTSContext);
766 PURB pUrb;
767 int ret = 0;
768 unsigned long IrqFlags;
769 UCHAR PipeID=0;
771 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
772 PipeID= 3;
773 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
774 PipeID= 2;
775 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
776 PipeID= 1;
777 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
778 PipeID= 0;
780 RTMP_IRQ_LOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
781 if ((pAd->BulkOutPending[PipeID] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
783 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
784 return;
786 pAd->BulkOutPending[PipeID] = TRUE;
787 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
789 // Increase Total transmit byte counter
790 pAd->RalinkCounters.TransmittedByteCount += pRTSContext->BulkOutSize;
792 DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutRTSFrame \n"));
794 // Clear RTS frame bulk flag
795 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_RTS);
797 #ifdef RT_BIG_ENDIAN
798 RTMPDescriptorEndianChange((PUCHAR)pRTSContext->TransferBuffer, TYPE_TXINFO);
799 #endif // RT_BIG_ENDIAN //
801 // Init Tx context descriptor
802 RTUSBInitTxDesc(pAd, pRTSContext, PipeID, (usb_complete_t)RTUSBBulkOutRTSFrameComplete);
803 pRTSContext->IRPPending = TRUE;
805 pUrb = pRTSContext->pUrb;
806 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
808 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutRTSFrame: Submit Tx URB failed %d\n", ret));
809 return;
812 DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutRTSFrame \n"));
816 // RTS frame use BulkOutPipeId = 0
817 VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
819 PRTMP_ADAPTER pAd;
820 PTX_CONTEXT pRTSContext;
821 NTSTATUS Status;
822 #if 0 // sample, IRQ LOCK
823 unsigned long IrqFlags;
824 #endif
825 POS_COOKIE pObj;
827 DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutRTSFrameComplete\n"));
829 pRTSContext = (PTX_CONTEXT)pUrb->context;
830 pAd = pRTSContext->pAd;
831 Status = pUrb->status;
833 #if 0 // sample, IRQ LOCK
834 // Reset RTS frame context flags
835 pRTSContext->IRPPending = FALSE;
836 pRTSContext->InUse = FALSE;
838 if (Status == USB_ST_NOERROR)
840 // Don't worry about the queue is empty or not, this function will check itself
841 //RTMPUSBDeQueuePacket(pAd, pRTSContext->BulkOutPipeId);
842 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
844 else // STATUS_OTHER
846 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
847 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
848 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
849 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
851 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
852 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
853 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
857 RTMP_IRQ_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags);
858 pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
859 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags);
861 // Always call Bulk routine, even reset bulk.
862 // The protectioon of rest bulk should be in BulkOut routine
863 RTUSBKickBulkOut(pAd);
864 #else
866 pObj = (POS_COOKIE) pAd->OS_Cookie;
867 pObj->rts_frame_complete_task.data = (unsigned long)pUrb;
868 tasklet_hi_schedule(&pObj->rts_frame_complete_task);
869 #endif
871 DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutRTSFrameComplete\n"));
874 #endif
877 ========================================================================
879 Routine Description:
881 Arguments:
883 Return Value:
885 Note: MLME use BulkOutPipeId = 0
887 ========================================================================
889 VOID RTUSBBulkOutMLMEPacket(
890 IN PRTMP_ADAPTER pAd,
891 IN UCHAR Index)
893 PTX_CONTEXT pMLMEContext;
894 PURB pUrb;
895 int ret = 0;
896 unsigned long IrqFlags;
898 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
899 pUrb = pMLMEContext->pUrb;
901 if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
902 (pMLMEContext->InUse == FALSE) ||
903 (pMLMEContext->bWaitingBulkOut == FALSE))
907 // Clear MLME bulk flag
908 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
910 return;
914 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
915 if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
917 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
918 return;
921 pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
922 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
923 pMLMEContext->IRPPending = TRUE;
924 pMLMEContext->bWaitingBulkOut = FALSE;
925 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
927 // Increase Total transmit byte counter
928 pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
930 // Clear MLME bulk flag
931 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
934 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacket\n"));
935 #if 0 // for debug
937 printk("MLME-Out, C=%d!, D=%d, F=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
939 //TODO: Need to remove it when formal release
940 PTXINFO_STRUC pTxInfo;
942 pTxInfo = (PTXINFO_STRUC)pMLMEContext->TransferBuffer;
943 if (pTxInfo->QSEL != FIFO_EDCA)
945 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __FUNCTION__, pTxInfo->QSEL);
946 printk("\tMLME_Index=%d!\n", Index);
947 hex_dump("Wrong QSel Pkt:", (PUCHAR)pMLMEContext->TransferBuffer, pTxInfo->USBDMATxPktLen);
950 #endif
952 #ifdef RT_BIG_ENDIAN
953 RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO);
954 #endif // RT_BIG_ENDIAN //
956 // Init Tx context descriptor
957 RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
959 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
960 //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
961 pUrb->transfer_dma = 0;
962 pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
963 #endif
965 pUrb = pMLMEContext->pUrb;
966 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
968 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
969 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
970 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
971 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
972 pMLMEContext->IRPPending = FALSE;
973 pMLMEContext->bWaitingBulkOut = TRUE;
974 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
976 return;
979 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
980 // printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
984 VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
986 PTX_CONTEXT pMLMEContext;
987 PRTMP_ADAPTER pAd;
988 NTSTATUS Status;
989 POS_COOKIE pObj;
990 int index;
991 #if 0 // sample, IRQ LOCK
992 unsigned long IrqFlags;
993 PNDIS_PACKET pPacket;
994 #endif
997 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
998 pMLMEContext = (PTX_CONTEXT)pUrb->context;
999 pAd = pMLMEContext->pAd;
1000 pObj = (POS_COOKIE)pAd->OS_Cookie;
1001 Status = pUrb->status;
1002 index = pMLMEContext->SelfIdx;
1005 #if 0 // sample, IRQ LOCK
1006 ASSERT((pAd->MgmtRing.TxDmaIdx == index));
1007 //printk("MLME-Done-B: C=%d, D=%d, F=%d, Self=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx, pMLMEContext->SelfIdx);
1009 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1012 if (Status != USB_ST_NOERROR)
1014 //Bulk-Out fail status handle
1015 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1016 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1017 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1018 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1020 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1021 // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
1022 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1023 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1026 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1027 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1029 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1030 // Reset MLME context flags
1031 pMLMEContext->IRPPending = FALSE;
1032 pMLMEContext->InUse = FALSE;
1033 pMLMEContext->bWaitingBulkOut = FALSE;
1034 pMLMEContext->BulkOutSize = 0;
1036 pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
1037 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
1039 // Increase MgmtRing Index
1040 INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
1041 pAd->MgmtRing.TxSwFreeIdx++;
1043 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1045 // No-matter success or fail, we free the mgmt packet.
1046 if (pPacket)
1047 RTMPFreeNdisPacket(pAd, pPacket);
1049 #if 0
1050 //Bulk-Out fail status handle
1051 if (Status != USB_ST_NOERROR)
1053 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1054 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1055 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1056 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1058 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1059 // TODO: How to handle about the MLMEBulkOut failed issue. Need to reset the endpoint?
1060 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1061 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1064 #endif
1066 //printk("MLME-Done-A: C=%d, D=%d, F=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
1068 pObj->mgmt_dma_done_task.data = (unsigned long)pAd;
1069 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
1071 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacketComplete\n"));
1072 // printk("<---RTUSBBulkOutMLMEPacketComplete, Cpu=%d, Dma=%d, SwIdx=%d!\n",
1073 // pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
1075 #else
1077 pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
1078 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
1079 #endif
1084 ========================================================================
1086 Routine Description:
1088 Arguments:
1090 Return Value:
1092 Note: PsPoll use BulkOutPipeId = 0
1094 ========================================================================
1096 VOID RTUSBBulkOutPsPoll(
1097 IN PRTMP_ADAPTER pAd)
1099 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
1100 PURB pUrb;
1101 int ret = 0;
1102 unsigned long IrqFlags;
1104 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1105 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
1107 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1108 return;
1110 pAd->BulkOutPending[0] = TRUE;
1111 pAd->watchDogTxPendingCnt[0] = 1;
1112 pPsPollContext->IRPPending = TRUE;
1113 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1116 // Clear PS-Poll bulk flag
1117 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
1119 #ifdef RT_BIG_ENDIAN
1120 RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO);
1121 #endif // RT_BIG_ENDIAN //
1123 // Init Tx context descriptor
1124 RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
1126 pUrb = pPsPollContext->pUrb;
1127 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1129 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1130 pAd->BulkOutPending[0] = FALSE;
1131 pAd->watchDogTxPendingCnt[0] = 0;
1132 pPsPollContext->IRPPending = FALSE;
1133 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1135 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
1136 return;
1141 // PS-Poll frame use BulkOutPipeId = 0
1142 VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
1144 PRTMP_ADAPTER pAd;
1145 PTX_CONTEXT pPsPollContext;
1146 NTSTATUS Status;
1147 #if 0 // sample, IRQ LOCK
1148 unsigned long IrqFlags;
1149 #endif
1150 POS_COOKIE pObj;
1153 pPsPollContext= (PTX_CONTEXT)pUrb->context;
1154 pAd = pPsPollContext->pAd;
1155 Status = pUrb->status;
1157 #if 0 // sample, IRQ LOCK
1158 // Reset PsPoll context flags
1159 pPsPollContext->IRPPending = FALSE;
1160 pPsPollContext->InUse = FALSE;
1162 if (Status == USB_ST_NOERROR)
1164 // Don't worry about the queue is empty or not, this function will check itself
1165 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1167 else // STATUS_OTHER
1169 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1170 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1171 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1172 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1174 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
1175 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1176 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1180 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1181 pAd->BulkOutPending[0] = FALSE;
1182 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1184 // Always call Bulk routine, even reset bulk.
1185 // The protectioon of rest bulk should be in BulkOut routine
1186 RTUSBKickBulkOut(pAd);
1187 #else
1189 pObj = (POS_COOKIE) pAd->OS_Cookie;
1190 pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
1191 tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
1192 #endif
1196 #if 0
1198 ========================================================================
1200 Routine Description:
1201 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
1202 to USB. It checks if an Rx Descriptor is available and passes the
1203 the coresponding buffer to be filled. If no descriptor is available
1204 fails the request. When setting the completion routine we pass our
1205 Adapter Object as Context.
1207 Arguments:
1209 Return Value:
1210 TRUE found matched tuple cache
1211 FALSE no matched found
1213 Note:
1215 ========================================================================
1217 VOID RTUSBBulkReceive(
1218 IN PRTMP_ADAPTER pAd)
1220 PRX_CONTEXT pRxContext;
1221 PURB pUrb;
1222 int ret = 0;
1223 unsigned long IrqFlags;
1226 /* device had been closed */
1227 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS))
1228 return;
1230 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1232 // Last is time point between 2 separate URB.
1233 if (pAd->NextRxBulkInPosition == 0)
1235 //pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % (RX_RING_SIZE);
1236 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1238 else if ((pAd->NextRxBulkInPosition&0x1ff) != 0)
1240 //pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % (RX_RING_SIZE);
1241 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1242 DBGPRINT_RAW(RT_DEBUG_TRACE, ("pAd->NextRxBulkInPosition = 0x%lx. End of URB.\n", pAd->NextRxBulkInPosition ));
1243 pAd->NextRxBulkInPosition = 0;
1246 if (pAd->NextRxBulkInPosition == MAX_RXBULK_SIZE)
1247 pAd->NextRxBulkInPosition = 0;
1249 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1251 // TODO: Why need to check if pRxContext->InUsed == TRUE?
1252 //if ((pRxContext->InUse == TRUE) || (pRxContext->Readable == TRUE))
1253 if ((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE))
1255 DBGPRINT_RAW(RT_DEBUG_TRACE, ("pRxContext[%d] InUse = %d.pRxContext->Readable = %d. Return.\n", pAd->NextRxBulkInIndex,pRxContext->InUse, pRxContext->Readable ));
1256 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1258 // read RxContext, Since not
1259 #ifdef CONFIG_STA_SUPPORT
1260 STARxDoneInterruptHandle(pAd, TRUE);
1261 #endif // CONFIG_STA_SUPPORT //
1263 //return;
1265 pRxContext->InUse = TRUE;
1266 pRxContext->IRPPending= TRUE;
1268 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1270 // Init Rx context descriptor
1271 NdisZeroMemory(pRxContext->TransferBuffer, BUFFER_SIZE);
1272 RTUSBInitRxDesc(pAd, pRxContext);
1274 pUrb = pRxContext->pUrb;
1275 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1277 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
1278 return;
1280 else // success
1282 NdisInterlockedIncrement(&pAd->PendingRx);
1283 pAd->BulkInReq++;
1286 // read RxContext, Since not
1287 #ifdef CONFIG_STA_SUPPORT
1288 STARxDoneInterruptHandle(pAd, FALSE);
1289 #endif // CONFIG_STA_SUPPORT //
1293 ========================================================================
1295 Routine Description:
1296 This routine process Rx Irp and call rx complete function.
1298 Arguments:
1299 DeviceObject Pointer to the device object for next lower
1300 device. DeviceObject passed in here belongs to
1301 the next lower driver in the stack because we
1302 were invoked via IoCallDriver in USB_RxPacket
1303 AND it is not OUR device object
1304 Irp Ptr to completed IRP
1305 Context Ptr to our Adapter object (context specified
1306 in IoSetCompletionRoutine
1308 Return Value:
1309 Always returns STATUS_MORE_PROCESSING_REQUIRED
1311 Note:
1312 Always returns STATUS_MORE_PROCESSING_REQUIRED
1313 ========================================================================
1315 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
1317 #if 0
1318 PRX_CONTEXT pRxContext;
1319 PRTMP_ADAPTER pAd;
1320 NTSTATUS Status;
1321 // POS_COOKIE pObj;
1323 pRxContext = (PRX_CONTEXT)pUrb->context;
1324 pAd = pRxContext->pAd;
1325 // pObj = (POS_COOKIE) pAd->OS_Cookie;
1328 Status = pUrb->status;
1329 //pRxContext->pIrp = NULL;
1331 pRxContext->InUse = FALSE;
1332 pRxContext->IRPPending = FALSE;
1334 if (Status == USB_ST_NOERROR)
1336 pAd->BulkInComplete++;
1337 pRxContext->Readable = TRUE;
1338 pAd->NextRxBulkInPosition = 0;
1341 else // STATUS_OTHER
1343 pAd->BulkInCompleteFail++;
1344 // Still read this packet although it may comtain wrong bytes.
1345 pRxContext->Readable = FALSE;
1346 // Parsing all packets. because after reset, the index will reset to all zero.
1348 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1349 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET)) &&
1350 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1351 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1354 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status = %d\n", Status));
1355 DBGPRINT_RAW(RT_DEBUG_ERROR, ("==>NextRxBulkInIndex=0x%x, NextRxBulkInReadIndex=0x%x, TransferBufferLength= 0x%x\n",
1356 pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
1358 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1359 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
1361 //pUrb = NULL;
1364 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1365 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET)) &&
1366 // (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) &&
1367 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) &&
1368 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1369 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1371 RTUSBBulkReceive(pAd);
1372 #if 0
1373 #if 1
1374 STARxDoneInterruptHandle(pAd, FALSE);
1375 #else
1376 pObj->rx_bh.data = (unsigned long)pUrb;
1377 tasklet_schedule(&pObj->rx_bh);
1378 #endif
1379 #endif
1382 // Call RxPacket to process packet and return the status
1383 NdisInterlockedDecrement(&pAd->PendingRx);
1384 #else
1387 // use a receive tasklet to handle received packets;
1388 // or sometimes hardware IRQ will be disabled here, so we can not
1389 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
1390 PRX_CONTEXT pRxContext;
1391 PRTMP_ADAPTER pAd;
1392 POS_COOKIE pObj;
1395 pRxContext = (PRX_CONTEXT)pUrb->context;
1396 pAd = pRxContext->pAd;
1397 pObj = (POS_COOKIE) pAd->OS_Cookie;
1399 pObj->rx_done_task.data = (unsigned long)pUrb;
1400 tasklet_hi_schedule(&pObj->rx_done_task);
1401 #endif
1404 #else
1406 VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
1408 PRX_CONTEXT pRxContext;
1409 PURB pUrb;
1410 int ret = 0;
1411 unsigned long IrqFlags;
1413 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1414 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1415 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
1417 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1418 return;
1420 pRxContext->InUse = TRUE;
1421 pRxContext->IRPPending = TRUE;
1422 pAd->PendingRx++;
1423 pAd->BulkInReq++;
1424 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1426 // Init Rx context descriptor
1427 NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
1428 RTUSBInitRxDesc(pAd, pRxContext);
1430 pUrb = pRxContext->pUrb;
1431 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1432 { // fail
1434 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1435 pRxContext->InUse = FALSE;
1436 pRxContext->IRPPending = FALSE;
1437 pAd->PendingRx--;
1438 pAd->BulkInReq--;
1439 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1440 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
1442 else
1443 { // success
1444 #if 0
1445 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1446 pRxContext->IRPPending = TRUE;
1447 //NdisInterlockedIncrement(&pAd->PendingRx);
1448 pAd->PendingRx++;
1449 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1450 pAd->BulkInReq++;
1451 #endif
1452 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1453 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
1459 ========================================================================
1461 Routine Description:
1462 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
1463 to USB. It checks if an Rx Descriptor is available and passes the
1464 the coresponding buffer to be filled. If no descriptor is available
1465 fails the request. When setting the completion routine we pass our
1466 Adapter Object as Context.
1468 Arguments:
1470 Return Value:
1471 TRUE found matched tuple cache
1472 FALSE no matched found
1474 Note:
1476 ========================================================================
1478 #define fRTMP_ADAPTER_NEED_STOP_RX \
1479 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
1480 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
1481 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
1483 #define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
1484 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
1485 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
1486 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
1488 VOID RTUSBBulkReceive(
1489 IN PRTMP_ADAPTER pAd)
1491 PRX_CONTEXT pRxContext;
1492 unsigned long IrqFlags;
1495 /* sanity check */
1496 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
1497 return;
1499 while(1)
1502 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1503 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
1504 if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
1505 (pRxContext->bRxHandling == FALSE))
1507 pRxContext->bRxHandling = TRUE;
1508 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1510 // read RxContext, Since not
1511 #ifdef CONFIG_STA_SUPPORT
1512 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1513 STARxDoneInterruptHandle(pAd, TRUE);
1514 #endif // CONFIG_STA_SUPPORT //
1516 // Finish to handle this bulkIn buffer.
1517 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1518 pRxContext->BulkInOffset = 0;
1519 pRxContext->Readable = FALSE;
1520 pRxContext->bRxHandling = FALSE;
1521 pAd->ReadPosition = 0;
1522 pAd->TransferBufferLength = 0;
1523 INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
1524 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1527 else
1529 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1530 break;
1534 if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
1535 DoBulkIn(pAd);
1541 ========================================================================
1543 Routine Description:
1544 This routine process Rx Irp and call rx complete function.
1546 Arguments:
1547 DeviceObject Pointer to the device object for next lower
1548 device. DeviceObject passed in here belongs to
1549 the next lower driver in the stack because we
1550 were invoked via IoCallDriver in USB_RxPacket
1551 AND it is not OUR device object
1552 Irp Ptr to completed IRP
1553 Context Ptr to our Adapter object (context specified
1554 in IoSetCompletionRoutine
1556 Return Value:
1557 Always returns STATUS_MORE_PROCESSING_REQUIRED
1559 Note:
1560 Always returns STATUS_MORE_PROCESSING_REQUIRED
1561 ========================================================================
1563 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
1565 // use a receive tasklet to handle received packets;
1566 // or sometimes hardware IRQ will be disabled here, so we can not
1567 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
1568 PRX_CONTEXT pRxContext;
1569 PRTMP_ADAPTER pAd;
1570 POS_COOKIE pObj;
1573 pRxContext = (PRX_CONTEXT)pUrb->context;
1574 pAd = pRxContext->pAd;
1575 pObj = (POS_COOKIE) pAd->OS_Cookie;
1577 pObj->rx_done_task.data = (unsigned long)pUrb;
1578 tasklet_hi_schedule(&pObj->rx_done_task);
1582 #endif
1587 ========================================================================
1589 Routine Description:
1591 Arguments:
1593 Return Value:
1595 Note:
1597 ========================================================================
1599 VOID RTUSBKickBulkOut(
1600 IN PRTMP_ADAPTER pAd)
1602 // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
1603 if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
1604 #ifdef RALINK_ATE
1605 && !(ATE_ON(pAd))
1606 #endif // RALINK_ATE //
1609 #if 0 // not used now in RT28xx, but may used latter.
1610 // 1. Data Fragment has highest priority
1611 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG))
1613 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1614 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1617 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
1620 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_2))
1622 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1623 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1626 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
1629 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_3))
1631 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1632 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1635 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
1638 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_4))
1640 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1641 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1644 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
1647 #endif
1649 // 2. PS-Poll frame is next
1650 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
1652 RTUSBBulkOutPsPoll(pAd);
1655 // 5. Mlme frame is next
1656 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
1657 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
1659 RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
1662 // 6. Data frame normal is next
1663 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
1665 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1666 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1669 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
1672 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
1674 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1675 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1678 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
1681 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
1683 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1684 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1687 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
1690 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
1692 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1693 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1696 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
1700 // 7. Null frame is the last
1701 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
1703 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1705 RTUSBBulkOutNullFrame(pAd);
1709 // 8. No data avaliable
1710 else
1715 #ifdef RALINK_ATE
1716 /* If the mode is in ATE mode. */
1717 else if((ATE_ON(pAd)) &&
1718 !RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX))// PETER : watch out !
1720 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE))
1722 ATE_RTUSBBulkOutDataPacket(pAd, 0);
1725 #endif // RALINK_ATE //
1730 ========================================================================
1732 Routine Description:
1733 Call from Reset action after BulkOut failed.
1734 Arguments:
1736 Return Value:
1738 Note:
1740 ========================================================================
1742 VOID RTUSBCleanUpDataBulkOutQueue(
1743 IN PRTMP_ADAPTER pAd)
1745 UCHAR Idx;
1746 PHT_TX_CONTEXT pTxContext;
1748 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1750 for (Idx = 0; Idx < 4; Idx++)
1752 pTxContext = &pAd->TxContext[Idx];
1754 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1755 pTxContext->LastOne = FALSE;
1756 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1757 pAd->BulkOutPending[Idx] = FALSE;
1758 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1761 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1765 ========================================================================
1767 Routine Description:
1769 Arguments:
1771 Return Value:
1773 Note:
1775 ========================================================================
1777 VOID RTUSBCleanUpMLMEBulkOutQueue(
1778 IN PRTMP_ADAPTER pAd)
1780 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
1782 #if 0 // Do nothing!
1783 NdisAcquireSpinLock(&pAd->MLMEBulkOutLock);
1784 while (pAd->PrioRingTxCnt > 0)
1786 pAd->MLMEContext[pAd->PrioRingFirstIndex].InUse = FALSE;
1788 pAd->PrioRingFirstIndex++;
1789 if (pAd->PrioRingFirstIndex >= MGMT_RING_SIZE)
1791 pAd->PrioRingFirstIndex = 0;
1794 pAd->PrioRingTxCnt--;
1796 NdisReleaseSpinLock(&pAd->MLMEBulkOutLock);
1797 #endif
1799 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1804 ========================================================================
1806 Routine Description:
1808 Arguments:
1810 Return Value:
1813 Note:
1815 ========================================================================
1817 VOID RTUSBCancelPendingIRPs(
1818 IN PRTMP_ADAPTER pAd)
1820 RTUSBCancelPendingBulkInIRP(pAd);
1821 RTUSBCancelPendingBulkOutIRP(pAd);
1825 ========================================================================
1827 Routine Description:
1829 Arguments:
1831 Return Value:
1833 Note:
1835 ========================================================================
1837 VOID RTUSBCancelPendingBulkInIRP(
1838 IN PRTMP_ADAPTER pAd)
1840 PRX_CONTEXT pRxContext;
1841 UINT i;
1843 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
1844 for ( i = 0; i < (RX_RING_SIZE); i++)
1846 pRxContext = &(pAd->RxContext[i]);
1847 if(pRxContext->IRPPending == TRUE)
1849 RTUSB_UNLINK_URB(pRxContext->pUrb);
1850 pRxContext->IRPPending = FALSE;
1851 pRxContext->InUse = FALSE;
1852 //NdisInterlockedDecrement(&pAd->PendingRx);
1853 //pAd->PendingRx--;
1856 DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1861 ========================================================================
1863 Routine Description:
1865 Arguments:
1867 Return Value:
1869 Note:
1871 ========================================================================
1873 VOID RTUSBCancelPendingBulkOutIRP(
1874 IN PRTMP_ADAPTER pAd)
1876 PHT_TX_CONTEXT pHTTXContext;
1877 PTX_CONTEXT pMLMEContext;
1878 PTX_CONTEXT pBeaconContext;
1879 PTX_CONTEXT pNullContext;
1880 PTX_CONTEXT pPsPollContext;
1881 PTX_CONTEXT pRTSContext;
1882 UINT i, Idx;
1883 // unsigned int IrqFlags;
1884 // NDIS_SPIN_LOCK *pLock;
1885 // BOOLEAN *pPending;
1888 // pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
1889 // pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
1891 for (Idx = 0; Idx < 4; Idx++)
1893 pHTTXContext = &(pAd->TxContext[Idx]);
1895 if (pHTTXContext->IRPPending == TRUE)
1898 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1899 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1900 // when the last IRP on the list has been cancelled; that's how we exit this loop
1903 RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1905 // Sleep 200 microseconds to give cancellation time to work
1906 RTMPusecDelay(200);
1909 #ifdef RALINK_ATE
1910 pHTTXContext->bCopySavePad = 0;
1911 pHTTXContext->CurWritePosition = 0;
1912 pHTTXContext->CurWriteRealPos = 0;
1913 pHTTXContext->bCurWriting = FALSE;
1914 pHTTXContext->NextBulkOutPosition = 0;
1915 pHTTXContext->ENextBulkOutPosition = 0;
1916 #endif // RALINK_ATE //
1917 pAd->BulkOutPending[Idx] = FALSE;
1920 //RTMP_IRQ_LOCK(pLock, IrqFlags);
1921 for (i = 0; i < MGMT_RING_SIZE; i++)
1923 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
1924 if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
1927 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1928 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1929 // when the last IRP on the list has been cancelled; that's how we exit this loop
1932 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1933 pMLMEContext->IRPPending = FALSE;
1935 // Sleep 200 microsecs to give cancellation time to work
1936 RTMPusecDelay(200);
1939 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1940 //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
1943 for (i = 0; i < BEACON_RING_SIZE; i++)
1945 pBeaconContext = &(pAd->BeaconContext[i]);
1947 if(pBeaconContext->IRPPending == TRUE)
1950 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1951 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1952 // when the last IRP on the list has been cancelled; that's how we exit this loop
1955 RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1957 // Sleep 200 microsecs to give cancellation time to work
1958 RTMPusecDelay(200);
1962 pNullContext = &(pAd->NullContext);
1963 if (pNullContext->IRPPending == TRUE)
1964 RTUSB_UNLINK_URB(pNullContext->pUrb);
1966 pRTSContext = &(pAd->RTSContext);
1967 if (pRTSContext->IRPPending == TRUE)
1968 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1970 pPsPollContext = &(pAd->PsPollContext);
1971 if (pPsPollContext->IRPPending == TRUE)
1972 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1974 for (Idx = 0; Idx < 4; Idx++)
1976 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1977 pAd->BulkOutPending[Idx] = FALSE;
1978 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);