2
*************************************************************************
4
* 5F., No.36, Taiyuan St., Jhubei City,
8
* (c) Copyright 2002-2007, Ralink Technology, Inc.
10
* This program is free software; you can redistribute it and/or modify *
11
* it under the terms of the GNU General Public License as published by *
12
* the Free Software Foundation; either version 2 of the License, or *
13
* (at your option) any later version. *
15
* This program is distributed in the hope that it will be useful, *
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18
* GNU General Public License for more details. *
20
* You should have received a copy of the GNU General Public License *
21
* along with this program; if not, write to the *
22
* Free Software Foundation, Inc., *
23
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25
*************************************************************************
34
-------- ---------- ----------------------------------------------
35
Name Date Modification logs
36
Paul Lin 06-25-2004 created
42
#include "../rt_config.h"
43
/* Match total 6 bulkout endpoint to corresponding queue. */
45
{ FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT };
47
/*static BOOLEAN SingleBulkOut = FALSE; */
49
void RTUSB_FILL_BULK_URB(struct urb *pUrb,
50
struct usb_device *pUsb_Dev,
51
unsigned int bulkpipe,
53
int BufSize, usb_complete_t Complete, void *pContext)
56
usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize,
57
(usb_complete_t) Complete, pContext);
61
void RTUSBInitTxDesc(struct rt_rtmp_adapter *pAd,
62
struct rt_tx_context *pTxContext,
63
u8 BulkOutPipeId, IN usb_complete_t Func)
67
struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
69
pUrb = pTxContext->pUrb;
72
/* Store BulkOut PipeId */
73
pTxContext->BulkOutPipeId = BulkOutPipeId;
75
if (pTxContext->bAggregatible) {
76
pSrc = &pTxContext->TransferBuffer->Aggregation[2];
79
(u8 *)pTxContext->TransferBuffer->field.WirelessPacket;
82
/*Initialize a tx bulk urb */
83
RTUSB_FILL_BULK_URB(pUrb,
85
usb_sndbulkpipe(pObj->pUsb_Dev,
86
pAd->BulkOutEpAddr[BulkOutPipeId]),
87
pSrc, pTxContext->BulkOutSize, Func, pTxContext);
89
if (pTxContext->bAggregatible)
91
(pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
93
pUrb->transfer_dma = pTxContext->data_dma;
95
pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
99
void RTUSBInitHTTxDesc(struct rt_rtmp_adapter *pAd,
100
struct rt_ht_tx_context *pTxContext,
102
unsigned long BulkOutSize, IN usb_complete_t Func)
106
struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
108
pUrb = pTxContext->pUrb;
111
/* Store BulkOut PipeId */
112
pTxContext->BulkOutPipeId = BulkOutPipeId;
115
&pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->
116
NextBulkOutPosition];
118
/*Initialize a tx bulk urb */
119
RTUSB_FILL_BULK_URB(pUrb,
121
usb_sndbulkpipe(pObj->pUsb_Dev,
122
pAd->BulkOutEpAddr[BulkOutPipeId]),
123
pSrc, BulkOutSize, Func, pTxContext);
126
(pTxContext->data_dma + pTxContext->NextBulkOutPosition);
127
pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
131
void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext)
134
struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
135
unsigned long RX_bulk_size;
137
pUrb = pRxContext->pUrb;
140
if (pAd->BulkInMaxPacketSize == 64)
143
RX_bulk_size = MAX_RXBULK_SIZE;
145
/*Initialize a rx bulk urb */
146
RTUSB_FILL_BULK_URB(pUrb,
148
usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
150
TransferBuffer[pAd->NextRxBulkInPosition]),
151
RX_bulk_size - (pAd->NextRxBulkInPosition),
152
(usb_complete_t) RTUSBBulkRxComplete,
155
pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
156
pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
161
========================================================================
171
========================================================================
174
#define BULK_OUT_LOCK(pLock, IrqFlags) \
175
if (1 /*!(in_interrupt() & 0xffff0000)*/) \
176
RTMP_IRQ_LOCK((pLock), IrqFlags);
178
#define BULK_OUT_UNLOCK(pLock, IrqFlags) \
179
if (1 /*!(in_interrupt() & 0xffff0000)*/) \
180
RTMP_IRQ_UNLOCK((pLock), IrqFlags);
182
void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd,
183
u8 BulkOutPipeId, u8 Index)
186
struct rt_ht_tx_context *pHTTXContext;
189
struct rt_txinfo *pTxInfo, *pLastTxInfo = NULL;
190
struct rt_txwi *pTxWI;
191
unsigned long TmpBulkEndPos, ThisBulkSize;
192
unsigned long IrqFlags = 0, IrqFlags2 = 0;
193
u8 *pWirelessPkt, *pAppendant;
194
BOOLEAN bTxQLastRound = FALSE;
195
u8 allzero[4] = { 0x0, 0x0, 0x0, 0x0 };
197
BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
198
if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE)
199
|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
200
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
203
pAd->BulkOutPending[BulkOutPipeId] = TRUE;
205
if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
207
pAd->BulkOutPending[BulkOutPipeId] = FALSE;
208
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
211
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
213
pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
215
BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
216
if ((pHTTXContext->ENextBulkOutPosition ==
217
pHTTXContext->CurWritePosition)
218
|| ((pHTTXContext->ENextBulkOutPosition - 8) ==
219
pHTTXContext->CurWritePosition)) {
220
BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId],
223
BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
224
pAd->BulkOutPending[BulkOutPipeId] = FALSE;
226
/* Clear Data flag */
227
RTUSB_CLEAR_BULK_FLAG(pAd,
228
(fRTUSB_BULK_OUT_DATA_FRAG <<
230
RTUSB_CLEAR_BULK_FLAG(pAd,
231
(fRTUSB_BULK_OUT_DATA_NORMAL <<
234
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
237
/* Clear Data flag */
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));
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)); */
246
pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
248
TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
249
pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
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]));
264
NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos],
265
pHTTXContext->SavedPad, 8);
266
pHTTXContext->bCopySavePad = FALSE;
267
if (pAd->bForcePrintTX == TRUE)
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));
276
pTxInfo = (struct rt_txinfo *)&pWirelessPkt[TmpBulkEndPos];
278
(struct rt_txwi *)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
280
if (pAd->bForcePrintTX == TRUE)
281
DBGPRINT(RT_DEBUG_TRACE,
282
("RTUSBBulkOutDataPacket AMPDU = %d.\n",
285
/* add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items */
286
/*if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */
287
if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) {
288
if (((ThisBulkSize & 0xffff8000) != 0)
289
|| ((ThisBulkSize & 0x1000) == 0x1000)) {
290
/* Limit BulkOut size to about 4k bytes. */
291
pHTTXContext->ENextBulkOutPosition =
295
if (((pAd->BulkOutMaxPacketSize < 512)
296
&& ((ThisBulkSize & 0xfffff800) !=
298
/*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */
300
/* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */
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. */
302
pHTTXContext->ENextBulkOutPosition =
309
if (((ThisBulkSize & 0xffff8000) != 0) || ((ThisBulkSize & 0x6000) == 0x6000)) { /* Limit BulkOut size to about 24k bytes. */
310
pHTTXContext->ENextBulkOutPosition =
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 performance in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */
315
pHTTXContext->ENextBulkOutPosition =
321
if (TmpBulkEndPos == pHTTXContext->CurWritePosition) {
322
pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
326
if (pTxInfo->QSEL != FIFO_EDCA) {
327
DBGPRINT(RT_DEBUG_ERROR,
328
("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n",
329
__func__, 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:",
337
(u8 *)&pWirelessPkt[TmpBulkEndPos],
338
(pHTTXContext->CurWritePosition -
339
pHTTXContext->NextBulkOutPosition));
342
if (pTxInfo->USBDMATxPktLen <= 8) {
343
BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId],
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));
353
DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE */
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]));
365
pAd->bForcePrintTX = TRUE;
366
BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId],
368
pAd->BulkOutPending[BulkOutPipeId] = FALSE;
369
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId],
371
/*DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen)); */
374
/* Increase Total transmit byte counter */
375
pAd->RalinkCounters.OneSecTransmittedByteCount +=
376
pTxWI->MPDUtotalByteCount;
377
pAd->RalinkCounters.TransmittedByteCount +=
378
pTxWI->MPDUtotalByteCount;
380
pLastTxInfo = pTxInfo;
382
/* Make sure we use EDCA QUEUE. */
383
pTxInfo->QSEL = FIFO_EDCA;
384
ThisBulkSize += (pTxInfo->USBDMATxPktLen + 4);
385
TmpBulkEndPos += (pTxInfo->USBDMATxPktLen + 4);
387
if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
388
pTxInfo->USBDMANextVLD = 1;
390
if (pTxInfo->SwUseLastRound == 1) {
391
if (pHTTXContext->CurWritePosition == 8)
392
pTxInfo->USBDMANextVLD = 0;
393
pTxInfo->SwUseLastRound = 0;
395
bTxQLastRound = TRUE;
396
pHTTXContext->ENextBulkOutPosition = 8;
403
/* adjust the pTxInfo->USBDMANextVLD value of last pTxInfo. */
405
pLastTxInfo->USBDMANextVLD = 0;
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)
415
(2). The EndPosition of the bulk out is not reach to the Current Write Position.
416
=>(ENextBulkOutPosition != CurWritePosition)
418
if ((bTxQLastRound == FALSE) &&
419
(((pHTTXContext->ENextBulkOutPosition ==
420
pHTTXContext->CurWritePosition)
421
&& (pHTTXContext->CurWriteRealPos >
422
pHTTXContext->CurWritePosition))
423
|| (pHTTXContext->ENextBulkOutPosition !=
424
pHTTXContext->CurWritePosition))
426
NdisMoveMemory(pHTTXContext->SavedPad,
427
&pWirelessPkt[pHTTXContext->
428
ENextBulkOutPosition], 8);
429
pHTTXContext->bCopySavePad = TRUE;
430
if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) {
431
u8 *pBuf = &pHTTXContext->SavedPad[0];
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));
442
pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
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]));
448
/*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad)); */
451
if (pAd->bForcePrintTX == TRUE)
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));
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)); */
460
/* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize. */
461
pAppendant = &pWirelessPkt[TmpBulkEndPos];
462
NdisZeroMemory(pAppendant, 8);
464
pHTTXContext->LastOne = TRUE;
465
if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
467
pHTTXContext->BulkOutSize = ThisBulkSize;
469
pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
470
BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
472
/* Init Tx context descriptor */
473
RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize,
474
(usb_complete_t) RTUSBBulkOutDataPacketComplete);
476
pUrb = pHTTXContext->pUrb;
477
ret = RTUSB_SUBMIT_URB(pUrb);
479
DBGPRINT(RT_DEBUG_ERROR,
480
("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n",
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);
491
BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
492
pHTTXContext->IRPPending = TRUE;
493
BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
498
void RTUSBBulkOutDataPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs)
500
struct rt_ht_tx_context *pHTTXContext;
501
struct rt_rtmp_adapter *pAd;
502
struct os_cookie *pObj;
505
pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
506
pAd = pHTTXContext->pAd;
507
pObj = (struct os_cookie *)pAd->OS_Cookie;
509
/* Store BulkOut PipeId */
510
BulkOutPipeId = pHTTXContext->BulkOutPipeId;
511
pAd->BulkOutDataOneSecCount++;
513
switch (BulkOutPipeId) {
515
pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
516
tasklet_hi_schedule(&pObj->ac0_dma_done_task);
519
pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
520
tasklet_hi_schedule(&pObj->ac1_dma_done_task);
523
pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
524
tasklet_hi_schedule(&pObj->ac2_dma_done_task);
527
pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
528
tasklet_hi_schedule(&pObj->ac3_dma_done_task);
535
========================================================================
543
Note: NULL frame use BulkOutPipeId = 0
545
========================================================================
547
void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd)
549
struct rt_tx_context *pNullContext = &(pAd->NullContext);
552
unsigned long IrqFlags;
554
RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
555
if ((pAd->BulkOutPending[0] == TRUE)
556
|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
557
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
560
pAd->BulkOutPending[0] = TRUE;
561
pAd->watchDogTxPendingCnt[0] = 1;
562
pNullContext->IRPPending = TRUE;
563
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
565
/* Increase Total transmit byte counter */
566
pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
568
/* Clear Null frame bulk flag */
569
RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
571
/* Init Tx context descriptor */
572
RTUSBInitTxDesc(pAd, pNullContext, 0,
573
(usb_complete_t) RTUSBBulkOutNullFrameComplete);
575
pUrb = pNullContext->pUrb;
576
ret = RTUSB_SUBMIT_URB(pUrb);
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);
584
DBGPRINT(RT_DEBUG_ERROR,
585
("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n",
592
/* NULL frame use BulkOutPipeId = 0 */
593
void RTUSBBulkOutNullFrameComplete(struct urb *pUrb, struct pt_regs * pt_regs)
595
struct rt_rtmp_adapter *pAd;
596
struct rt_tx_context *pNullContext;
598
struct os_cookie *pObj;
600
pNullContext = (struct rt_tx_context *)pUrb->context;
601
pAd = pNullContext->pAd;
602
Status = pUrb->status;
604
pObj = (struct os_cookie *)pAd->OS_Cookie;
605
pObj->null_frame_complete_task.data = (unsigned long)pUrb;
606
tasklet_hi_schedule(&pObj->null_frame_complete_task);
610
========================================================================
618
Note: MLME use BulkOutPipeId = 0
620
========================================================================
622
void RTUSBBulkOutMLMEPacket(struct rt_rtmp_adapter *pAd, u8 Index)
624
struct rt_tx_context *pMLMEContext;
627
unsigned long IrqFlags;
630
(struct rt_tx_context *)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
631
pUrb = pMLMEContext->pUrb;
633
if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
634
(pMLMEContext->InUse == FALSE) ||
635
(pMLMEContext->bWaitingBulkOut == FALSE)) {
637
/* Clear MLME bulk flag */
638
RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
643
RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
644
if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE)
645
|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
646
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
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);
656
/* Increase Total transmit byte counter */
657
pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
659
/* Clear MLME bulk flag */
660
RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
662
/* Init Tx context descriptor */
663
RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX,
664
(usb_complete_t) RTUSBBulkOutMLMEPacketComplete);
666
/*For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping. */
667
pUrb->transfer_dma = 0;
668
pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
670
pUrb = pMLMEContext->pUrb;
671
ret = RTUSB_SUBMIT_URB(pUrb);
673
DBGPRINT(RT_DEBUG_ERROR,
674
("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n",
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);
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); */
689
void RTUSBBulkOutMLMEPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs)
691
struct rt_tx_context *pMLMEContext;
692
struct rt_rtmp_adapter *pAd;
694
struct os_cookie *pObj;
697
/*DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n")); */
698
pMLMEContext = (struct rt_tx_context *)pUrb->context;
699
pAd = pMLMEContext->pAd;
700
pObj = (struct os_cookie *)pAd->OS_Cookie;
701
Status = pUrb->status;
702
index = pMLMEContext->SelfIdx;
704
pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
705
tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
709
========================================================================
717
Note: PsPoll use BulkOutPipeId = 0
719
========================================================================
721
void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd)
723
struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext);
726
unsigned long IrqFlags;
728
RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
729
if ((pAd->BulkOutPending[0] == TRUE)
730
|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
731
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
734
pAd->BulkOutPending[0] = TRUE;
735
pAd->watchDogTxPendingCnt[0] = 1;
736
pPsPollContext->IRPPending = TRUE;
737
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
739
/* Clear PS-Poll bulk flag */
740
RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
742
/* Init Tx context descriptor */
743
RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX,
744
(usb_complete_t) RTUSBBulkOutPsPollComplete);
746
pUrb = pPsPollContext->pUrb;
747
ret = RTUSB_SUBMIT_URB(pUrb);
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);
755
DBGPRINT(RT_DEBUG_ERROR,
756
("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n",
763
/* PS-Poll frame use BulkOutPipeId = 0 */
764
void RTUSBBulkOutPsPollComplete(struct urb *pUrb, struct pt_regs * pt_regs)
766
struct rt_rtmp_adapter *pAd;
767
struct rt_tx_context *pPsPollContext;
769
struct os_cookie *pObj;
771
pPsPollContext = (struct rt_tx_context *)pUrb->context;
772
pAd = pPsPollContext->pAd;
773
Status = pUrb->status;
775
pObj = (struct os_cookie *)pAd->OS_Cookie;
776
pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
777
tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
780
void DoBulkIn(struct rt_rtmp_adapter *pAd)
782
struct rt_rx_context *pRxContext;
785
unsigned long IrqFlags;
787
RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
788
pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
789
if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE)
790
|| (pRxContext->InUse == TRUE)) {
791
RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
794
pRxContext->InUse = TRUE;
795
pRxContext->IRPPending = TRUE;
798
RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
800
/* Init Rx context descriptor */
801
NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
802
RTUSBInitRxDesc(pAd, pRxContext);
804
pUrb = pRxContext->pUrb;
805
ret = RTUSB_SUBMIT_URB(pUrb);
806
if (ret != 0) { /* fail */
808
RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
809
pRxContext->InUse = FALSE;
810
pRxContext->IRPPending = FALSE;
813
RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
814
DBGPRINT(RT_DEBUG_ERROR,
815
("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
816
} else { /* success */
817
ASSERT((pRxContext->InUse == pRxContext->IRPPending));
818
/*printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex); */
823
========================================================================
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.
835
TRUE found matched tuple cache
836
FALSE no matched found
840
========================================================================
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)
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)
852
void RTUSBBulkReceive(struct rt_rtmp_adapter *pAd)
854
struct rt_rx_context *pRxContext;
855
unsigned long IrqFlags;
858
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
863
RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
864
pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
865
if (((pRxContext->InUse == FALSE)
866
&& (pRxContext->Readable == TRUE))
867
&& (pRxContext->bRxHandling == FALSE)) {
868
pRxContext->bRxHandling = TRUE;
869
RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
871
/* read RxContext, Since not */
872
STARxDoneInterruptHandle(pAd, TRUE);
874
/* Finish to handle this bulkIn buffer. */
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;
881
INC_RING_INDEX(pAd->NextRxBulkInReadIndex,
883
RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
886
RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
891
if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
897
========================================================================
900
This routine process Rx Irp and call rx complete function.
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
913
Always returns STATUS_MORE_PROCESSING_REQUIRED
916
Always returns STATUS_MORE_PROCESSING_REQUIRED
917
========================================================================
919
void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs)
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. :< */
924
struct rt_rx_context *pRxContext;
925
struct rt_rtmp_adapter *pAd;
926
struct os_cookie *pObj;
928
pRxContext = (struct rt_rx_context *)pUrb->context;
929
pAd = pRxContext->pAd;
930
pObj = (struct os_cookie *)pAd->OS_Cookie;
932
pObj->rx_done_task.data = (unsigned long)pUrb;
933
tasklet_hi_schedule(&pObj->rx_done_task);
938
========================================================================
948
========================================================================
950
void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd)
952
/* BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged. */
953
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)
955
/* 2. PS-Poll frame is next */
956
if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
957
RTUSBBulkOutPsPoll(pAd);
958
/* 5. Mlme frame is next */
959
else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) ||
960
(pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) {
961
RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
963
/* 6. Data frame normal is next */
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))
969
(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
971
RTUSBBulkOutDataPacket(pAd, 0,
973
NextBulkOutIndex[0]);
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))
981
(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
983
RTUSBBulkOutDataPacket(pAd, 1,
985
NextBulkOutIndex[1]);
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))
993
(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
995
RTUSBBulkOutDataPacket(pAd, 2,
997
NextBulkOutIndex[2]);
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))
1004
(!OPSTATUS_TEST_FLAG
1005
(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1007
RTUSBBulkOutDataPacket(pAd, 3,
1009
NextBulkOutIndex[3]);
1012
/* 7. Null frame is the last */
1013
else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) {
1015
(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
1016
RTUSBBulkOutNullFrame(pAd);
1019
/* 8. No data available */
1026
========================================================================
1028
Routine Description:
1029
Call from Reset action after BulkOut failed.
1036
========================================================================
1038
void RTUSBCleanUpDataBulkOutQueue(struct rt_rtmp_adapter *pAd)
1041
struct rt_ht_tx_context *pTxContext;
1043
DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1045
for (Idx = 0; Idx < 4; Idx++) {
1046
pTxContext = &pAd->TxContext[Idx];
1048
pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1049
pTxContext->LastOne = FALSE;
1050
NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1051
pAd->BulkOutPending[Idx] = FALSE;
1052
NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1055
DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1059
========================================================================
1061
Routine Description:
1069
========================================================================
1071
void RTUSBCleanUpMLMEBulkOutQueue(struct rt_rtmp_adapter *pAd)
1073
DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
1074
DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1078
========================================================================
1080
Routine Description:
1088
========================================================================
1090
void RTUSBCancelPendingIRPs(struct rt_rtmp_adapter *pAd)
1092
RTUSBCancelPendingBulkInIRP(pAd);
1093
RTUSBCancelPendingBulkOutIRP(pAd);
1097
========================================================================
1099
Routine Description:
1107
========================================================================
1109
void RTUSBCancelPendingBulkInIRP(struct rt_rtmp_adapter *pAd)
1111
struct rt_rx_context *pRxContext;
1114
DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
1115
for (i = 0; i < (RX_RING_SIZE); i++) {
1116
pRxContext = &(pAd->RxContext[i]);
1117
if (pRxContext->IRPPending == TRUE) {
1118
RTUSB_UNLINK_URB(pRxContext->pUrb);
1119
pRxContext->IRPPending = FALSE;
1120
pRxContext->InUse = FALSE;
1121
/*NdisInterlockedDecrement(&pAd->PendingRx); */
1122
/*pAd->PendingRx--; */
1125
DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1129
========================================================================
1131
Routine Description:
1139
========================================================================
1141
void RTUSBCancelPendingBulkOutIRP(struct rt_rtmp_adapter *pAd)
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;
1150
/* unsigned int IrqFlags; */
1151
/* spinlock_t *pLock; */
1152
/* BOOLEAN *pPending; */
1154
/* pLock = &pAd->BulkOutLock[MGMTPIPEIDX]; */
1155
/* pPending = &pAd->BulkOutPending[MGMTPIPEIDX]; */
1157
for (Idx = 0; Idx < 4; Idx++) {
1158
pHTTXContext = &(pAd->TxContext[Idx]);
1160
if (pHTTXContext->IRPPending == TRUE) {
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 */
1167
RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1169
/* Sleep 200 microseconds to give cancellation time to work */
1173
pAd->BulkOutPending[Idx] = FALSE;
1176
/*RTMP_IRQ_LOCK(pLock, IrqFlags); */
1177
for (i = 0; i < MGMT_RING_SIZE; i++) {
1178
pMLMEContext = (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
1179
if (pMLMEContext && (pMLMEContext->IRPPending == TRUE)) {
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 */
1186
RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1187
pMLMEContext->IRPPending = FALSE;
1189
/* Sleep 200 microsecs to give cancellation time to work */
1193
pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1194
/*RTMP_IRQ_UNLOCK(pLock, IrqFlags); */
1196
for (i = 0; i < BEACON_RING_SIZE; i++) {
1197
pBeaconContext = &(pAd->BeaconContext[i]);
1199
if (pBeaconContext->IRPPending == TRUE) {
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 */
1206
RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1208
/* Sleep 200 microsecs to give cancellation time to work */
1213
pNullContext = &(pAd->NullContext);
1214
if (pNullContext->IRPPending == TRUE)
1215
RTUSB_UNLINK_URB(pNullContext->pUrb);
1217
pRTSContext = &(pAd->RTSContext);
1218
if (pRTSContext->IRPPending == TRUE)
1219
RTUSB_UNLINK_URB(pRTSContext->pUrb);
1221
pPsPollContext = &(pAd->PsPollContext);
1222
if (pPsPollContext->IRPPending == TRUE)
1223
RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1225
for (Idx = 0; Idx < 4; Idx++) {
1226
NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1227
pAd->BulkOutPending[Idx] = FALSE;
1228
NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1232
#endif /* RTMP_MAC_USB // */