]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/rt2870/common/rtusb_bulk.c
Staging: rt28x0: remove typedefs (part one)
[net-next-2.6.git] / drivers / staging / rt2870 / common / rtusb_bulk.c
CommitLineData
ca97b838 1/*
c55519ff
GKH
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtusb_bulk.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 06-25-2004 created
37
38*/
39
ca97b838
BZ
40#ifdef RTMP_MAC_USB
41
c55519ff 42#include "../rt_config.h"
9f548a2a 43/* Match total 6 bulkout endpoint to corresponding queue. */
51126deb 44u8 EpToQueue[6] =
66cd8d6e 45 { FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT };
c55519ff 46
9f548a2a 47/*static BOOLEAN SingleBulkOut = FALSE; */
c55519ff 48
66cd8d6e
BZ
49void RTUSB_FILL_BULK_URB(struct urb *pUrb,
50 struct usb_device *pUsb_Dev,
51 unsigned int bulkpipe,
52 void *pTransferBuf,
53 int BufSize, usb_complete_t Complete, void *pContext)
c55519ff
GKH
54{
55
66cd8d6e
BZ
56 usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize,
57 (usb_complete_t) Complete, pContext);
c55519ff
GKH
58
59}
60
51126deb 61void RTUSBInitTxDesc(IN PRTMP_ADAPTER pAd,
66cd8d6e 62 IN PTX_CONTEXT pTxContext,
51126deb 63 u8 BulkOutPipeId, IN usb_complete_t Func)
c55519ff 64{
66cd8d6e 65 PURB pUrb;
51126deb 66 u8 *pSrc = NULL;
66cd8d6e 67 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
c55519ff
GKH
68
69 pUrb = pTxContext->pUrb;
70 ASSERT(pUrb);
71
9f548a2a 72 /* Store BulkOut PipeId */
c55519ff
GKH
73 pTxContext->BulkOutPipeId = BulkOutPipeId;
74
66cd8d6e 75 if (pTxContext->bAggregatible) {
c55519ff 76 pSrc = &pTxContext->TransferBuffer->Aggregation[2];
66cd8d6e
BZ
77 } else {
78 pSrc =
51126deb 79 (u8 *)pTxContext->TransferBuffer->field.WirelessPacket;
c55519ff
GKH
80 }
81
9f548a2a 82 /*Initialize a tx bulk urb */
c55519ff 83 RTUSB_FILL_BULK_URB(pUrb,
66cd8d6e
BZ
84 pObj->pUsb_Dev,
85 usb_sndbulkpipe(pObj->pUsb_Dev,
86 pAd->BulkOutEpAddr[BulkOutPipeId]),
87 pSrc, pTxContext->BulkOutSize, Func, pTxContext);
c55519ff 88
c55519ff 89 if (pTxContext->bAggregatible)
66cd8d6e
BZ
90 pUrb->transfer_dma =
91 (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
c55519ff 92 else
66cd8d6e 93 pUrb->transfer_dma = pTxContext->data_dma;
c55519ff
GKH
94
95 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
c55519ff
GKH
96
97}
98
51126deb 99void RTUSBInitHTTxDesc(IN PRTMP_ADAPTER pAd,
66cd8d6e 100 IN PHT_TX_CONTEXT pTxContext,
51126deb
BZ
101 u8 BulkOutPipeId,
102 unsigned long BulkOutSize, IN usb_complete_t Func)
c55519ff 103{
66cd8d6e 104 PURB pUrb;
51126deb 105 u8 *pSrc = NULL;
66cd8d6e 106 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
c55519ff
GKH
107
108 pUrb = pTxContext->pUrb;
109 ASSERT(pUrb);
110
9f548a2a 111 /* Store BulkOut PipeId */
c55519ff
GKH
112 pTxContext->BulkOutPipeId = BulkOutPipeId;
113
66cd8d6e
BZ
114 pSrc =
115 &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->
116 NextBulkOutPosition];
c55519ff 117
9f548a2a 118 /*Initialize a tx bulk urb */
c55519ff 119 RTUSB_FILL_BULK_URB(pUrb,
66cd8d6e
BZ
120 pObj->pUsb_Dev,
121 usb_sndbulkpipe(pObj->pUsb_Dev,
122 pAd->BulkOutEpAddr[BulkOutPipeId]),
123 pSrc, BulkOutSize, Func, pTxContext);
124
125 pUrb->transfer_dma =
126 (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
c55519ff 127 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
c55519ff
GKH
128
129}
130
51126deb 131void RTUSBInitRxDesc(IN PRTMP_ADAPTER pAd, IN PRX_CONTEXT pRxContext)
c55519ff 132{
66cd8d6e
BZ
133 PURB pUrb;
134 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
51126deb 135 unsigned long RX_bulk_size;
c55519ff
GKH
136
137 pUrb = pRxContext->pUrb;
138 ASSERT(pUrb);
139
66cd8d6e 140 if (pAd->BulkInMaxPacketSize == 64)
c55519ff
GKH
141 RX_bulk_size = 4096;
142 else
143 RX_bulk_size = MAX_RXBULK_SIZE;
144
9f548a2a 145 /*Initialize a rx bulk urb */
c55519ff 146 RTUSB_FILL_BULK_URB(pUrb,
66cd8d6e
BZ
147 pObj->pUsb_Dev,
148 usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
149 &(pRxContext->
150 TransferBuffer[pAd->NextRxBulkInPosition]),
151 RX_bulk_size - (pAd->NextRxBulkInPosition),
152 (usb_complete_t) RTUSBBulkRxComplete,
153 (void *)pRxContext);
154
155 pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
c55519ff 156 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
c55519ff 157
c55519ff
GKH
158}
159
160/*
161 ========================================================================
162
163 Routine Description:
164
165 Arguments:
166
167 Return Value:
168
169 Note:
170
171 ========================================================================
172*/
173
174#define BULK_OUT_LOCK(pLock, IrqFlags) \
175 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
176 RTMP_IRQ_LOCK((pLock), IrqFlags);
177
178#define BULK_OUT_UNLOCK(pLock, IrqFlags) \
179 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
180 RTMP_IRQ_UNLOCK((pLock), IrqFlags);
181
51126deb
BZ
182void RTUSBBulkOutDataPacket(IN PRTMP_ADAPTER pAd,
183 u8 BulkOutPipeId, u8 Index)
c55519ff
GKH
184{
185
66cd8d6e
BZ
186 PHT_TX_CONTEXT pHTTXContext;
187 PURB pUrb;
188 int ret = 0;
189 PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL;
190 PTXWI_STRUC pTxWI;
51126deb 191 unsigned long TmpBulkEndPos, ThisBulkSize;
66cd8d6e 192 unsigned long IrqFlags = 0, IrqFlags2 = 0;
51126deb 193 u8 *pWirelessPkt, *pAppendant;
66cd8d6e 194 BOOLEAN bTxQLastRound = FALSE;
51126deb 195 u8 allzero[4] = { 0x0, 0x0, 0x0, 0x0 };
c55519ff
GKH
196
197 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
66cd8d6e
BZ
198 if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE)
199 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
c55519ff
GKH
200 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
201 return;
202 }
203 pAd->BulkOutPending[BulkOutPipeId] = TRUE;
204
205 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
66cd8d6e 206 ) {
c55519ff
GKH
207 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
208 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
209 return;
210 }
211 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
212
c55519ff
GKH
213 pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
214
215 BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
66cd8d6e
BZ
216 if ((pHTTXContext->ENextBulkOutPosition ==
217 pHTTXContext->CurWritePosition)
218 || ((pHTTXContext->ENextBulkOutPosition - 8) ==
219 pHTTXContext->CurWritePosition)) {
220 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId],
221 IrqFlags2);
c55519ff
GKH
222
223 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
224 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
225
9f548a2a 226 /* Clear Data flag */
66cd8d6e
BZ
227 RTUSB_CLEAR_BULK_FLAG(pAd,
228 (fRTUSB_BULK_OUT_DATA_FRAG <<
229 BulkOutPipeId));
230 RTUSB_CLEAR_BULK_FLAG(pAd,
231 (fRTUSB_BULK_OUT_DATA_NORMAL <<
232 BulkOutPipeId));
c55519ff
GKH
233
234 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
235 return;
236 }
9f548a2a 237 /* Clear Data flag */
66cd8d6e
BZ
238 RTUSB_CLEAR_BULK_FLAG(pAd,
239 (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
240 RTUSB_CLEAR_BULK_FLAG(pAd,
241 (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
c55519ff 242
9f548a2a
BZ
243 /*DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(), */
244 /* pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, */
245 /* pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); */
c55519ff
GKH
246 pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
247 ThisBulkSize = 0;
248 TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
249 pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
250
66cd8d6e
BZ
251 if ((pHTTXContext->bCopySavePad == TRUE)) {
252 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) {
253 DBGPRINT_RAW(RT_DEBUG_ERROR,
254 ("e1, allzero : %x %x %x %x %x %x %x %x \n",
255 pHTTXContext->SavedPad[0],
256 pHTTXContext->SavedPad[1],
257 pHTTXContext->SavedPad[2],
258 pHTTXContext->SavedPad[3]
259 , pHTTXContext->SavedPad[4],
260 pHTTXContext->SavedPad[5],
261 pHTTXContext->SavedPad[6],
262 pHTTXContext->SavedPad[7]));
c55519ff 263 }
66cd8d6e
BZ
264 NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos],
265 pHTTXContext->SavedPad, 8);
c55519ff
GKH
266 pHTTXContext->bCopySavePad = FALSE;
267 if (pAd->bForcePrintTX == TRUE)
66cd8d6e
BZ
268 DBGPRINT(RT_DEBUG_TRACE,
269 ("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n",
270 pHTTXContext->CurWritePosition,
271 pHTTXContext->NextBulkOutPosition,
272 pHTTXContext->ENextBulkOutPosition));
c55519ff
GKH
273 }
274
66cd8d6e
BZ
275 do {
276 pTxInfo = (PTXINFO_STRUC) & pWirelessPkt[TmpBulkEndPos];
277 pTxWI =
278 (PTXWI_STRUC) & pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
c55519ff
GKH
279
280 if (pAd->bForcePrintTX == TRUE)
66cd8d6e
BZ
281 DBGPRINT(RT_DEBUG_TRACE,
282 ("RTUSBBulkOutDataPacket AMPDU = %d.\n",
283 pTxWI->AMPDU));
c55519ff 284
9f548a2a
BZ
285 /* add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items */
286 /*if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */
66cd8d6e
BZ
287 if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) {
288 if (((ThisBulkSize & 0xffff8000) != 0)
289 || ((ThisBulkSize & 0x1000) == 0x1000)) {
9f548a2a 290 /* Limit BulkOut size to about 4k bytes. */
66cd8d6e
BZ
291 pHTTXContext->ENextBulkOutPosition =
292 TmpBulkEndPos;
c55519ff 293 break;
66cd8d6e
BZ
294 } else
295 if (((pAd->BulkOutMaxPacketSize < 512)
296 && ((ThisBulkSize & 0xfffff800) !=
297 0))
298 /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */
299 ) {
9f548a2a
BZ
300 /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */
301 /* 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. */
66cd8d6e
BZ
302 pHTTXContext->ENextBulkOutPosition =
303 TmpBulkEndPos;
c55519ff
GKH
304 break;
305 }
306 }
9f548a2a 307 /* end Iverson */
66cd8d6e 308 else {
9f548a2a 309 if (((ThisBulkSize & 0xffff8000) != 0) || ((ThisBulkSize & 0x6000) == 0x6000)) { /* Limit BulkOut size to about 24k bytes. */
66cd8d6e
BZ
310 pHTTXContext->ENextBulkOutPosition =
311 TmpBulkEndPos;
c55519ff 312 break;
9f548a2a
BZ
313 } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize & 0xfffff800) != 0)) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */ ) { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */
314 /* 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. */
66cd8d6e
BZ
315 pHTTXContext->ENextBulkOutPosition =
316 TmpBulkEndPos;
c55519ff
GKH
317 break;
318 }
319 }
320
66cd8d6e 321 if (TmpBulkEndPos == pHTTXContext->CurWritePosition) {
c55519ff
GKH
322 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
323 break;
324 }
325
66cd8d6e
BZ
326 if (pTxInfo->QSEL != FIFO_EDCA) {
327 DBGPRINT(RT_DEBUG_ERROR,
328 ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n",
329 __FUNCTION__, pTxInfo->QSEL));
330 DBGPRINT(RT_DEBUG_ERROR,
331 ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n",
332 pHTTXContext->CurWritePosition,
333 pHTTXContext->NextBulkOutPosition,
334 pHTTXContext->ENextBulkOutPosition,
335 pHTTXContext->bCopySavePad));
336 hex_dump("Wrong QSel Pkt:",
51126deb 337 (u8 *)& pWirelessPkt[TmpBulkEndPos],
66cd8d6e
BZ
338 (pHTTXContext->CurWritePosition -
339 pHTTXContext->NextBulkOutPosition));
c55519ff
GKH
340 }
341
66cd8d6e
BZ
342 if (pTxInfo->USBDMATxPktLen <= 8) {
343 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId],
344 IrqFlags2);
345 DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE */ ,
346 ("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
347 pHTTXContext->BulkOutSize,
348 pHTTXContext->bCopySavePad,
349 pHTTXContext->CurWritePosition,
350 pHTTXContext->NextBulkOutPosition,
351 pHTTXContext->CurWriteRealPos));
c55519ff 352 {
66cd8d6e
BZ
353 DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE */
354 ,
355 ("%x %x %x %x %x %x %x %x \n",
356 pHTTXContext->SavedPad[0],
357 pHTTXContext->SavedPad[1],
358 pHTTXContext->SavedPad[2],
359 pHTTXContext->SavedPad[3]
360 , pHTTXContext->SavedPad[4],
361 pHTTXContext->SavedPad[5],
362 pHTTXContext->SavedPad[6],
363 pHTTXContext->SavedPad[7]));
c55519ff
GKH
364 }
365 pAd->bForcePrintTX = TRUE;
66cd8d6e
BZ
366 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId],
367 IrqFlags);
c55519ff 368 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
66cd8d6e
BZ
369 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId],
370 IrqFlags);
9f548a2a 371 /*DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen)); */
c55519ff
GKH
372 return;
373 }
9f548a2a 374 /* Increase Total transmit byte counter */
66cd8d6e
BZ
375 pAd->RalinkCounters.OneSecTransmittedByteCount +=
376 pTxWI->MPDUtotalByteCount;
377 pAd->RalinkCounters.TransmittedByteCount +=
378 pTxWI->MPDUtotalByteCount;
c55519ff
GKH
379
380 pLastTxInfo = pTxInfo;
381
9f548a2a 382 /* Make sure we use EDCA QUEUE. */
ca97b838 383 pTxInfo->QSEL = FIFO_EDCA;
66cd8d6e
BZ
384 ThisBulkSize += (pTxInfo->USBDMATxPktLen + 4);
385 TmpBulkEndPos += (pTxInfo->USBDMATxPktLen + 4);
c55519ff
GKH
386
387 if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
388 pTxInfo->USBDMANextVLD = 1;
389
66cd8d6e 390 if (pTxInfo->SwUseLastRound == 1) {
c55519ff
GKH
391 if (pHTTXContext->CurWritePosition == 8)
392 pTxInfo->USBDMANextVLD = 0;
393 pTxInfo->SwUseLastRound = 0;
394
395 bTxQLastRound = TRUE;
396 pHTTXContext->ENextBulkOutPosition = 8;
397
c55519ff
GKH
398 break;
399 }
ca97b838 400
66cd8d6e 401 } while (TRUE);
c55519ff 402
9f548a2a 403 /* adjust the pTxInfo->USBDMANextVLD value of last pTxInfo. */
66cd8d6e 404 if (pLastTxInfo) {
c55519ff 405 pLastTxInfo->USBDMANextVLD = 0;
c55519ff
GKH
406 }
407
408 /*
66cd8d6e
BZ
409 We need to copy SavedPad when following condition matched!
410 1. Not the last round of the TxQueue and
411 2. any match of following cases:
412 (1). The End Position of this bulk out is reach to the Currenct Write position and
413 the TxInfo and related header already write to the CurWritePosition.
414 =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
415
416 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
417 =>(ENextBulkOutPosition != CurWritePosition)
418 */
c55519ff 419 if ((bTxQLastRound == FALSE) &&
66cd8d6e
BZ
420 (((pHTTXContext->ENextBulkOutPosition ==
421 pHTTXContext->CurWritePosition)
422 && (pHTTXContext->CurWriteRealPos >
423 pHTTXContext->CurWritePosition))
424 || (pHTTXContext->ENextBulkOutPosition !=
425 pHTTXContext->CurWritePosition))
426 ) {
427 NdisMoveMemory(pHTTXContext->SavedPad,
428 &pWirelessPkt[pHTTXContext->
429 ENextBulkOutPosition], 8);
c55519ff 430 pHTTXContext->bCopySavePad = TRUE;
66cd8d6e 431 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) {
51126deb 432 u8 *pBuf = &pHTTXContext->SavedPad[0];
66cd8d6e
BZ
433 DBGPRINT_RAW(RT_DEBUG_ERROR,
434 ("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
435 pBuf[0], pBuf[1], pBuf[2], pBuf[3],
436 pBuf[4], pBuf[5], pBuf[6], pBuf[7],
437 pHTTXContext->CurWritePosition,
438 pHTTXContext->CurWriteRealPos,
439 pHTTXContext->bCurWriting,
440 pHTTXContext->NextBulkOutPosition,
441 TmpBulkEndPos, ThisBulkSize));
c55519ff
GKH
442
443 pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
66cd8d6e
BZ
444 DBGPRINT_RAW(RT_DEBUG_ERROR,
445 ("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n",
446 pBuf[0], pBuf[1], pBuf[2], pBuf[3],
447 pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
c55519ff 448 }
9f548a2a 449 /*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad)); */
c55519ff
GKH
450 }
451
452 if (pAd->bForcePrintTX == TRUE)
66cd8d6e
BZ
453 DBGPRINT(RT_DEBUG_TRACE,
454 ("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n",
455 ThisBulkSize, pHTTXContext->CurWritePosition,
456 pHTTXContext->NextBulkOutPosition,
457 pHTTXContext->ENextBulkOutPosition,
458 pHTTXContext->bCopySavePad));
9f548a2a 459 /*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)); */
c55519ff 460
9f548a2a 461 /* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize. */
c55519ff
GKH
462 pAppendant = &pWirelessPkt[TmpBulkEndPos];
463 NdisZeroMemory(pAppendant, 8);
66cd8d6e
BZ
464 ThisBulkSize += 4;
465 pHTTXContext->LastOne = TRUE;
466 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
c55519ff 467 ThisBulkSize += 4;
c55519ff
GKH
468 pHTTXContext->BulkOutSize = ThisBulkSize;
469
470 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
471 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
472
9f548a2a 473 /* Init Tx context descriptor */
66cd8d6e
BZ
474 RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize,
475 (usb_complete_t) RTUSBBulkOutDataPacketComplete);
c55519ff
GKH
476
477 pUrb = pHTTXContext->pUrb;
66cd8d6e
BZ
478 if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {
479 DBGPRINT(RT_DEBUG_ERROR,
480 ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n",
481 ret));
c55519ff
GKH
482
483 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
484 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
485 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
486 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
487
488 return;
489 }
490
491 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
492 pHTTXContext->IRPPending = TRUE;
493 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
494 pAd->BulkOutReq++;
495
496}
497
51126deb 498void RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs * pt_regs)
c55519ff 499{
66cd8d6e
BZ
500 PHT_TX_CONTEXT pHTTXContext;
501 PRTMP_ADAPTER pAd;
502 POS_COOKIE pObj;
51126deb 503 u8 BulkOutPipeId;
c55519ff 504
66cd8d6e
BZ
505 pHTTXContext = (PHT_TX_CONTEXT) pUrb->context;
506 pAd = pHTTXContext->pAd;
507 pObj = (POS_COOKIE) pAd->OS_Cookie;
c55519ff 508
9f548a2a 509 /* Store BulkOut PipeId */
66cd8d6e 510 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
c55519ff
GKH
511 pAd->BulkOutDataOneSecCount++;
512
66cd8d6e
BZ
513 switch (BulkOutPipeId) {
514 case 0:
515 pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
516 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
517 break;
518 case 1:
519 pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
520 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
521 break;
522 case 2:
523 pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
524 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
525 break;
526 case 3:
527 pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
528 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
529 break;
c55519ff 530 }
ca97b838 531
c55519ff 532}
c55519ff 533
c55519ff
GKH
534/*
535 ========================================================================
536
537 Routine Description:
538
539 Arguments:
540
541 Return Value:
542
543 Note: NULL frame use BulkOutPipeId = 0
544
545 ========================================================================
546*/
51126deb 547void RTUSBBulkOutNullFrame(IN PRTMP_ADAPTER pAd)
c55519ff 548{
66cd8d6e
BZ
549 PTX_CONTEXT pNullContext = &(pAd->NullContext);
550 PURB pUrb;
551 int ret = 0;
552 unsigned long IrqFlags;
c55519ff
GKH
553
554 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
66cd8d6e
BZ
555 if ((pAd->BulkOutPending[0] == TRUE)
556 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
c55519ff
GKH
557 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
558 return;
559 }
560 pAd->BulkOutPending[0] = TRUE;
561 pAd->watchDogTxPendingCnt[0] = 1;
562 pNullContext->IRPPending = TRUE;
563 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
564
9f548a2a 565 /* Increase Total transmit byte counter */
66cd8d6e 566 pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
c55519ff 567
9f548a2a 568 /* Clear Null frame bulk flag */
c55519ff
GKH
569 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
570
9f548a2a 571 /* Init Tx context descriptor */
66cd8d6e
BZ
572 RTUSBInitTxDesc(pAd, pNullContext, 0,
573 (usb_complete_t) RTUSBBulkOutNullFrameComplete);
c55519ff
GKH
574
575 pUrb = pNullContext->pUrb;
66cd8d6e 576 if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {
c55519ff
GKH
577 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
578 pAd->BulkOutPending[0] = FALSE;
579 pAd->watchDogTxPendingCnt[0] = 0;
580 pNullContext->IRPPending = FALSE;
581 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
582
66cd8d6e
BZ
583 DBGPRINT(RT_DEBUG_ERROR,
584 ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n",
585 ret));
c55519ff
GKH
586 return;
587 }
588
589}
590
9f548a2a 591/* NULL frame use BulkOutPipeId = 0 */
51126deb 592void RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs * pt_regs)
c55519ff 593{
66cd8d6e
BZ
594 PRTMP_ADAPTER pAd;
595 PTX_CONTEXT pNullContext;
51126deb 596 int Status;
66cd8d6e 597 POS_COOKIE pObj;
c55519ff 598
66cd8d6e
BZ
599 pNullContext = (PTX_CONTEXT) pUrb->context;
600 pAd = pNullContext->pAd;
601 Status = pUrb->status;
c55519ff 602
c55519ff
GKH
603 pObj = (POS_COOKIE) pAd->OS_Cookie;
604 pObj->null_frame_complete_task.data = (unsigned long)pUrb;
605 tasklet_hi_schedule(&pObj->null_frame_complete_task);
c55519ff
GKH
606}
607
c55519ff
GKH
608/*
609 ========================================================================
610
611 Routine Description:
612
613 Arguments:
614
615 Return Value:
616
617 Note: MLME use BulkOutPipeId = 0
618
619 ========================================================================
620*/
51126deb 621void RTUSBBulkOutMLMEPacket(IN PRTMP_ADAPTER pAd, u8 Index)
c55519ff 622{
66cd8d6e
BZ
623 PTX_CONTEXT pMLMEContext;
624 PURB pUrb;
625 int ret = 0;
626 unsigned long IrqFlags;
c55519ff 627
66cd8d6e
BZ
628 pMLMEContext =
629 (PTX_CONTEXT) pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
c55519ff
GKH
630 pUrb = pMLMEContext->pUrb;
631
632 if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
66cd8d6e
BZ
633 (pMLMEContext->InUse == FALSE) ||
634 (pMLMEContext->bWaitingBulkOut == FALSE)) {
c55519ff 635
9f548a2a 636 /* Clear MLME bulk flag */
c55519ff
GKH
637 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
638
639 return;
640 }
641
c55519ff 642 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
66cd8d6e
BZ
643 if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE)
644 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
c55519ff
GKH
645 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
646 return;
647 }
648
649 pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
650 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
651 pMLMEContext->IRPPending = TRUE;
652 pMLMEContext->bWaitingBulkOut = FALSE;
653 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
654
9f548a2a 655 /* Increase Total transmit byte counter */
66cd8d6e 656 pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
c55519ff 657
9f548a2a 658 /* Clear MLME bulk flag */
c55519ff
GKH
659 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
660
9f548a2a 661 /* Init Tx context descriptor */
66cd8d6e
BZ
662 RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX,
663 (usb_complete_t) RTUSBBulkOutMLMEPacketComplete);
c55519ff 664
9f548a2a 665 /*For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping. */
66cd8d6e 666 pUrb->transfer_dma = 0;
c55519ff 667 pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
c55519ff
GKH
668
669 pUrb = pMLMEContext->pUrb;
66cd8d6e
BZ
670 if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {
671 DBGPRINT(RT_DEBUG_ERROR,
672 ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n",
673 ret));
c55519ff
GKH
674 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
675 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
676 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
677 pMLMEContext->IRPPending = FALSE;
678 pMLMEContext->bWaitingBulkOut = TRUE;
679 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
680
681 return;
682 }
9f548a2a
BZ
683 /*DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n")); */
684/* printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx); */
c55519ff
GKH
685}
686
51126deb 687void RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs * pt_regs)
c55519ff 688{
66cd8d6e
BZ
689 PTX_CONTEXT pMLMEContext;
690 PRTMP_ADAPTER pAd;
51126deb 691 int Status;
66cd8d6e
BZ
692 POS_COOKIE pObj;
693 int index;
c55519ff 694
9f548a2a 695 /*DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n")); */
66cd8d6e
BZ
696 pMLMEContext = (PTX_CONTEXT) pUrb->context;
697 pAd = pMLMEContext->pAd;
698 pObj = (POS_COOKIE) pAd->OS_Cookie;
699 Status = pUrb->status;
700 index = pMLMEContext->SelfIdx;
c55519ff 701
c55519ff
GKH
702 pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
703 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
c55519ff
GKH
704}
705
c55519ff
GKH
706/*
707 ========================================================================
708
709 Routine Description:
710
711 Arguments:
712
713 Return Value:
714
715 Note: PsPoll use BulkOutPipeId = 0
716
717 ========================================================================
718*/
51126deb 719void RTUSBBulkOutPsPoll(IN PRTMP_ADAPTER pAd)
c55519ff 720{
66cd8d6e
BZ
721 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
722 PURB pUrb;
723 int ret = 0;
724 unsigned long IrqFlags;
c55519ff
GKH
725
726 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
66cd8d6e
BZ
727 if ((pAd->BulkOutPending[0] == TRUE)
728 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
c55519ff
GKH
729 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
730 return;
731 }
732 pAd->BulkOutPending[0] = TRUE;
733 pAd->watchDogTxPendingCnt[0] = 1;
734 pPsPollContext->IRPPending = TRUE;
735 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
736
9f548a2a 737 /* Clear PS-Poll bulk flag */
c55519ff
GKH
738 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
739
9f548a2a 740 /* Init Tx context descriptor */
66cd8d6e
BZ
741 RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX,
742 (usb_complete_t) RTUSBBulkOutPsPollComplete);
c55519ff
GKH
743
744 pUrb = pPsPollContext->pUrb;
66cd8d6e 745 if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {
c55519ff
GKH
746 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
747 pAd->BulkOutPending[0] = FALSE;
748 pAd->watchDogTxPendingCnt[0] = 0;
749 pPsPollContext->IRPPending = FALSE;
750 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
751
66cd8d6e
BZ
752 DBGPRINT(RT_DEBUG_ERROR,
753 ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n",
754 ret));
c55519ff
GKH
755 return;
756 }
757
758}
759
9f548a2a 760/* PS-Poll frame use BulkOutPipeId = 0 */
51126deb 761void RTUSBBulkOutPsPollComplete(purbb_t pUrb, struct pt_regs * pt_regs)
c55519ff 762{
66cd8d6e
BZ
763 PRTMP_ADAPTER pAd;
764 PTX_CONTEXT pPsPollContext;
51126deb 765 int Status;
66cd8d6e 766 POS_COOKIE pObj;
c55519ff 767
66cd8d6e 768 pPsPollContext = (PTX_CONTEXT) pUrb->context;
c55519ff
GKH
769 pAd = pPsPollContext->pAd;
770 Status = pUrb->status;
771
c55519ff
GKH
772 pObj = (POS_COOKIE) pAd->OS_Cookie;
773 pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
774 tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
c55519ff
GKH
775}
776
51126deb 777void DoBulkIn(IN RTMP_ADAPTER * pAd)
c55519ff 778{
66cd8d6e
BZ
779 PRX_CONTEXT pRxContext;
780 PURB pUrb;
781 int ret = 0;
782 unsigned long IrqFlags;
c55519ff
GKH
783
784 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
785 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
66cd8d6e
BZ
786 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE)
787 || (pRxContext->InUse == TRUE)) {
c55519ff
GKH
788 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
789 return;
790 }
791 pRxContext->InUse = TRUE;
792 pRxContext->IRPPending = TRUE;
793 pAd->PendingRx++;
794 pAd->BulkInReq++;
795 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
796
9f548a2a 797 /* Init Rx context descriptor */
c55519ff
GKH
798 NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
799 RTUSBInitRxDesc(pAd, pRxContext);
800
801 pUrb = pRxContext->pUrb;
9f548a2a 802 if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { /* fail */
c55519ff
GKH
803
804 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
805 pRxContext->InUse = FALSE;
806 pRxContext->IRPPending = FALSE;
807 pAd->PendingRx--;
808 pAd->BulkInReq--;
809 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
66cd8d6e
BZ
810 DBGPRINT(RT_DEBUG_ERROR,
811 ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
9f548a2a 812 } else { /* success */
c55519ff 813 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
9f548a2a 814 /*printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex); */
c55519ff
GKH
815 }
816}
817
c55519ff
GKH
818/*
819 ========================================================================
820
821 Routine Description:
822 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
823 to USB. It checks if an Rx Descriptor is available and passes the
824 the coresponding buffer to be filled. If no descriptor is available
825 fails the request. When setting the completion routine we pass our
826 Adapter Object as Context.
827
828 Arguments:
829
830 Return Value:
831 TRUE found matched tuple cache
832 FALSE no matched found
833
834 Note:
835
836 ========================================================================
837*/
838#define fRTMP_ADAPTER_NEED_STOP_RX \
839 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
840 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
841 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
842
843#define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
844 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
845 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
846 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
847
51126deb 848void RTUSBBulkReceive(IN PRTMP_ADAPTER pAd)
c55519ff 849{
66cd8d6e
BZ
850 PRX_CONTEXT pRxContext;
851 unsigned long IrqFlags;
c55519ff
GKH
852
853 /* sanity check */
854 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
855 return;
856
66cd8d6e 857 while (1) {
c55519ff
GKH
858
859 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
860 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
66cd8d6e
BZ
861 if (((pRxContext->InUse == FALSE)
862 && (pRxContext->Readable == TRUE))
863 && (pRxContext->bRxHandling == FALSE)) {
c55519ff
GKH
864 pRxContext->bRxHandling = TRUE;
865 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
866
9f548a2a 867 /* read RxContext, Since not */
303ee97d 868 STARxDoneInterruptHandle(pAd, TRUE);
c55519ff 869
9f548a2a 870 /* Finish to handle this bulkIn buffer. */
c55519ff
GKH
871 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
872 pRxContext->BulkInOffset = 0;
873 pRxContext->Readable = FALSE;
874 pRxContext->bRxHandling = FALSE;
875 pAd->ReadPosition = 0;
876 pAd->TransferBufferLength = 0;
66cd8d6e
BZ
877 INC_RING_INDEX(pAd->NextRxBulkInReadIndex,
878 RX_RING_SIZE);
c55519ff
GKH
879 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
880
66cd8d6e 881 } else {
c55519ff
GKH
882 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
883 break;
884 }
885 }
886
887 if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
888 DoBulkIn(pAd);
889
890}
891
c55519ff
GKH
892/*
893 ========================================================================
894
895 Routine Description:
896 This routine process Rx Irp and call rx complete function.
897
898 Arguments:
899 DeviceObject Pointer to the device object for next lower
900 device. DeviceObject passed in here belongs to
901 the next lower driver in the stack because we
902 were invoked via IoCallDriver in USB_RxPacket
903 AND it is not OUR device object
904 Irp Ptr to completed IRP
905 Context Ptr to our Adapter object (context specified
906 in IoSetCompletionRoutine
907
908 Return Value:
909 Always returns STATUS_MORE_PROCESSING_REQUIRED
910
911 Note:
912 Always returns STATUS_MORE_PROCESSING_REQUIRED
913 ========================================================================
914*/
51126deb 915void RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
c55519ff 916{
9f548a2a
BZ
917 /* use a receive tasklet to handle received packets; */
918 /* or sometimes hardware IRQ will be disabled here, so we can not */
919 /* use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :< */
66cd8d6e
BZ
920 PRX_CONTEXT pRxContext;
921 PRTMP_ADAPTER pAd;
922 POS_COOKIE pObj;
c55519ff 923
66cd8d6e
BZ
924 pRxContext = (PRX_CONTEXT) pUrb->context;
925 pAd = pRxContext->pAd;
926 pObj = (POS_COOKIE) pAd->OS_Cookie;
c55519ff
GKH
927
928 pObj->rx_done_task.data = (unsigned long)pUrb;
929 tasklet_hi_schedule(&pObj->rx_done_task);
930
931}
932
c55519ff
GKH
933/*
934 ========================================================================
935
936 Routine Description:
937
938 Arguments:
939
940 Return Value:
941
942 Note:
943
944 ========================================================================
945*/
51126deb 946void RTUSBKickBulkOut(IN PRTMP_ADAPTER pAd)
c55519ff 947{
9f548a2a 948 /* BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged. */
66cd8d6e
BZ
949 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)
950 ) {
9f548a2a 951 /* 2. PS-Poll frame is next */
66cd8d6e 952 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL)) {
c55519ff
GKH
953 RTUSBBulkOutPsPoll(pAd);
954 }
9f548a2a 955 /* 5. Mlme frame is next */
ca97b838 956 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) ||
66cd8d6e 957 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) {
c55519ff
GKH
958 RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
959 }
9f548a2a 960 /* 6. Data frame normal is next */
66cd8d6e
BZ
961 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL)) {
962 if (((!RTMP_TEST_FLAG
963 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
964 ||
965 (!OPSTATUS_TEST_FLAG
966 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
967 )) {
968 RTUSBBulkOutDataPacket(pAd, 0,
969 pAd->
970 NextBulkOutIndex[0]);
c55519ff
GKH
971 }
972 }
66cd8d6e
BZ
973 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2)) {
974 if (((!RTMP_TEST_FLAG
975 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
976 ||
977 (!OPSTATUS_TEST_FLAG
978 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
979 )) {
980 RTUSBBulkOutDataPacket(pAd, 1,
981 pAd->
982 NextBulkOutIndex[1]);
c55519ff
GKH
983 }
984 }
66cd8d6e
BZ
985 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3)) {
986 if (((!RTMP_TEST_FLAG
987 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
988 ||
989 (!OPSTATUS_TEST_FLAG
990 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
991 )) {
992 RTUSBBulkOutDataPacket(pAd, 2,
993 pAd->
994 NextBulkOutIndex[2]);
c55519ff
GKH
995 }
996 }
66cd8d6e
BZ
997 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4)) {
998 if (((!RTMP_TEST_FLAG
999 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1000 ||
1001 (!OPSTATUS_TEST_FLAG
1002 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1003 )) {
1004 RTUSBBulkOutDataPacket(pAd, 3,
1005 pAd->
1006 NextBulkOutIndex[3]);
c55519ff
GKH
1007 }
1008 }
9f548a2a 1009 /* 7. Null frame is the last */
66cd8d6e
BZ
1010 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) {
1011 if (!RTMP_TEST_FLAG
1012 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
c55519ff
GKH
1013 RTUSBBulkOutNullFrame(pAd);
1014 }
1015 }
9f548a2a 1016 /* 8. No data avaliable */
66cd8d6e 1017 else {
c55519ff
GKH
1018
1019 }
1020 }
c55519ff
GKH
1021}
1022
1023/*
1024 ========================================================================
1025
1026 Routine Description:
1027 Call from Reset action after BulkOut failed.
1028 Arguments:
1029
1030 Return Value:
1031
1032 Note:
1033
1034 ========================================================================
1035*/
51126deb 1036void RTUSBCleanUpDataBulkOutQueue(IN PRTMP_ADAPTER pAd)
c55519ff 1037{
51126deb 1038 u8 Idx;
66cd8d6e 1039 PHT_TX_CONTEXT pTxContext;
c55519ff
GKH
1040
1041 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1042
66cd8d6e 1043 for (Idx = 0; Idx < 4; Idx++) {
c55519ff
GKH
1044 pTxContext = &pAd->TxContext[Idx];
1045
1046 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1047 pTxContext->LastOne = FALSE;
1048 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1049 pAd->BulkOutPending[Idx] = FALSE;
1050 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1051 }
1052
1053 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1054}
1055
1056/*
1057 ========================================================================
1058
1059 Routine Description:
1060
1061 Arguments:
1062
1063 Return Value:
1064
1065 Note:
1066
1067 ========================================================================
1068*/
51126deb 1069void RTUSBCleanUpMLMEBulkOutQueue(IN PRTMP_ADAPTER pAd)
c55519ff
GKH
1070{
1071 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
c55519ff
GKH
1072 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1073}
1074
c55519ff
GKH
1075/*
1076 ========================================================================
1077
1078 Routine Description:
1079
1080 Arguments:
1081
1082 Return Value:
1083
c55519ff
GKH
1084 Note:
1085
1086 ========================================================================
1087*/
51126deb 1088void RTUSBCancelPendingIRPs(IN PRTMP_ADAPTER pAd)
c55519ff
GKH
1089{
1090 RTUSBCancelPendingBulkInIRP(pAd);
1091 RTUSBCancelPendingBulkOutIRP(pAd);
1092}
1093
1094/*
1095 ========================================================================
1096
1097 Routine Description:
1098
1099 Arguments:
1100
1101 Return Value:
1102
1103 Note:
1104
1105 ========================================================================
1106*/
51126deb 1107void RTUSBCancelPendingBulkInIRP(IN PRTMP_ADAPTER pAd)
c55519ff 1108{
66cd8d6e 1109 PRX_CONTEXT pRxContext;
51126deb 1110 u32 i;
c55519ff
GKH
1111
1112 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
66cd8d6e 1113 for (i = 0; i < (RX_RING_SIZE); i++) {
c55519ff 1114 pRxContext = &(pAd->RxContext[i]);
66cd8d6e 1115 if (pRxContext->IRPPending == TRUE) {
c55519ff
GKH
1116 RTUSB_UNLINK_URB(pRxContext->pUrb);
1117 pRxContext->IRPPending = FALSE;
1118 pRxContext->InUse = FALSE;
9f548a2a
BZ
1119 /*NdisInterlockedDecrement(&pAd->PendingRx); */
1120 /*pAd->PendingRx--; */
c55519ff
GKH
1121 }
1122 }
1123 DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1124}
1125
c55519ff
GKH
1126/*
1127 ========================================================================
1128
1129 Routine Description:
1130
1131 Arguments:
1132
1133 Return Value:
1134
1135 Note:
1136
1137 ========================================================================
1138*/
51126deb 1139void RTUSBCancelPendingBulkOutIRP(IN PRTMP_ADAPTER pAd)
c55519ff 1140{
66cd8d6e
BZ
1141 PHT_TX_CONTEXT pHTTXContext;
1142 PTX_CONTEXT pMLMEContext;
1143 PTX_CONTEXT pBeaconContext;
1144 PTX_CONTEXT pNullContext;
1145 PTX_CONTEXT pPsPollContext;
1146 PTX_CONTEXT pRTSContext;
51126deb 1147 u32 i, Idx;
9f548a2a
BZ
1148/* unsigned int IrqFlags; */
1149/* NDIS_SPIN_LOCK *pLock; */
1150/* BOOLEAN *pPending; */
66cd8d6e 1151
9f548a2a
BZ
1152/* pLock = &pAd->BulkOutLock[MGMTPIPEIDX]; */
1153/* pPending = &pAd->BulkOutPending[MGMTPIPEIDX]; */
66cd8d6e
BZ
1154
1155 for (Idx = 0; Idx < 4; Idx++) {
c55519ff
GKH
1156 pHTTXContext = &(pAd->TxContext[Idx]);
1157
66cd8d6e 1158 if (pHTTXContext->IRPPending == TRUE) {
c55519ff 1159
9f548a2a
BZ
1160 /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
1161 /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
1162 /* when the last IRP on the list has been cancelled; that's how we exit this loop */
1163 /* */
c55519ff
GKH
1164
1165 RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1166
9f548a2a 1167 /* Sleep 200 microseconds to give cancellation time to work */
c55519ff
GKH
1168 RTMPusecDelay(200);
1169 }
1170
c55519ff
GKH
1171 pAd->BulkOutPending[Idx] = FALSE;
1172 }
1173
9f548a2a 1174 /*RTMP_IRQ_LOCK(pLock, IrqFlags); */
66cd8d6e
BZ
1175 for (i = 0; i < MGMT_RING_SIZE; i++) {
1176 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
1177 if (pMLMEContext && (pMLMEContext->IRPPending == TRUE)) {
c55519ff 1178
9f548a2a
BZ
1179 /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
1180 /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
1181 /* when the last IRP on the list has been cancelled; that's how we exit this loop */
1182 /* */
c55519ff
GKH
1183
1184 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1185 pMLMEContext->IRPPending = FALSE;
1186
9f548a2a 1187 /* Sleep 200 microsecs to give cancellation time to work */
c55519ff
GKH
1188 RTMPusecDelay(200);
1189 }
1190 }
1191 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
9f548a2a 1192 /*RTMP_IRQ_UNLOCK(pLock, IrqFlags); */
c55519ff 1193
66cd8d6e 1194 for (i = 0; i < BEACON_RING_SIZE; i++) {
c55519ff
GKH
1195 pBeaconContext = &(pAd->BeaconContext[i]);
1196
66cd8d6e 1197 if (pBeaconContext->IRPPending == TRUE) {
c55519ff 1198
9f548a2a
BZ
1199 /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
1200 /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
1201 /* when the last IRP on the list has been cancelled; that's how we exit this loop */
1202 /* */
c55519ff
GKH
1203
1204 RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1205
9f548a2a 1206 /* Sleep 200 microsecs to give cancellation time to work */
c55519ff
GKH
1207 RTMPusecDelay(200);
1208 }
1209 }
1210
1211 pNullContext = &(pAd->NullContext);
1212 if (pNullContext->IRPPending == TRUE)
1213 RTUSB_UNLINK_URB(pNullContext->pUrb);
1214
1215 pRTSContext = &(pAd->RTSContext);
1216 if (pRTSContext->IRPPending == TRUE)
1217 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1218
1219 pPsPollContext = &(pAd->PsPollContext);
1220 if (pPsPollContext->IRPPending == TRUE)
1221 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1222
66cd8d6e 1223 for (Idx = 0; Idx < 4; Idx++) {
c55519ff
GKH
1224 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1225 pAd->BulkOutPending[Idx] = FALSE;
1226 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1227 }
1228}
1229
9f548a2a 1230#endif /* RTMP_MAC_USB // */