Fix common misspellings
[linux-block.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
62eb734b
BZ
61void RTUSBInitTxDesc(struct rt_rtmp_adapter *pAd,
62 struct rt_tx_context *pTxContext,
51126deb 63 u8 BulkOutPipeId, IN usb_complete_t Func)
c55519ff 64{
66cd8d6e 65 PURB pUrb;
51126deb 66 u8 *pSrc = NULL;
8a10a546 67 struct os_cookie *pObj = (struct os_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
62eb734b
BZ
99void RTUSBInitHTTxDesc(struct rt_rtmp_adapter *pAd,
100 struct rt_ht_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;
8a10a546 106 struct os_cookie *pObj = (struct os_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
62eb734b 131void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext)
c55519ff 132{
66cd8d6e 133 PURB pUrb;
8a10a546 134 struct os_cookie *pObj = (struct os_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) \
d24e4497 175 if (1 /*!(in_interrupt() & 0xffff0000)*/) \
c55519ff
GKH
176 RTMP_IRQ_LOCK((pLock), IrqFlags);
177
178#define BULK_OUT_UNLOCK(pLock, IrqFlags) \
d24e4497 179 if (1 /*!(in_interrupt() & 0xffff0000)*/) \
c55519ff
GKH
180 RTMP_IRQ_UNLOCK((pLock), IrqFlags);
181
62eb734b 182void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd,
51126deb 183 u8 BulkOutPipeId, u8 Index)
c55519ff
GKH
184{
185
62eb734b 186 struct rt_ht_tx_context *pHTTXContext;
66cd8d6e
BZ
187 PURB pUrb;
188 int ret = 0;
62eb734b 189 struct rt_txinfo *pTxInfo, *pLastTxInfo = NULL;
d24e4497 190 struct rt_txwi *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 275 do {
d24e4497 276 pTxInfo = (struct rt_txinfo *)&pWirelessPkt[TmpBulkEndPos];
66cd8d6e 277 pTxWI =
d24e4497 278 (struct rt_txwi *)&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 300 /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */
25985edc 301 /* For performance 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;
d24e4497 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. */
25985edc 314 /* For performance 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",
d24e4497 329 __func__, pTxInfo->QSEL));
66cd8d6e
BZ
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:",
d24e4497 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. */
d24e4497 404 if (pLastTxInfo)
c55519ff 405 pLastTxInfo->USBDMANextVLD = 0;
c55519ff
GKH
406
407 /*
66cd8d6e
BZ
408 We need to copy SavedPad when following condition matched!
409 1. Not the last round of the TxQueue and
410 2. any match of following cases:
411 (1). The End Position of this bulk out is reach to the Currenct Write position and
412 the TxInfo and related header already write to the CurWritePosition.
413 =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
414
415 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
416 =>(ENextBulkOutPosition != CurWritePosition)
417 */
c55519ff 418 if ((bTxQLastRound == FALSE) &&
66cd8d6e
BZ
419 (((pHTTXContext->ENextBulkOutPosition ==
420 pHTTXContext->CurWritePosition)
421 && (pHTTXContext->CurWriteRealPos >
422 pHTTXContext->CurWritePosition))
423 || (pHTTXContext->ENextBulkOutPosition !=
424 pHTTXContext->CurWritePosition))
425 ) {
426 NdisMoveMemory(pHTTXContext->SavedPad,
427 &pWirelessPkt[pHTTXContext->
428 ENextBulkOutPosition], 8);
c55519ff 429 pHTTXContext->bCopySavePad = TRUE;
66cd8d6e 430 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) {
51126deb 431 u8 *pBuf = &pHTTXContext->SavedPad[0];
66cd8d6e
BZ
432 DBGPRINT_RAW(RT_DEBUG_ERROR,
433 ("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
434 pBuf[0], pBuf[1], pBuf[2], pBuf[3],
435 pBuf[4], pBuf[5], pBuf[6], pBuf[7],
436 pHTTXContext->CurWritePosition,
437 pHTTXContext->CurWriteRealPos,
438 pHTTXContext->bCurWriting,
439 pHTTXContext->NextBulkOutPosition,
440 TmpBulkEndPos, ThisBulkSize));
c55519ff
GKH
441
442 pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
66cd8d6e
BZ
443 DBGPRINT_RAW(RT_DEBUG_ERROR,
444 ("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n",
445 pBuf[0], pBuf[1], pBuf[2], pBuf[3],
446 pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
c55519ff 447 }
9f548a2a 448 /*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad)); */
c55519ff
GKH
449 }
450
451 if (pAd->bForcePrintTX == TRUE)
66cd8d6e
BZ
452 DBGPRINT(RT_DEBUG_TRACE,
453 ("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n",
454 ThisBulkSize, pHTTXContext->CurWritePosition,
455 pHTTXContext->NextBulkOutPosition,
456 pHTTXContext->ENextBulkOutPosition,
457 pHTTXContext->bCopySavePad));
9f548a2a 458 /*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 459
9f548a2a 460 /* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize. */
c55519ff
GKH
461 pAppendant = &pWirelessPkt[TmpBulkEndPos];
462 NdisZeroMemory(pAppendant, 8);
66cd8d6e
BZ
463 ThisBulkSize += 4;
464 pHTTXContext->LastOne = TRUE;
465 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
c55519ff 466 ThisBulkSize += 4;
c55519ff
GKH
467 pHTTXContext->BulkOutSize = ThisBulkSize;
468
469 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
470 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
471
9f548a2a 472 /* Init Tx context descriptor */
66cd8d6e
BZ
473 RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize,
474 (usb_complete_t) RTUSBBulkOutDataPacketComplete);
c55519ff
GKH
475
476 pUrb = pHTTXContext->pUrb;
699910dd
JP
477 ret = RTUSB_SUBMIT_URB(pUrb);
478 if (ret != 0) {
66cd8d6e
BZ
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
8a10a546 498void RTUSBBulkOutDataPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs)
c55519ff 499{
62eb734b
BZ
500 struct rt_ht_tx_context *pHTTXContext;
501 struct rt_rtmp_adapter *pAd;
8a10a546 502 struct os_cookie *pObj;
51126deb 503 u8 BulkOutPipeId;
c55519ff 504
62eb734b 505 pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
66cd8d6e 506 pAd = pHTTXContext->pAd;
8a10a546 507 pObj = (struct os_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*/
62eb734b 547void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd)
c55519ff 548{
62eb734b 549 struct rt_tx_context *pNullContext = &(pAd->NullContext);
66cd8d6e
BZ
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;
699910dd
JP
576 ret = RTUSB_SUBMIT_URB(pUrb);
577 if (ret != 0) {
c55519ff
GKH
578 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
579 pAd->BulkOutPending[0] = FALSE;
580 pAd->watchDogTxPendingCnt[0] = 0;
581 pNullContext->IRPPending = FALSE;
582 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
583
66cd8d6e
BZ
584 DBGPRINT(RT_DEBUG_ERROR,
585 ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n",
586 ret));
c55519ff
GKH
587 return;
588 }
589
590}
591
9f548a2a 592/* NULL frame use BulkOutPipeId = 0 */
8a10a546 593void RTUSBBulkOutNullFrameComplete(struct urb *pUrb, struct pt_regs * pt_regs)
c55519ff 594{
62eb734b
BZ
595 struct rt_rtmp_adapter *pAd;
596 struct rt_tx_context *pNullContext;
51126deb 597 int Status;
8a10a546 598 struct os_cookie *pObj;
c55519ff 599
62eb734b 600 pNullContext = (struct rt_tx_context *)pUrb->context;
66cd8d6e
BZ
601 pAd = pNullContext->pAd;
602 Status = pUrb->status;
c55519ff 603
8a10a546 604 pObj = (struct os_cookie *)pAd->OS_Cookie;
c55519ff
GKH
605 pObj->null_frame_complete_task.data = (unsigned long)pUrb;
606 tasklet_hi_schedule(&pObj->null_frame_complete_task);
c55519ff
GKH
607}
608
c55519ff
GKH
609/*
610 ========================================================================
611
612 Routine Description:
613
614 Arguments:
615
616 Return Value:
617
618 Note: MLME use BulkOutPipeId = 0
619
620 ========================================================================
621*/
62eb734b 622void RTUSBBulkOutMLMEPacket(struct rt_rtmp_adapter *pAd, u8 Index)
c55519ff 623{
62eb734b 624 struct rt_tx_context *pMLMEContext;
66cd8d6e
BZ
625 PURB pUrb;
626 int ret = 0;
627 unsigned long IrqFlags;
c55519ff 628
66cd8d6e 629 pMLMEContext =
62eb734b 630 (struct rt_tx_context *)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
c55519ff
GKH
631 pUrb = pMLMEContext->pUrb;
632
633 if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
66cd8d6e
BZ
634 (pMLMEContext->InUse == FALSE) ||
635 (pMLMEContext->bWaitingBulkOut == FALSE)) {
c55519ff 636
9f548a2a 637 /* Clear MLME bulk flag */
c55519ff
GKH
638 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
639
640 return;
641 }
642
c55519ff 643 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
66cd8d6e
BZ
644 if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE)
645 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
c55519ff
GKH
646 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
647 return;
648 }
649
650 pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
651 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
652 pMLMEContext->IRPPending = TRUE;
653 pMLMEContext->bWaitingBulkOut = FALSE;
654 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
655
9f548a2a 656 /* Increase Total transmit byte counter */
66cd8d6e 657 pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
c55519ff 658
9f548a2a 659 /* Clear MLME bulk flag */
c55519ff
GKH
660 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
661
9f548a2a 662 /* Init Tx context descriptor */
66cd8d6e
BZ
663 RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX,
664 (usb_complete_t) RTUSBBulkOutMLMEPacketComplete);
c55519ff 665
9f548a2a 666 /*For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping. */
66cd8d6e 667 pUrb->transfer_dma = 0;
c55519ff 668 pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
c55519ff
GKH
669
670 pUrb = pMLMEContext->pUrb;
699910dd
JP
671 ret = RTUSB_SUBMIT_URB(pUrb);
672 if (ret != 0) {
66cd8d6e
BZ
673 DBGPRINT(RT_DEBUG_ERROR,
674 ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n",
675 ret));
c55519ff
GKH
676 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
677 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
678 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
679 pMLMEContext->IRPPending = FALSE;
680 pMLMEContext->bWaitingBulkOut = TRUE;
681 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
682
683 return;
684 }
9f548a2a
BZ
685 /*DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n")); */
686/* printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx); */
c55519ff
GKH
687}
688
8a10a546 689void RTUSBBulkOutMLMEPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs)
c55519ff 690{
62eb734b
BZ
691 struct rt_tx_context *pMLMEContext;
692 struct rt_rtmp_adapter *pAd;
51126deb 693 int Status;
8a10a546 694 struct os_cookie *pObj;
66cd8d6e 695 int index;
c55519ff 696
9f548a2a 697 /*DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n")); */
62eb734b 698 pMLMEContext = (struct rt_tx_context *)pUrb->context;
66cd8d6e 699 pAd = pMLMEContext->pAd;
8a10a546 700 pObj = (struct os_cookie *)pAd->OS_Cookie;
66cd8d6e
BZ
701 Status = pUrb->status;
702 index = pMLMEContext->SelfIdx;
c55519ff 703
c55519ff
GKH
704 pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
705 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
c55519ff
GKH
706}
707
c55519ff
GKH
708/*
709 ========================================================================
710
711 Routine Description:
712
713 Arguments:
714
715 Return Value:
716
717 Note: PsPoll use BulkOutPipeId = 0
718
719 ========================================================================
720*/
62eb734b 721void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd)
c55519ff 722{
62eb734b 723 struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext);
66cd8d6e
BZ
724 PURB pUrb;
725 int ret = 0;
726 unsigned long IrqFlags;
c55519ff
GKH
727
728 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
66cd8d6e
BZ
729 if ((pAd->BulkOutPending[0] == TRUE)
730 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
c55519ff
GKH
731 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
732 return;
733 }
734 pAd->BulkOutPending[0] = TRUE;
735 pAd->watchDogTxPendingCnt[0] = 1;
736 pPsPollContext->IRPPending = TRUE;
737 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
738
9f548a2a 739 /* Clear PS-Poll bulk flag */
c55519ff
GKH
740 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
741
9f548a2a 742 /* Init Tx context descriptor */
66cd8d6e
BZ
743 RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX,
744 (usb_complete_t) RTUSBBulkOutPsPollComplete);
c55519ff
GKH
745
746 pUrb = pPsPollContext->pUrb;
699910dd
JP
747 ret = RTUSB_SUBMIT_URB(pUrb);
748 if (ret != 0) {
c55519ff
GKH
749 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
750 pAd->BulkOutPending[0] = FALSE;
751 pAd->watchDogTxPendingCnt[0] = 0;
752 pPsPollContext->IRPPending = FALSE;
753 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
754
66cd8d6e
BZ
755 DBGPRINT(RT_DEBUG_ERROR,
756 ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n",
757 ret));
c55519ff
GKH
758 return;
759 }
760
761}
762
9f548a2a 763/* PS-Poll frame use BulkOutPipeId = 0 */
8a10a546 764void RTUSBBulkOutPsPollComplete(struct urb *pUrb, struct pt_regs * pt_regs)
c55519ff 765{
62eb734b
BZ
766 struct rt_rtmp_adapter *pAd;
767 struct rt_tx_context *pPsPollContext;
51126deb 768 int Status;
8a10a546 769 struct os_cookie *pObj;
c55519ff 770
62eb734b 771 pPsPollContext = (struct rt_tx_context *)pUrb->context;
c55519ff
GKH
772 pAd = pPsPollContext->pAd;
773 Status = pUrb->status;
774
8a10a546 775 pObj = (struct os_cookie *)pAd->OS_Cookie;
c55519ff
GKH
776 pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
777 tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
c55519ff
GKH
778}
779
62eb734b 780void DoBulkIn(struct rt_rtmp_adapter *pAd)
c55519ff 781{
62eb734b 782 struct rt_rx_context *pRxContext;
66cd8d6e
BZ
783 PURB pUrb;
784 int ret = 0;
785 unsigned long IrqFlags;
c55519ff
GKH
786
787 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
788 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
66cd8d6e
BZ
789 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE)
790 || (pRxContext->InUse == TRUE)) {
c55519ff
GKH
791 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
792 return;
793 }
794 pRxContext->InUse = TRUE;
795 pRxContext->IRPPending = TRUE;
796 pAd->PendingRx++;
797 pAd->BulkInReq++;
798 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
799
9f548a2a 800 /* Init Rx context descriptor */
c55519ff
GKH
801 NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
802 RTUSBInitRxDesc(pAd, pRxContext);
803
804 pUrb = pRxContext->pUrb;
699910dd
JP
805 ret = RTUSB_SUBMIT_URB(pUrb);
806 if (ret != 0) { /* fail */
c55519ff
GKH
807
808 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
809 pRxContext->InUse = FALSE;
810 pRxContext->IRPPending = FALSE;
811 pAd->PendingRx--;
812 pAd->BulkInReq--;
813 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
66cd8d6e
BZ
814 DBGPRINT(RT_DEBUG_ERROR,
815 ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
9f548a2a 816 } else { /* success */
c55519ff 817 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
9f548a2a 818 /*printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex); */
c55519ff
GKH
819 }
820}
821
c55519ff
GKH
822/*
823 ========================================================================
824
825 Routine Description:
826 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
827 to USB. It checks if an Rx Descriptor is available and passes the
828 the coresponding buffer to be filled. If no descriptor is available
829 fails the request. When setting the completion routine we pass our
830 Adapter Object as Context.
831
832 Arguments:
833
834 Return Value:
835 TRUE found matched tuple cache
836 FALSE no matched found
837
838 Note:
839
840 ========================================================================
841*/
842#define fRTMP_ADAPTER_NEED_STOP_RX \
843 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
844 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
845 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
846
847#define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
848 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
849 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
850 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
851
62eb734b 852void RTUSBBulkReceive(struct rt_rtmp_adapter *pAd)
c55519ff 853{
62eb734b 854 struct rt_rx_context *pRxContext;
66cd8d6e 855 unsigned long IrqFlags;
c55519ff
GKH
856
857 /* sanity check */
858 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
859 return;
860
66cd8d6e 861 while (1) {
c55519ff
GKH
862
863 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
864 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
66cd8d6e
BZ
865 if (((pRxContext->InUse == FALSE)
866 && (pRxContext->Readable == TRUE))
867 && (pRxContext->bRxHandling == FALSE)) {
c55519ff
GKH
868 pRxContext->bRxHandling = TRUE;
869 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
870
9f548a2a 871 /* read RxContext, Since not */
303ee97d 872 STARxDoneInterruptHandle(pAd, TRUE);
c55519ff 873
9f548a2a 874 /* Finish to handle this bulkIn buffer. */
c55519ff
GKH
875 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
876 pRxContext->BulkInOffset = 0;
877 pRxContext->Readable = FALSE;
878 pRxContext->bRxHandling = FALSE;
879 pAd->ReadPosition = 0;
880 pAd->TransferBufferLength = 0;
66cd8d6e
BZ
881 INC_RING_INDEX(pAd->NextRxBulkInReadIndex,
882 RX_RING_SIZE);
c55519ff
GKH
883 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
884
66cd8d6e 885 } else {
c55519ff
GKH
886 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
887 break;
888 }
889 }
890
891 if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
892 DoBulkIn(pAd);
893
894}
895
c55519ff
GKH
896/*
897 ========================================================================
898
899 Routine Description:
900 This routine process Rx Irp and call rx complete function.
901
902 Arguments:
903 DeviceObject Pointer to the device object for next lower
904 device. DeviceObject passed in here belongs to
905 the next lower driver in the stack because we
906 were invoked via IoCallDriver in USB_RxPacket
907 AND it is not OUR device object
908 Irp Ptr to completed IRP
909 Context Ptr to our Adapter object (context specified
910 in IoSetCompletionRoutine
911
912 Return Value:
913 Always returns STATUS_MORE_PROCESSING_REQUIRED
914
915 Note:
916 Always returns STATUS_MORE_PROCESSING_REQUIRED
917 ========================================================================
918*/
8a10a546 919void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs)
c55519ff 920{
9f548a2a
BZ
921 /* use a receive tasklet to handle received packets; */
922 /* or sometimes hardware IRQ will be disabled here, so we can not */
923 /* use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :< */
62eb734b
BZ
924 struct rt_rx_context *pRxContext;
925 struct rt_rtmp_adapter *pAd;
8a10a546 926 struct os_cookie *pObj;
c55519ff 927
62eb734b 928 pRxContext = (struct rt_rx_context *)pUrb->context;
66cd8d6e 929 pAd = pRxContext->pAd;
8a10a546 930 pObj = (struct os_cookie *)pAd->OS_Cookie;
c55519ff
GKH
931
932 pObj->rx_done_task.data = (unsigned long)pUrb;
933 tasklet_hi_schedule(&pObj->rx_done_task);
934
935}
936
c55519ff
GKH
937/*
938 ========================================================================
939
940 Routine Description:
941
942 Arguments:
943
944 Return Value:
945
946 Note:
947
948 ========================================================================
949*/
62eb734b 950void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd)
c55519ff 951{
9f548a2a 952 /* BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged. */
66cd8d6e
BZ
953 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)
954 ) {
9f548a2a 955 /* 2. PS-Poll frame is next */
d24e4497 956 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
c55519ff 957 RTUSBBulkOutPsPoll(pAd);
9f548a2a 958 /* 5. Mlme frame is next */
ca97b838 959 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) ||
66cd8d6e 960 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) {
c55519ff
GKH
961 RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
962 }
9f548a2a 963 /* 6. Data frame normal is next */
66cd8d6e
BZ
964 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL)) {
965 if (((!RTMP_TEST_FLAG
966 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
967 ||
968 (!OPSTATUS_TEST_FLAG
969 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
970 )) {
971 RTUSBBulkOutDataPacket(pAd, 0,
972 pAd->
973 NextBulkOutIndex[0]);
c55519ff
GKH
974 }
975 }
66cd8d6e
BZ
976 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2)) {
977 if (((!RTMP_TEST_FLAG
978 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
979 ||
980 (!OPSTATUS_TEST_FLAG
981 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
982 )) {
983 RTUSBBulkOutDataPacket(pAd, 1,
984 pAd->
985 NextBulkOutIndex[1]);
c55519ff
GKH
986 }
987 }
66cd8d6e
BZ
988 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3)) {
989 if (((!RTMP_TEST_FLAG
990 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
991 ||
992 (!OPSTATUS_TEST_FLAG
993 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
994 )) {
995 RTUSBBulkOutDataPacket(pAd, 2,
996 pAd->
997 NextBulkOutIndex[2]);
c55519ff
GKH
998 }
999 }
66cd8d6e
BZ
1000 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4)) {
1001 if (((!RTMP_TEST_FLAG
1002 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1003 ||
1004 (!OPSTATUS_TEST_FLAG
1005 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1006 )) {
1007 RTUSBBulkOutDataPacket(pAd, 3,
1008 pAd->
1009 NextBulkOutIndex[3]);
c55519ff
GKH
1010 }
1011 }
9f548a2a 1012 /* 7. Null frame is the last */
66cd8d6e
BZ
1013 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) {
1014 if (!RTMP_TEST_FLAG
1015 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
c55519ff
GKH
1016 RTUSBBulkOutNullFrame(pAd);
1017 }
1018 }
25985edc 1019 /* 8. No data available */
d24e4497
AG
1020 else
1021 ;
c55519ff 1022 }
c55519ff
GKH
1023}
1024
1025/*
1026 ========================================================================
1027
1028 Routine Description:
1029 Call from Reset action after BulkOut failed.
1030 Arguments:
1031
1032 Return Value:
1033
1034 Note:
1035
1036 ========================================================================
1037*/
62eb734b 1038void RTUSBCleanUpDataBulkOutQueue(struct rt_rtmp_adapter *pAd)
c55519ff 1039{
51126deb 1040 u8 Idx;
62eb734b 1041 struct rt_ht_tx_context *pTxContext;
c55519ff
GKH
1042
1043 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1044
66cd8d6e 1045 for (Idx = 0; Idx < 4; Idx++) {
c55519ff
GKH
1046 pTxContext = &pAd->TxContext[Idx];
1047
1048 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1049 pTxContext->LastOne = FALSE;
1050 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1051 pAd->BulkOutPending[Idx] = FALSE;
1052 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1053 }
1054
1055 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1056}
1057
1058/*
1059 ========================================================================
1060
1061 Routine Description:
1062
1063 Arguments:
1064
1065 Return Value:
1066
1067 Note:
1068
1069 ========================================================================
1070*/
62eb734b 1071void RTUSBCleanUpMLMEBulkOutQueue(struct rt_rtmp_adapter *pAd)
c55519ff
GKH
1072{
1073 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
c55519ff
GKH
1074 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1075}
1076
c55519ff
GKH
1077/*
1078 ========================================================================
1079
1080 Routine Description:
1081
1082 Arguments:
1083
1084 Return Value:
1085
c55519ff
GKH
1086 Note:
1087
1088 ========================================================================
1089*/
62eb734b 1090void RTUSBCancelPendingIRPs(struct rt_rtmp_adapter *pAd)
c55519ff
GKH
1091{
1092 RTUSBCancelPendingBulkInIRP(pAd);
1093 RTUSBCancelPendingBulkOutIRP(pAd);
1094}
1095
1096/*
1097 ========================================================================
1098
1099 Routine Description:
1100
1101 Arguments:
1102
1103 Return Value:
1104
1105 Note:
1106
1107 ========================================================================
1108*/
62eb734b 1109void RTUSBCancelPendingBulkInIRP(struct rt_rtmp_adapter *pAd)
c55519ff 1110{
62eb734b 1111 struct rt_rx_context *pRxContext;
51126deb 1112 u32 i;
c55519ff
GKH
1113
1114 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
66cd8d6e 1115 for (i = 0; i < (RX_RING_SIZE); i++) {
c55519ff 1116 pRxContext = &(pAd->RxContext[i]);
66cd8d6e 1117 if (pRxContext->IRPPending == TRUE) {
c55519ff
GKH
1118 RTUSB_UNLINK_URB(pRxContext->pUrb);
1119 pRxContext->IRPPending = FALSE;
1120 pRxContext->InUse = FALSE;
9f548a2a
BZ
1121 /*NdisInterlockedDecrement(&pAd->PendingRx); */
1122 /*pAd->PendingRx--; */
c55519ff
GKH
1123 }
1124 }
1125 DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1126}
1127
c55519ff
GKH
1128/*
1129 ========================================================================
1130
1131 Routine Description:
1132
1133 Arguments:
1134
1135 Return Value:
1136
1137 Note:
1138
1139 ========================================================================
1140*/
62eb734b 1141void RTUSBCancelPendingBulkOutIRP(struct rt_rtmp_adapter *pAd)
c55519ff 1142{
62eb734b
BZ
1143 struct rt_ht_tx_context *pHTTXContext;
1144 struct rt_tx_context *pMLMEContext;
1145 struct rt_tx_context *pBeaconContext;
1146 struct rt_tx_context *pNullContext;
1147 struct rt_tx_context *pPsPollContext;
1148 struct rt_tx_context *pRTSContext;
51126deb 1149 u32 i, Idx;
9f548a2a 1150/* unsigned int IrqFlags; */
8a10a546 1151/* spinlock_t *pLock; */
9f548a2a 1152/* BOOLEAN *pPending; */
66cd8d6e 1153
9f548a2a
BZ
1154/* pLock = &pAd->BulkOutLock[MGMTPIPEIDX]; */
1155/* pPending = &pAd->BulkOutPending[MGMTPIPEIDX]; */
66cd8d6e
BZ
1156
1157 for (Idx = 0; Idx < 4; Idx++) {
c55519ff
GKH
1158 pHTTXContext = &(pAd->TxContext[Idx]);
1159
66cd8d6e 1160 if (pHTTXContext->IRPPending == TRUE) {
c55519ff 1161
9f548a2a
BZ
1162 /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
1163 /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
1164 /* when the last IRP on the list has been cancelled; that's how we exit this loop */
1165 /* */
c55519ff
GKH
1166
1167 RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1168
9f548a2a 1169 /* Sleep 200 microseconds to give cancellation time to work */
c55519ff
GKH
1170 RTMPusecDelay(200);
1171 }
1172
c55519ff
GKH
1173 pAd->BulkOutPending[Idx] = FALSE;
1174 }
1175
9f548a2a 1176 /*RTMP_IRQ_LOCK(pLock, IrqFlags); */
66cd8d6e 1177 for (i = 0; i < MGMT_RING_SIZE; i++) {
62eb734b 1178 pMLMEContext = (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
66cd8d6e 1179 if (pMLMEContext && (pMLMEContext->IRPPending == TRUE)) {
c55519ff 1180
9f548a2a
BZ
1181 /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
1182 /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
1183 /* when the last IRP on the list has been cancelled; that's how we exit this loop */
1184 /* */
c55519ff
GKH
1185
1186 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1187 pMLMEContext->IRPPending = FALSE;
1188
9f548a2a 1189 /* Sleep 200 microsecs to give cancellation time to work */
c55519ff
GKH
1190 RTMPusecDelay(200);
1191 }
1192 }
1193 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
9f548a2a 1194 /*RTMP_IRQ_UNLOCK(pLock, IrqFlags); */
c55519ff 1195
66cd8d6e 1196 for (i = 0; i < BEACON_RING_SIZE; i++) {
c55519ff
GKH
1197 pBeaconContext = &(pAd->BeaconContext[i]);
1198
66cd8d6e 1199 if (pBeaconContext->IRPPending == TRUE) {
c55519ff 1200
9f548a2a
BZ
1201 /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
1202 /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
1203 /* when the last IRP on the list has been cancelled; that's how we exit this loop */
1204 /* */
c55519ff
GKH
1205
1206 RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1207
9f548a2a 1208 /* Sleep 200 microsecs to give cancellation time to work */
c55519ff
GKH
1209 RTMPusecDelay(200);
1210 }
1211 }
1212
1213 pNullContext = &(pAd->NullContext);
1214 if (pNullContext->IRPPending == TRUE)
1215 RTUSB_UNLINK_URB(pNullContext->pUrb);
1216
1217 pRTSContext = &(pAd->RTSContext);
1218 if (pRTSContext->IRPPending == TRUE)
1219 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1220
1221 pPsPollContext = &(pAd->PsPollContext);
1222 if (pPsPollContext->IRPPending == TRUE)
1223 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1224
66cd8d6e 1225 for (Idx = 0; Idx < 4; Idx++) {
c55519ff
GKH
1226 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1227 pAd->BulkOutPending[Idx] = FALSE;
1228 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1229 }
1230}
1231
9f548a2a 1232#endif /* RTMP_MAC_USB // */