2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 06-25-2004 created
40 #include "../rt_config.h"
41 // Match total 6 bulkout endpoint to corresponding queue.
42 UCHAR EpToQueue
[6]={FIFO_EDCA
, FIFO_EDCA
, FIFO_EDCA
, FIFO_EDCA
, FIFO_EDCA
, FIFO_MGMT
};
44 //static BOOLEAN SingleBulkOut = FALSE;
46 void RTUSB_FILL_BULK_URB (struct urb
*pUrb
,
47 struct usb_device
*pUsb_Dev
,
48 unsigned int bulkpipe
,
51 usb_complete_t Complete
,
55 usb_fill_bulk_urb(pUrb
, pUsb_Dev
, bulkpipe
, pTransferBuf
, BufSize
, (usb_complete_t
)Complete
, pContext
);
61 IN PTX_CONTEXT pTxContext
,
62 IN UCHAR BulkOutPipeId
,
63 IN usb_complete_t Func
)
67 POS_COOKIE pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
69 pUrb
= pTxContext
->pUrb
;
72 // Store BulkOut PipeId
73 pTxContext
->BulkOutPipeId
= BulkOutPipeId
;
75 if (pTxContext
->bAggregatible
)
77 pSrc
= &pTxContext
->TransferBuffer
->Aggregation
[2];
81 pSrc
= (PUCHAR
) pTxContext
->TransferBuffer
->field
.WirelessPacket
;
85 //Initialize a tx bulk urb
86 RTUSB_FILL_BULK_URB(pUrb
,
88 usb_sndbulkpipe(pObj
->pUsb_Dev
, pAd
->BulkOutEpAddr
[BulkOutPipeId
]),
90 pTxContext
->BulkOutSize
,
94 if (pTxContext
->bAggregatible
)
95 pUrb
->transfer_dma
= (pTxContext
->data_dma
+ TX_BUFFER_NORMSIZE
+ 2);
97 pUrb
->transfer_dma
= pTxContext
->data_dma
;
99 pUrb
->transfer_flags
|= URB_NO_TRANSFER_DMA_MAP
;
103 VOID
RTUSBInitHTTxDesc(
104 IN PRTMP_ADAPTER pAd
,
105 IN PHT_TX_CONTEXT pTxContext
,
106 IN UCHAR BulkOutPipeId
,
107 IN ULONG BulkOutSize
,
108 IN usb_complete_t Func
)
112 POS_COOKIE pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
114 pUrb
= pTxContext
->pUrb
;
117 // Store BulkOut PipeId
118 pTxContext
->BulkOutPipeId
= BulkOutPipeId
;
120 pSrc
= &pTxContext
->TransferBuffer
->field
.WirelessPacket
[pTxContext
->NextBulkOutPosition
];
123 //Initialize a tx bulk urb
124 RTUSB_FILL_BULK_URB(pUrb
,
126 usb_sndbulkpipe(pObj
->pUsb_Dev
, pAd
->BulkOutEpAddr
[BulkOutPipeId
]),
132 pUrb
->transfer_dma
= (pTxContext
->data_dma
+ pTxContext
->NextBulkOutPosition
);
133 pUrb
->transfer_flags
|= URB_NO_TRANSFER_DMA_MAP
;
137 VOID
RTUSBInitRxDesc(
138 IN PRTMP_ADAPTER pAd
,
139 IN PRX_CONTEXT pRxContext
)
142 POS_COOKIE pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
146 pUrb
= pRxContext
->pUrb
;
149 if ( pAd
->BulkInMaxPacketSize
== 64)
152 RX_bulk_size
= MAX_RXBULK_SIZE
;
154 //Initialize a rx bulk urb
155 RTUSB_FILL_BULK_URB(pUrb
,
157 usb_rcvbulkpipe(pObj
->pUsb_Dev
, pAd
->BulkInEpAddr
),
158 &(pRxContext
->TransferBuffer
[pAd
->NextRxBulkInPosition
]),
159 RX_bulk_size
- (pAd
->NextRxBulkInPosition
),
160 (usb_complete_t
)RTUSBBulkRxComplete
,
163 pUrb
->transfer_dma
= pRxContext
->data_dma
+ pAd
->NextRxBulkInPosition
;
164 pUrb
->transfer_flags
|= URB_NO_TRANSFER_DMA_MAP
;
170 ========================================================================
180 ========================================================================
183 #define BULK_OUT_LOCK(pLock, IrqFlags) \
184 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
185 RTMP_IRQ_LOCK((pLock), IrqFlags);
187 #define BULK_OUT_UNLOCK(pLock, IrqFlags) \
188 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
189 RTMP_IRQ_UNLOCK((pLock), IrqFlags);
192 VOID
RTUSBBulkOutDataPacket(
193 IN PRTMP_ADAPTER pAd
,
194 IN UCHAR BulkOutPipeId
,
198 PHT_TX_CONTEXT pHTTXContext
;
201 PTXINFO_STRUC pTxInfo
, pLastTxInfo
= NULL
;
203 ULONG TmpBulkEndPos
, ThisBulkSize
;
204 unsigned long IrqFlags
= 0, IrqFlags2
= 0;
205 PUCHAR pWirelessPkt
, pAppendant
;
206 BOOLEAN bTxQLastRound
= FALSE
;
207 UCHAR allzero
[4]= {0x0,0x0,0x0,0x0};
209 BULK_OUT_LOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
210 if ((pAd
->BulkOutPending
[BulkOutPipeId
] == TRUE
) || RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NEED_STOP_TX
))
212 BULK_OUT_UNLOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
215 pAd
->BulkOutPending
[BulkOutPipeId
] = TRUE
;
217 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
)
220 pAd
->BulkOutPending
[BulkOutPipeId
] = FALSE
;
221 BULK_OUT_UNLOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
224 BULK_OUT_UNLOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
227 pHTTXContext
= &(pAd
->TxContext
[BulkOutPipeId
]);
229 BULK_OUT_LOCK(&pAd
->TxContextQueueLock
[BulkOutPipeId
], IrqFlags2
);
230 if ((pHTTXContext
->ENextBulkOutPosition
== pHTTXContext
->CurWritePosition
)
231 || ((pHTTXContext
->ENextBulkOutPosition
-8) == pHTTXContext
->CurWritePosition
))
233 BULK_OUT_UNLOCK(&pAd
->TxContextQueueLock
[BulkOutPipeId
], IrqFlags2
);
235 BULK_OUT_LOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
236 pAd
->BulkOutPending
[BulkOutPipeId
] = FALSE
;
239 RTUSB_CLEAR_BULK_FLAG(pAd
, (fRTUSB_BULK_OUT_DATA_FRAG
<< BulkOutPipeId
));
240 RTUSB_CLEAR_BULK_FLAG(pAd
, (fRTUSB_BULK_OUT_DATA_NORMAL
<< BulkOutPipeId
));
242 BULK_OUT_UNLOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
247 RTUSB_CLEAR_BULK_FLAG(pAd
, (fRTUSB_BULK_OUT_DATA_FRAG
<< BulkOutPipeId
));
248 RTUSB_CLEAR_BULK_FLAG(pAd
, (fRTUSB_BULK_OUT_DATA_NORMAL
<< BulkOutPipeId
));
250 //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
251 // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
252 // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
253 pHTTXContext
->NextBulkOutPosition
= pHTTXContext
->ENextBulkOutPosition
;
255 TmpBulkEndPos
= pHTTXContext
->NextBulkOutPosition
;
256 pWirelessPkt
= &pHTTXContext
->TransferBuffer
->field
.WirelessPacket
[0];
258 if ((pHTTXContext
->bCopySavePad
== TRUE
))
260 if (RTMPEqualMemory(pHTTXContext
->SavedPad
, allzero
,4))
262 DBGPRINT_RAW(RT_DEBUG_ERROR
,("e1, allzero : %x %x %x %x %x %x %x %x \n",
263 pHTTXContext
->SavedPad
[0], pHTTXContext
->SavedPad
[1], pHTTXContext
->SavedPad
[2],pHTTXContext
->SavedPad
[3]
264 ,pHTTXContext
->SavedPad
[4], pHTTXContext
->SavedPad
[5], pHTTXContext
->SavedPad
[6],pHTTXContext
->SavedPad
[7]));
266 NdisMoveMemory(&pWirelessPkt
[TmpBulkEndPos
], pHTTXContext
->SavedPad
, 8);
267 pHTTXContext
->bCopySavePad
= FALSE
;
268 if (pAd
->bForcePrintTX
== TRUE
)
269 DBGPRINT(RT_DEBUG_TRACE
,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext
->CurWritePosition
, pHTTXContext
->NextBulkOutPosition
, pHTTXContext
->ENextBulkOutPosition
));
274 pTxInfo
= (PTXINFO_STRUC
)&pWirelessPkt
[TmpBulkEndPos
];
275 pTxWI
= (PTXWI_STRUC
)&pWirelessPkt
[TmpBulkEndPos
+ TXINFO_SIZE
];
277 if (pAd
->bForcePrintTX
== TRUE
)
278 DBGPRINT(RT_DEBUG_TRACE
, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI
->AMPDU
));
280 // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
281 //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))
282 if ((ThisBulkSize
!= 0) && (pTxWI
->PHYMODE
== MODE_CCK
))
284 if (((ThisBulkSize
&0xffff8000) != 0) || ((ThisBulkSize
&0x1000) == 0x1000))
286 // Limit BulkOut size to about 4k bytes.
287 pHTTXContext
->ENextBulkOutPosition
= TmpBulkEndPos
;
290 else if (((pAd
->BulkOutMaxPacketSize
< 512) && ((ThisBulkSize
&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
292 // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
293 // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
294 pHTTXContext
->ENextBulkOutPosition
= TmpBulkEndPos
;
301 if (((ThisBulkSize
&0xffff8000) != 0) || ((ThisBulkSize
&0x6000) == 0x6000))
302 { // Limit BulkOut size to about 24k bytes.
303 pHTTXContext
->ENextBulkOutPosition
= TmpBulkEndPos
;
306 else if (((pAd
->BulkOutMaxPacketSize
< 512) && ((ThisBulkSize
&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
307 { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
308 // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
309 pHTTXContext
->ENextBulkOutPosition
= TmpBulkEndPos
;
314 if (TmpBulkEndPos
== pHTTXContext
->CurWritePosition
)
316 pHTTXContext
->ENextBulkOutPosition
= TmpBulkEndPos
;
320 if (pTxInfo
->QSEL
!= FIFO_EDCA
)
322 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__
, pTxInfo
->QSEL
);
323 printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext
->CurWritePosition
, pHTTXContext
->NextBulkOutPosition
, pHTTXContext
->ENextBulkOutPosition
, pHTTXContext
->bCopySavePad
);
324 hex_dump("Wrong QSel Pkt:", (PUCHAR
)&pWirelessPkt
[TmpBulkEndPos
], (pHTTXContext
->CurWritePosition
- pHTTXContext
->NextBulkOutPosition
));
327 if (pTxInfo
->USBDMATxPktLen
<= 8)
329 BULK_OUT_UNLOCK(&pAd
->TxContextQueueLock
[BulkOutPipeId
], IrqFlags2
);
330 DBGPRINT(RT_DEBUG_ERROR
/*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
331 pHTTXContext
->BulkOutSize
, pHTTXContext
->bCopySavePad
, pHTTXContext
->CurWritePosition
, pHTTXContext
->NextBulkOutPosition
, pHTTXContext
->CurWriteRealPos
));
333 DBGPRINT_RAW(RT_DEBUG_ERROR
/*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n",
334 pHTTXContext
->SavedPad
[0], pHTTXContext
->SavedPad
[1], pHTTXContext
->SavedPad
[2],pHTTXContext
->SavedPad
[3]
335 ,pHTTXContext
->SavedPad
[4], pHTTXContext
->SavedPad
[5], pHTTXContext
->SavedPad
[6],pHTTXContext
->SavedPad
[7]));
337 pAd
->bForcePrintTX
= TRUE
;
338 BULK_OUT_LOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
339 pAd
->BulkOutPending
[BulkOutPipeId
] = FALSE
;
340 BULK_OUT_UNLOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
341 //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
345 // Increase Total transmit byte counter
346 pAd
->RalinkCounters
.OneSecTransmittedByteCount
+= pTxWI
->MPDUtotalByteCount
;
347 pAd
->RalinkCounters
.TransmittedByteCount
+= pTxWI
->MPDUtotalByteCount
;
349 pLastTxInfo
= pTxInfo
;
351 // Make sure we use EDCA QUEUE.
352 pTxInfo
->QSEL
= FIFO_EDCA
;
353 ThisBulkSize
+= (pTxInfo
->USBDMATxPktLen
+4);
354 TmpBulkEndPos
+= (pTxInfo
->USBDMATxPktLen
+4);
356 if (TmpBulkEndPos
!= pHTTXContext
->CurWritePosition
)
357 pTxInfo
->USBDMANextVLD
= 1;
359 if (pTxInfo
->SwUseLastRound
== 1)
361 if (pHTTXContext
->CurWritePosition
== 8)
362 pTxInfo
->USBDMANextVLD
= 0;
363 pTxInfo
->SwUseLastRound
= 0;
365 bTxQLastRound
= TRUE
;
366 pHTTXContext
->ENextBulkOutPosition
= 8;
372 // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
375 pLastTxInfo
->USBDMANextVLD
= 0;
379 We need to copy SavedPad when following condition matched!
380 1. Not the last round of the TxQueue and
381 2. any match of following cases:
382 (1). The End Position of this bulk out is reach to the Currenct Write position and
383 the TxInfo and related header already write to the CurWritePosition.
384 =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
386 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
387 =>(ENextBulkOutPosition != CurWritePosition)
389 if ((bTxQLastRound
== FALSE
) &&
390 (((pHTTXContext
->ENextBulkOutPosition
== pHTTXContext
->CurWritePosition
) && (pHTTXContext
->CurWriteRealPos
> pHTTXContext
->CurWritePosition
)) ||
391 (pHTTXContext
->ENextBulkOutPosition
!= pHTTXContext
->CurWritePosition
))
394 NdisMoveMemory(pHTTXContext
->SavedPad
, &pWirelessPkt
[pHTTXContext
->ENextBulkOutPosition
], 8);
395 pHTTXContext
->bCopySavePad
= TRUE
;
396 if (RTMPEqualMemory(pHTTXContext
->SavedPad
, allzero
,4))
398 PUCHAR pBuf
= &pHTTXContext
->SavedPad
[0];
399 DBGPRINT_RAW(RT_DEBUG_ERROR
,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
400 pBuf
[0], pBuf
[1], pBuf
[2],pBuf
[3],pBuf
[4], pBuf
[5], pBuf
[6],pBuf
[7], pHTTXContext
->CurWritePosition
, pHTTXContext
->CurWriteRealPos
,
401 pHTTXContext
->bCurWriting
, pHTTXContext
->NextBulkOutPosition
, TmpBulkEndPos
, ThisBulkSize
));
403 pBuf
= &pWirelessPkt
[pHTTXContext
->CurWritePosition
];
404 DBGPRINT_RAW(RT_DEBUG_ERROR
,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf
[0], pBuf
[1], pBuf
[2],pBuf
[3],pBuf
[4], pBuf
[5], pBuf
[6],pBuf
[7]));
406 //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
409 if (pAd
->bForcePrintTX
== TRUE
)
410 DBGPRINT(RT_DEBUG_TRACE
,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize
, pHTTXContext
->CurWritePosition
, pHTTXContext
->NextBulkOutPosition
, pHTTXContext
->ENextBulkOutPosition
, pHTTXContext
->bCopySavePad
));
411 //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));
413 // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
414 pAppendant
= &pWirelessPkt
[TmpBulkEndPos
];
415 NdisZeroMemory(pAppendant
, 8);
417 pHTTXContext
->LastOne
= TRUE
;
418 if ((ThisBulkSize
% pAd
->BulkOutMaxPacketSize
) == 0)
420 pHTTXContext
->BulkOutSize
= ThisBulkSize
;
422 pAd
->watchDogTxPendingCnt
[BulkOutPipeId
] = 1;
423 BULK_OUT_UNLOCK(&pAd
->TxContextQueueLock
[BulkOutPipeId
], IrqFlags2
);
425 // Init Tx context descriptor
426 RTUSBInitHTTxDesc(pAd
, pHTTXContext
, BulkOutPipeId
, ThisBulkSize
, (usb_complete_t
)RTUSBBulkOutDataPacketComplete
);
428 pUrb
= pHTTXContext
->pUrb
;
429 if((ret
= RTUSB_SUBMIT_URB(pUrb
))!=0)
431 DBGPRINT(RT_DEBUG_ERROR
, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret
));
433 BULK_OUT_LOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
434 pAd
->BulkOutPending
[BulkOutPipeId
] = FALSE
;
435 pAd
->watchDogTxPendingCnt
[BulkOutPipeId
] = 0;
436 BULK_OUT_UNLOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
441 BULK_OUT_LOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
442 pHTTXContext
->IRPPending
= TRUE
;
443 BULK_OUT_UNLOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
449 VOID
RTUSBBulkOutDataPacketComplete(purbb_t pUrb
, struct pt_regs
*pt_regs
)
451 #if 0 // sample, IRQ LOCK
454 PHT_TX_CONTEXT pHTTXContext
;
457 unsigned long IrqFlags
;
459 DBGPRINT_RAW(RT_DEBUG_INFO
, ("--->RTUSBBulkOutDataPacketComplete\n"));
461 pHTTXContext
= (PHT_TX_CONTEXT
)pUrb
->context
;
462 pAd
= pHTTXContext
->pAd
;
463 pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
464 Status
= pUrb
->status
;
466 // Store BulkOut PipeId
467 BulkOutPipeId
= pHTTXContext
->BulkOutPipeId
;
468 pAd
->BulkOutDataOneSecCount
++;
470 //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
471 // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
473 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
474 pAd
->BulkOutPending
[BulkOutPipeId
] = FALSE
;
475 pHTTXContext
->IRPPending
= FALSE
;
476 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[BulkOutPipeId
], IrqFlags
);
478 if (Status
== USB_ST_NOERROR
)
480 pAd
->BulkOutComplete
++;
482 pAd
->Counters8023
.GoodTransmits
++;
483 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
484 FREE_HTTX_RING(pAd
, BulkOutPipeId
, pHTTXContext
);
485 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
493 pAd
->BulkOutCompleteOther
++;
495 pBuf
= &pHTTXContext
->TransferBuffer
->WirelessPacket
[pHTTXContext
->NextBulkOutPosition
];
497 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status
));
498 DBGPRINT_RAW(RT_DEBUG_ERROR
, (">>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd
->BulkOutReq
, pAd
->BulkOutComplete
, pAd
->BulkOutCompleteOther
));
499 DBGPRINT_RAW(RT_DEBUG_ERROR
, (">>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf
[0], pBuf
[1], pBuf
[2], pBuf
[3], pBuf
[4], pBuf
[5], pBuf
[6], pBuf
[7]));
500 //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
502 if (!RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_RESET_IN_PROGRESS
|
503 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
504 fRTMP_ADAPTER_NIC_NOT_EXIST
|
505 fRTMP_ADAPTER_BULKOUT_RESET
)))
507 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
);
508 pAd
->bulkResetPipeid
= BulkOutPipeId
;
513 // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
514 // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
516 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
517 if ((pHTTXContext
->ENextBulkOutPosition
!= pHTTXContext
->CurWritePosition
) &&
518 (pHTTXContext
->ENextBulkOutPosition
!= (pHTTXContext
->CurWritePosition
+8)) &&
519 !RTUSB_TEST_BULK_FLAG(pAd
, (fRTUSB_BULK_OUT_DATA_FRAG
<< BulkOutPipeId
)))
521 // Indicate There is data avaliable
522 RTUSB_SET_BULK_FLAG(pAd
, (fRTUSB_BULK_OUT_DATA_NORMAL
<< BulkOutPipeId
));
524 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
526 // Always call Bulk routine, even reset bulk.
527 // The protection of rest bulk should be in BulkOut routine
528 RTUSBKickBulkOut(pAd
);
531 //DBGPRINT(RT_DEBUG_LOUD,("Done-A(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d\n", BulkOutPipeId, in_interrupt(),
532 // pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
534 switch (BulkOutPipeId
)
537 pObj
->ac0_dma_done_task
.data
= (unsigned long)pAd
;
538 tasklet_hi_schedule(&pObj
->ac0_dma_done_task
);
541 pObj
->ac1_dma_done_task
.data
= (unsigned long)pAd
;
542 tasklet_hi_schedule(&pObj
->ac1_dma_done_task
);
545 pObj
->ac2_dma_done_task
.data
= (unsigned long)pAd
;
546 tasklet_hi_schedule(&pObj
->ac2_dma_done_task
);
549 pObj
->ac3_dma_done_task
.data
= (unsigned long)pAd
;
550 tasklet_hi_schedule(&pObj
->ac3_dma_done_task
);
553 pObj
->hcca_dma_done_task
.data
= (unsigned long)pAd
;
554 tasklet_hi_schedule(&pObj
->hcca_dma_done_task
);
560 PHT_TX_CONTEXT pHTTXContext
;
566 pHTTXContext
= (PHT_TX_CONTEXT
)pUrb
->context
;
567 pAd
= pHTTXContext
->pAd
;
568 pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
570 // Store BulkOut PipeId
571 BulkOutPipeId
= pHTTXContext
->BulkOutPipeId
;
572 pAd
->BulkOutDataOneSecCount
++;
574 switch (BulkOutPipeId
)
577 pObj
->ac0_dma_done_task
.data
= (unsigned long)pUrb
;
578 tasklet_hi_schedule(&pObj
->ac0_dma_done_task
);
581 pObj
->ac1_dma_done_task
.data
= (unsigned long)pUrb
;
582 tasklet_hi_schedule(&pObj
->ac1_dma_done_task
);
585 pObj
->ac2_dma_done_task
.data
= (unsigned long)pUrb
;
586 tasklet_hi_schedule(&pObj
->ac2_dma_done_task
);
589 pObj
->ac3_dma_done_task
.data
= (unsigned long)pUrb
;
590 tasklet_hi_schedule(&pObj
->ac3_dma_done_task
);
593 pObj
->hcca_dma_done_task
.data
= (unsigned long)pUrb
;
594 tasklet_hi_schedule(&pObj
->hcca_dma_done_task
);
605 ========================================================================
613 Note: NULL frame use BulkOutPipeId = 0
615 ========================================================================
617 VOID
RTUSBBulkOutNullFrame(
618 IN PRTMP_ADAPTER pAd
)
620 PTX_CONTEXT pNullContext
= &(pAd
->NullContext
);
623 unsigned long IrqFlags
;
625 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
626 if ((pAd
->BulkOutPending
[0] == TRUE
) || RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NEED_STOP_TX
))
628 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
631 pAd
->BulkOutPending
[0] = TRUE
;
632 pAd
->watchDogTxPendingCnt
[0] = 1;
633 pNullContext
->IRPPending
= TRUE
;
634 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
636 // Increase Total transmit byte counter
637 pAd
->RalinkCounters
.TransmittedByteCount
+= pNullContext
->BulkOutSize
;
640 // Clear Null frame bulk flag
641 RTUSB_CLEAR_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NULL
);
643 // Init Tx context descriptor
644 RTUSBInitTxDesc(pAd
, pNullContext
, 0, (usb_complete_t
)RTUSBBulkOutNullFrameComplete
);
646 pUrb
= pNullContext
->pUrb
;
647 if((ret
= RTUSB_SUBMIT_URB(pUrb
))!=0)
649 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
650 pAd
->BulkOutPending
[0] = FALSE
;
651 pAd
->watchDogTxPendingCnt
[0] = 0;
652 pNullContext
->IRPPending
= FALSE
;
653 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
655 DBGPRINT(RT_DEBUG_ERROR
, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret
));
661 // NULL frame use BulkOutPipeId = 0
662 VOID
RTUSBBulkOutNullFrameComplete(purbb_t pUrb
, struct pt_regs
*pt_regs
)
665 PTX_CONTEXT pNullContext
;
667 #if 0 // sample, IRQ LOCK
668 unsigned long IrqFlags
;
673 pNullContext
= (PTX_CONTEXT
)pUrb
->context
;
674 pAd
= pNullContext
->pAd
;
675 Status
= pUrb
->status
;
677 #if 0 // sample, IRQ LOCK
678 // Reset Null frame context flags
679 pNullContext
->IRPPending
= FALSE
;
680 pNullContext
->InUse
= FALSE
;
682 if (Status
== USB_ST_NOERROR
)
684 // Don't worry about the queue is empty or not, this function will check itself
685 //RTMPUSBDeQueuePacket(pAd, 0);
686 RTMPDeQueuePacket(pAd
, TRUE
, NUM_OF_TX_RING
, MAX_TX_PROCESS
);
690 if ((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) &&
691 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) &&
692 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)) &&
693 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)))
695 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("Bulk Out Null Frame Failed\n"));
696 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
);
697 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
701 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
702 pAd
->BulkOutPending
[0] = FALSE
;
703 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
705 // Always call Bulk routine, even reset bulk.
706 // The protectioon of rest bulk should be in BulkOut routine
707 RTUSBKickBulkOut(pAd
);
710 pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
711 pObj
->null_frame_complete_task
.data
= (unsigned long)pUrb
;
712 tasklet_hi_schedule(&pObj
->null_frame_complete_task
);
717 #if 0 // For RT2870, RTS frame not used now, but maybe will use it latter.
719 ========================================================================
727 Note: RTS frame use BulkOutPipeId = 0
729 ========================================================================
731 VOID
RTUSBBulkOutRTSFrame(
732 IN PRTMP_ADAPTER pAd
)
734 PTX_CONTEXT pRTSContext
= &(pAd
->RTSContext
);
737 unsigned long IrqFlags
;
740 if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL_4
))
742 else if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL_3
))
744 else if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL_2
))
746 else if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL
))
749 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[PipeID
], IrqFlags
);
750 if ((pAd
->BulkOutPending
[PipeID
] == TRUE
) || RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NEED_STOP_TX
))
752 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[PipeID
], IrqFlags
);
755 pAd
->BulkOutPending
[PipeID
] = TRUE
;
756 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[PipeID
], IrqFlags
);
758 // Increase Total transmit byte counter
759 pAd
->RalinkCounters
.TransmittedByteCount
+= pRTSContext
->BulkOutSize
;
761 DBGPRINT_RAW(RT_DEBUG_INFO
, ("--->RTUSBBulkOutRTSFrame \n"));
763 // Clear RTS frame bulk flag
764 RTUSB_CLEAR_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_RTS
);
766 // Init Tx context descriptor
767 RTUSBInitTxDesc(pAd
, pRTSContext
, PipeID
, (usb_complete_t
)RTUSBBulkOutRTSFrameComplete
);
768 pRTSContext
->IRPPending
= TRUE
;
770 pUrb
= pRTSContext
->pUrb
;
771 if((ret
= RTUSB_SUBMIT_URB(pUrb
))!=0)
773 DBGPRINT(RT_DEBUG_ERROR
, ("RTUSBBulkOutRTSFrame: Submit Tx URB failed %d\n", ret
));
777 DBGPRINT_RAW(RT_DEBUG_INFO
, ("<---RTUSBBulkOutRTSFrame \n"));
781 // RTS frame use BulkOutPipeId = 0
782 VOID
RTUSBBulkOutRTSFrameComplete(purbb_t pUrb
, struct pt_regs
*pt_regs
)
785 PTX_CONTEXT pRTSContext
;
787 #if 0 // sample, IRQ LOCK
788 unsigned long IrqFlags
;
792 DBGPRINT_RAW(RT_DEBUG_INFO
, ("--->RTUSBBulkOutRTSFrameComplete\n"));
794 pRTSContext
= (PTX_CONTEXT
)pUrb
->context
;
795 pAd
= pRTSContext
->pAd
;
796 Status
= pUrb
->status
;
798 #if 0 // sample, IRQ LOCK
799 // Reset RTS frame context flags
800 pRTSContext
->IRPPending
= FALSE
;
801 pRTSContext
->InUse
= FALSE
;
803 if (Status
== USB_ST_NOERROR
)
805 // Don't worry about the queue is empty or not, this function will check itself
806 //RTMPUSBDeQueuePacket(pAd, pRTSContext->BulkOutPipeId);
807 RTMPDeQueuePacket(pAd
, TRUE
, NUM_OF_TX_RING
, MAX_TX_PROCESS
);
811 if ((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) &&
812 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) &&
813 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)) &&
814 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)))
816 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("Bulk Out RTS Frame Failed\n"));
817 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
);
818 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
822 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[pRTSContext
->BulkOutPipeId
], IrqFlags
);
823 pAd
->BulkOutPending
[pRTSContext
->BulkOutPipeId
] = FALSE
;
824 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[pRTSContext
->BulkOutPipeId
], IrqFlags
);
826 // Always call Bulk routine, even reset bulk.
827 // The protectioon of rest bulk should be in BulkOut routine
828 RTUSBKickBulkOut(pAd
);
831 pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
832 pObj
->rts_frame_complete_task
.data
= (unsigned long)pUrb
;
833 tasklet_hi_schedule(&pObj
->rts_frame_complete_task
);
836 DBGPRINT_RAW(RT_DEBUG_INFO
, ("<---RTUSBBulkOutRTSFrameComplete\n"));
842 ========================================================================
850 Note: MLME use BulkOutPipeId = 0
852 ========================================================================
854 VOID
RTUSBBulkOutMLMEPacket(
855 IN PRTMP_ADAPTER pAd
,
858 PTX_CONTEXT pMLMEContext
;
861 unsigned long IrqFlags
;
863 pMLMEContext
= (PTX_CONTEXT
)pAd
->MgmtRing
.Cell
[pAd
->MgmtRing
.TxDmaIdx
].AllocVa
;
864 pUrb
= pMLMEContext
->pUrb
;
866 if ((pAd
->MgmtRing
.TxSwFreeIdx
>= MGMT_RING_SIZE
) ||
867 (pMLMEContext
->InUse
== FALSE
) ||
868 (pMLMEContext
->bWaitingBulkOut
== FALSE
))
872 // Clear MLME bulk flag
873 RTUSB_CLEAR_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_MLME
);
879 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[MGMTPIPEIDX
], IrqFlags
);
880 if ((pAd
->BulkOutPending
[MGMTPIPEIDX
] == TRUE
) || RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NEED_STOP_TX
))
882 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[MGMTPIPEIDX
], IrqFlags
);
886 pAd
->BulkOutPending
[MGMTPIPEIDX
] = TRUE
;
887 pAd
->watchDogTxPendingCnt
[MGMTPIPEIDX
] = 1;
888 pMLMEContext
->IRPPending
= TRUE
;
889 pMLMEContext
->bWaitingBulkOut
= FALSE
;
890 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[MGMTPIPEIDX
], IrqFlags
);
892 // Increase Total transmit byte counter
893 pAd
->RalinkCounters
.TransmittedByteCount
+= pMLMEContext
->BulkOutSize
;
895 // Clear MLME bulk flag
896 RTUSB_CLEAR_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_MLME
);
899 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacket\n"));
902 printk("MLME-Out, C=%d!, D=%d, F=%d!\n", pAd
->MgmtRing
.TxCpuIdx
, pAd
->MgmtRing
.TxDmaIdx
, pAd
->MgmtRing
.TxSwFreeIdx
);
904 //TODO: Need to remove it when formal release
905 PTXINFO_STRUC pTxInfo
;
907 pTxInfo
= (PTXINFO_STRUC
)pMLMEContext
->TransferBuffer
;
908 if (pTxInfo
->QSEL
!= FIFO_EDCA
)
910 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__
, pTxInfo
->QSEL
);
911 printk("\tMLME_Index=%d!\n", Index
);
912 hex_dump("Wrong QSel Pkt:", (PUCHAR
)pMLMEContext
->TransferBuffer
, pTxInfo
->USBDMATxPktLen
);
917 // Init Tx context descriptor
918 RTUSBInitTxDesc(pAd
, pMLMEContext
, MGMTPIPEIDX
, (usb_complete_t
)RTUSBBulkOutMLMEPacketComplete
);
920 //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
921 pUrb
->transfer_dma
= 0;
922 pUrb
->transfer_flags
&= (~URB_NO_TRANSFER_DMA_MAP
);
924 pUrb
= pMLMEContext
->pUrb
;
925 if((ret
= RTUSB_SUBMIT_URB(pUrb
))!=0)
927 DBGPRINT(RT_DEBUG_ERROR
, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret
));
928 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[MGMTPIPEIDX
], IrqFlags
);
929 pAd
->BulkOutPending
[MGMTPIPEIDX
] = FALSE
;
930 pAd
->watchDogTxPendingCnt
[MGMTPIPEIDX
] = 0;
931 pMLMEContext
->IRPPending
= FALSE
;
932 pMLMEContext
->bWaitingBulkOut
= TRUE
;
933 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[MGMTPIPEIDX
], IrqFlags
);
938 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
939 // printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
943 VOID
RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb
, struct pt_regs
*pt_regs
)
945 PTX_CONTEXT pMLMEContext
;
950 #if 0 // sample, IRQ LOCK
951 unsigned long IrqFlags
;
952 PNDIS_PACKET pPacket
;
956 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
957 pMLMEContext
= (PTX_CONTEXT
)pUrb
->context
;
958 pAd
= pMLMEContext
->pAd
;
959 pObj
= (POS_COOKIE
)pAd
->OS_Cookie
;
960 Status
= pUrb
->status
;
961 index
= pMLMEContext
->SelfIdx
;
964 #if 0 // sample, IRQ LOCK
965 ASSERT((pAd
->MgmtRing
.TxDmaIdx
== index
));
966 //printk("MLME-Done-B: C=%d, D=%d, F=%d, Self=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx, pMLMEContext->SelfIdx);
968 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[MGMTPIPEIDX
], IrqFlags
);
971 if (Status
!= USB_ST_NOERROR
)
973 //Bulk-Out fail status handle
974 if ((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) &&
975 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) &&
976 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)) &&
977 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)))
979 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("Bulk Out MLME Failed, Status=%d!\n", Status
));
980 // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
981 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
);
982 pAd
->bulkResetPipeid
= (MGMTPIPEIDX
| BULKOUT_MGMT_RESET_FLAG
);
985 pAd
->BulkOutPending
[MGMTPIPEIDX
] = FALSE
;
986 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[MGMTPIPEIDX
], IrqFlags
);
988 RTMP_IRQ_LOCK(&pAd
->MLMEBulkOutLock
, IrqFlags
);
989 // Reset MLME context flags
990 pMLMEContext
->IRPPending
= FALSE
;
991 pMLMEContext
->InUse
= FALSE
;
992 pMLMEContext
->bWaitingBulkOut
= FALSE
;
993 pMLMEContext
->BulkOutSize
= 0;
995 pPacket
= pAd
->MgmtRing
.Cell
[index
].pNdisPacket
;
996 pAd
->MgmtRing
.Cell
[index
].pNdisPacket
= NULL
;
998 // Increase MgmtRing Index
999 INC_RING_INDEX(pAd
->MgmtRing
.TxDmaIdx
, MGMT_RING_SIZE
);
1000 pAd
->MgmtRing
.TxSwFreeIdx
++;
1002 RTMP_IRQ_UNLOCK(&pAd
->MLMEBulkOutLock
, IrqFlags
);
1004 // No-matter success or fail, we free the mgmt packet.
1006 RTMPFreeNdisPacket(pAd
, pPacket
);
1009 //Bulk-Out fail status handle
1010 if (Status
!= USB_ST_NOERROR
)
1012 if ((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) &&
1013 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) &&
1014 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)) &&
1015 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)))
1017 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("Bulk Out MLME Failed, Status=%d!\n", Status
));
1018 // TODO: How to handle about the MLMEBulkOut failed issue. Need to reset the endpoint?
1019 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
);
1020 pAd
->bulkResetPipeid
= (MGMTPIPEIDX
| BULKOUT_MGMT_RESET_FLAG
);
1025 //printk("MLME-Done-A: C=%d, D=%d, F=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
1027 pObj
->mgmt_dma_done_task
.data
= (unsigned long)pAd
;
1028 tasklet_hi_schedule(&pObj
->mgmt_dma_done_task
);
1030 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacketComplete\n"));
1031 // printk("<---RTUSBBulkOutMLMEPacketComplete, Cpu=%d, Dma=%d, SwIdx=%d!\n",
1032 // pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
1036 pObj
->mgmt_dma_done_task
.data
= (unsigned long)pUrb
;
1037 tasklet_hi_schedule(&pObj
->mgmt_dma_done_task
);
1043 ========================================================================
1045 Routine Description:
1051 Note: PsPoll use BulkOutPipeId = 0
1053 ========================================================================
1055 VOID
RTUSBBulkOutPsPoll(
1056 IN PRTMP_ADAPTER pAd
)
1058 PTX_CONTEXT pPsPollContext
= &(pAd
->PsPollContext
);
1061 unsigned long IrqFlags
;
1063 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
1064 if ((pAd
->BulkOutPending
[0] == TRUE
) || RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NEED_STOP_TX
))
1066 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
1069 pAd
->BulkOutPending
[0] = TRUE
;
1070 pAd
->watchDogTxPendingCnt
[0] = 1;
1071 pPsPollContext
->IRPPending
= TRUE
;
1072 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
1075 // Clear PS-Poll bulk flag
1076 RTUSB_CLEAR_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_PSPOLL
);
1078 // Init Tx context descriptor
1079 RTUSBInitTxDesc(pAd
, pPsPollContext
, MGMTPIPEIDX
, (usb_complete_t
)RTUSBBulkOutPsPollComplete
);
1081 pUrb
= pPsPollContext
->pUrb
;
1082 if((ret
= RTUSB_SUBMIT_URB(pUrb
))!=0)
1084 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
1085 pAd
->BulkOutPending
[0] = FALSE
;
1086 pAd
->watchDogTxPendingCnt
[0] = 0;
1087 pPsPollContext
->IRPPending
= FALSE
;
1088 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
1090 DBGPRINT(RT_DEBUG_ERROR
, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret
));
1096 // PS-Poll frame use BulkOutPipeId = 0
1097 VOID
RTUSBBulkOutPsPollComplete(purbb_t pUrb
,struct pt_regs
*pt_regs
)
1100 PTX_CONTEXT pPsPollContext
;
1102 #if 0 // sample, IRQ LOCK
1103 unsigned long IrqFlags
;
1108 pPsPollContext
= (PTX_CONTEXT
)pUrb
->context
;
1109 pAd
= pPsPollContext
->pAd
;
1110 Status
= pUrb
->status
;
1112 #if 0 // sample, IRQ LOCK
1113 // Reset PsPoll context flags
1114 pPsPollContext
->IRPPending
= FALSE
;
1115 pPsPollContext
->InUse
= FALSE
;
1117 if (Status
== USB_ST_NOERROR
)
1119 // Don't worry about the queue is empty or not, this function will check itself
1120 RTMPDeQueuePacket(pAd
, TRUE
, NUM_OF_TX_RING
, MAX_TX_PROCESS
);
1122 else // STATUS_OTHER
1124 if ((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) &&
1125 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) &&
1126 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)) &&
1127 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
)))
1129 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("Bulk Out PSPoll Failed\n"));
1130 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKOUT_RESET
);
1131 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_OUT
, NULL
, 0);
1135 RTMP_IRQ_LOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
1136 pAd
->BulkOutPending
[0] = FALSE
;
1137 RTMP_IRQ_UNLOCK(&pAd
->BulkOutLock
[0], IrqFlags
);
1139 // Always call Bulk routine, even reset bulk.
1140 // The protectioon of rest bulk should be in BulkOut routine
1141 RTUSBKickBulkOut(pAd
);
1144 pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
1145 pObj
->pspoll_frame_complete_task
.data
= (unsigned long)pUrb
;
1146 tasklet_hi_schedule(&pObj
->pspoll_frame_complete_task
);
1153 ========================================================================
1155 Routine Description:
1156 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
1157 to USB. It checks if an Rx Descriptor is available and passes the
1158 the coresponding buffer to be filled. If no descriptor is available
1159 fails the request. When setting the completion routine we pass our
1160 Adapter Object as Context.
1165 TRUE found matched tuple cache
1166 FALSE no matched found
1170 ========================================================================
1172 VOID
RTUSBBulkReceive(
1173 IN PRTMP_ADAPTER pAd
)
1175 PRX_CONTEXT pRxContext
;
1178 unsigned long IrqFlags
;
1181 /* device had been closed */
1182 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_REMOVE_IN_PROGRESS
))
1185 RTMP_IRQ_LOCK(&pAd
->BulkInLock
, IrqFlags
);
1187 // Last is time point between 2 separate URB.
1188 if (pAd
->NextRxBulkInPosition
== 0)
1190 //pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % (RX_RING_SIZE);
1191 INC_RING_INDEX(pAd
->NextRxBulkInIndex
, RX_RING_SIZE
);
1193 else if ((pAd
->NextRxBulkInPosition
&0x1ff) != 0)
1195 //pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % (RX_RING_SIZE);
1196 INC_RING_INDEX(pAd
->NextRxBulkInIndex
, RX_RING_SIZE
);
1197 DBGPRINT_RAW(RT_DEBUG_TRACE
, ("pAd->NextRxBulkInPosition = 0x%lx. End of URB.\n", pAd
->NextRxBulkInPosition
));
1198 pAd
->NextRxBulkInPosition
= 0;
1201 if (pAd
->NextRxBulkInPosition
== MAX_RXBULK_SIZE
)
1202 pAd
->NextRxBulkInPosition
= 0;
1204 pRxContext
= &(pAd
->RxContext
[pAd
->NextRxBulkInIndex
]);
1206 // TODO: Why need to check if pRxContext->InUsed == TRUE?
1207 //if ((pRxContext->InUse == TRUE) || (pRxContext->Readable == TRUE))
1208 if ((pRxContext
->InUse
== FALSE
) && (pRxContext
->Readable
== TRUE
))
1210 DBGPRINT_RAW(RT_DEBUG_TRACE
, ("pRxContext[%d] InUse = %d.pRxContext->Readable = %d. Return.\n", pAd
->NextRxBulkInIndex
,pRxContext
->InUse
, pRxContext
->Readable
));
1211 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
1213 // read RxContext, Since not
1214 STARxDoneInterruptHandle(pAd
, TRUE
);
1218 pRxContext
->InUse
= TRUE
;
1219 pRxContext
->IRPPending
= TRUE
;
1221 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
1223 // Init Rx context descriptor
1224 NdisZeroMemory(pRxContext
->TransferBuffer
, BUFFER_SIZE
);
1225 RTUSBInitRxDesc(pAd
, pRxContext
);
1227 pUrb
= pRxContext
->pUrb
;
1228 if ((ret
= RTUSB_SUBMIT_URB(pUrb
))!=0)
1230 DBGPRINT(RT_DEBUG_ERROR
, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret
));
1235 NdisInterlockedIncrement(&pAd
->PendingRx
);
1239 // read RxContext, Since not
1240 STARxDoneInterruptHandle(pAd
, FALSE
);
1244 ========================================================================
1246 Routine Description:
1247 This routine process Rx Irp and call rx complete function.
1250 DeviceObject Pointer to the device object for next lower
1251 device. DeviceObject passed in here belongs to
1252 the next lower driver in the stack because we
1253 were invoked via IoCallDriver in USB_RxPacket
1254 AND it is not OUR device object
1255 Irp Ptr to completed IRP
1256 Context Ptr to our Adapter object (context specified
1257 in IoSetCompletionRoutine
1260 Always returns STATUS_MORE_PROCESSING_REQUIRED
1263 Always returns STATUS_MORE_PROCESSING_REQUIRED
1264 ========================================================================
1266 VOID
RTUSBBulkRxComplete(purbb_t pUrb
, struct pt_regs
*pt_regs
)
1269 PRX_CONTEXT pRxContext
;
1274 pRxContext
= (PRX_CONTEXT
)pUrb
->context
;
1275 pAd
= pRxContext
->pAd
;
1276 // pObj = (POS_COOKIE) pAd->OS_Cookie;
1279 Status
= pUrb
->status
;
1280 //pRxContext->pIrp = NULL;
1282 pRxContext
->InUse
= FALSE
;
1283 pRxContext
->IRPPending
= FALSE
;
1285 if (Status
== USB_ST_NOERROR
)
1287 pAd
->BulkInComplete
++;
1288 pRxContext
->Readable
= TRUE
;
1289 pAd
->NextRxBulkInPosition
= 0;
1292 else // STATUS_OTHER
1294 pAd
->BulkInCompleteFail
++;
1295 // Still read this packet although it may comtain wrong bytes.
1296 pRxContext
->Readable
= FALSE
;
1297 // Parsing all packets. because after reset, the index will reset to all zero.
1299 if ((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) &&
1300 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKIN_RESET
)) &&
1301 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) &&
1302 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)))
1305 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("Bulk In Failed. Status = %d\n", Status
));
1306 DBGPRINT_RAW(RT_DEBUG_ERROR
, ("==>NextRxBulkInIndex=0x%x, NextRxBulkInReadIndex=0x%x, TransferBufferLength= 0x%x\n",
1307 pAd
->NextRxBulkInIndex
, pAd
->NextRxBulkInReadIndex
, pRxContext
->pUrb
->actual_length
));
1309 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_BULKIN_RESET
);
1310 RTUSBEnqueueInternalCmd(pAd
, CMDTHREAD_RESET_BULK_IN
, NULL
, 0);
1315 if ((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) &&
1316 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BULKIN_RESET
)) &&
1317 // (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) &&
1318 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RADIO_OFF
)) &&
1319 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) &&
1320 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)))
1322 RTUSBBulkReceive(pAd
);
1325 STARxDoneInterruptHandle(pAd
, FALSE
);
1327 pObj
->rx_bh
.data
= (unsigned long)pUrb
;
1328 tasklet_schedule(&pObj
->rx_bh
);
1333 // Call RxPacket to process packet and return the status
1334 NdisInterlockedDecrement(&pAd
->PendingRx
);
1338 // use a receive tasklet to handle received packets;
1339 // or sometimes hardware IRQ will be disabled here, so we can not
1340 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
1341 PRX_CONTEXT pRxContext
;
1346 pRxContext
= (PRX_CONTEXT
)pUrb
->context
;
1347 pAd
= pRxContext
->pAd
;
1348 pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
1350 pObj
->rx_done_task
.data
= (unsigned long)pUrb
;
1351 tasklet_hi_schedule(&pObj
->rx_done_task
);
1357 VOID
DoBulkIn(IN RTMP_ADAPTER
*pAd
)
1359 PRX_CONTEXT pRxContext
;
1362 unsigned long IrqFlags
;
1364 RTMP_IRQ_LOCK(&pAd
->BulkInLock
, IrqFlags
);
1365 pRxContext
= &(pAd
->RxContext
[pAd
->NextRxBulkInIndex
]);
1366 if ((pAd
->PendingRx
> 0) || (pRxContext
->Readable
== TRUE
) || (pRxContext
->InUse
== TRUE
))
1368 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
1371 pRxContext
->InUse
= TRUE
;
1372 pRxContext
->IRPPending
= TRUE
;
1375 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
1377 // Init Rx context descriptor
1378 NdisZeroMemory(pRxContext
->TransferBuffer
, pRxContext
->BulkInOffset
);
1379 RTUSBInitRxDesc(pAd
, pRxContext
);
1381 pUrb
= pRxContext
->pUrb
;
1382 if ((ret
= RTUSB_SUBMIT_URB(pUrb
))!=0)
1385 RTMP_IRQ_LOCK(&pAd
->BulkInLock
, IrqFlags
);
1386 pRxContext
->InUse
= FALSE
;
1387 pRxContext
->IRPPending
= FALSE
;
1390 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
1391 DBGPRINT(RT_DEBUG_ERROR
, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret
));
1396 RTMP_IRQ_LOCK(&pAd
->BulkInLock
, IrqFlags
);
1397 pRxContext
->IRPPending
= TRUE
;
1398 //NdisInterlockedIncrement(&pAd->PendingRx);
1400 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
1403 ASSERT((pRxContext
->InUse
== pRxContext
->IRPPending
));
1404 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
1410 ========================================================================
1412 Routine Description:
1413 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
1414 to USB. It checks if an Rx Descriptor is available and passes the
1415 the coresponding buffer to be filled. If no descriptor is available
1416 fails the request. When setting the completion routine we pass our
1417 Adapter Object as Context.
1422 TRUE found matched tuple cache
1423 FALSE no matched found
1427 ========================================================================
1429 #define fRTMP_ADAPTER_NEED_STOP_RX \
1430 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
1431 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
1432 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
1434 #define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
1435 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
1436 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
1437 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
1439 VOID
RTUSBBulkReceive(
1440 IN PRTMP_ADAPTER pAd
)
1442 PRX_CONTEXT pRxContext
;
1443 unsigned long IrqFlags
;
1447 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX
))
1453 RTMP_IRQ_LOCK(&pAd
->BulkInLock
, IrqFlags
);
1454 pRxContext
= &(pAd
->RxContext
[pAd
->NextRxBulkInReadIndex
]);
1455 if (((pRxContext
->InUse
== FALSE
) && (pRxContext
->Readable
== TRUE
)) &&
1456 (pRxContext
->bRxHandling
== FALSE
))
1458 pRxContext
->bRxHandling
= TRUE
;
1459 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
1461 // read RxContext, Since not
1462 STARxDoneInterruptHandle(pAd
, TRUE
);
1464 // Finish to handle this bulkIn buffer.
1465 RTMP_IRQ_LOCK(&pAd
->BulkInLock
, IrqFlags
);
1466 pRxContext
->BulkInOffset
= 0;
1467 pRxContext
->Readable
= FALSE
;
1468 pRxContext
->bRxHandling
= FALSE
;
1469 pAd
->ReadPosition
= 0;
1470 pAd
->TransferBufferLength
= 0;
1471 INC_RING_INDEX(pAd
->NextRxBulkInReadIndex
, RX_RING_SIZE
);
1472 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
1477 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
1482 if (!(RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NEED_STOP_RX
)))
1489 ========================================================================
1491 Routine Description:
1492 This routine process Rx Irp and call rx complete function.
1495 DeviceObject Pointer to the device object for next lower
1496 device. DeviceObject passed in here belongs to
1497 the next lower driver in the stack because we
1498 were invoked via IoCallDriver in USB_RxPacket
1499 AND it is not OUR device object
1500 Irp Ptr to completed IRP
1501 Context Ptr to our Adapter object (context specified
1502 in IoSetCompletionRoutine
1505 Always returns STATUS_MORE_PROCESSING_REQUIRED
1508 Always returns STATUS_MORE_PROCESSING_REQUIRED
1509 ========================================================================
1511 VOID
RTUSBBulkRxComplete(purbb_t pUrb
, struct pt_regs
*pt_regs
)
1513 // use a receive tasklet to handle received packets;
1514 // or sometimes hardware IRQ will be disabled here, so we can not
1515 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
1516 PRX_CONTEXT pRxContext
;
1521 pRxContext
= (PRX_CONTEXT
)pUrb
->context
;
1522 pAd
= pRxContext
->pAd
;
1523 pObj
= (POS_COOKIE
) pAd
->OS_Cookie
;
1525 pObj
->rx_done_task
.data
= (unsigned long)pUrb
;
1526 tasklet_hi_schedule(&pObj
->rx_done_task
);
1535 ========================================================================
1537 Routine Description:
1545 ========================================================================
1547 VOID
RTUSBKickBulkOut(
1548 IN PRTMP_ADAPTER pAd
)
1550 // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
1551 if (!RTMP_TEST_FLAG(pAd
,fRTMP_ADAPTER_NEED_STOP_TX
)
1554 #if 0 // not used now in RT28xx, but may used latter.
1555 // 1. Data Fragment has highest priority
1556 if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_FRAG
))
1558 if (((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) ||
1559 (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1562 RTUSBBulkOutDataPacket(pAd
, 0, pAd
->NextBulkOutIndex
[0]);
1565 if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_FRAG_2
))
1567 if (((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) ||
1568 (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1571 RTUSBBulkOutDataPacket(pAd
, 1, pAd
->NextBulkOutIndex
[1]);
1574 if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_FRAG_3
))
1576 if (((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) ||
1577 (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1580 RTUSBBulkOutDataPacket(pAd
, 2, pAd
->NextBulkOutIndex
[2]);
1583 if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_FRAG_4
))
1585 if (((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) ||
1586 (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1589 RTUSBBulkOutDataPacket(pAd
, 3, pAd
->NextBulkOutIndex
[3]);
1594 // 2. PS-Poll frame is next
1595 if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_PSPOLL
))
1597 RTUSBBulkOutPsPoll(pAd
);
1600 // 5. Mlme frame is next
1601 else if ((RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_MLME
)) &&
1602 (pAd
->MgmtRing
.TxSwFreeIdx
< MGMT_RING_SIZE
))
1604 RTUSBBulkOutMLMEPacket(pAd
, pAd
->MgmtRing
.TxDmaIdx
);
1607 // 6. Data frame normal is next
1608 if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL
))
1610 if (((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) ||
1611 (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1614 RTUSBBulkOutDataPacket(pAd
, 0, pAd
->NextBulkOutIndex
[0]);
1617 if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL_2
))
1619 if (((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) ||
1620 (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1623 RTUSBBulkOutDataPacket(pAd
, 1, pAd
->NextBulkOutIndex
[1]);
1626 if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL_3
))
1628 if (((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) ||
1629 (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1632 RTUSBBulkOutDataPacket(pAd
, 2, pAd
->NextBulkOutIndex
[2]);
1635 if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NORMAL_4
))
1637 if (((!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) ||
1638 (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1641 RTUSBBulkOutDataPacket(pAd
, 3, pAd
->NextBulkOutIndex
[3]);
1645 // 7. Null frame is the last
1646 else if (RTUSB_TEST_BULK_FLAG(pAd
, fRTUSB_BULK_OUT_DATA_NULL
))
1648 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
))
1650 RTUSBBulkOutNullFrame(pAd
);
1654 // 8. No data avaliable
1663 ========================================================================
1665 Routine Description:
1666 Call from Reset action after BulkOut failed.
1673 ========================================================================
1675 VOID
RTUSBCleanUpDataBulkOutQueue(
1676 IN PRTMP_ADAPTER pAd
)
1679 PHT_TX_CONTEXT pTxContext
;
1681 DBGPRINT(RT_DEBUG_TRACE
, ("--->CleanUpDataBulkOutQueue\n"));
1683 for (Idx
= 0; Idx
< 4; Idx
++)
1685 pTxContext
= &pAd
->TxContext
[Idx
];
1687 pTxContext
->CurWritePosition
= pTxContext
->NextBulkOutPosition
;
1688 pTxContext
->LastOne
= FALSE
;
1689 NdisAcquireSpinLock(&pAd
->BulkOutLock
[Idx
]);
1690 pAd
->BulkOutPending
[Idx
] = FALSE
;
1691 NdisReleaseSpinLock(&pAd
->BulkOutLock
[Idx
]);
1694 DBGPRINT(RT_DEBUG_TRACE
, ("<---CleanUpDataBulkOutQueue\n"));
1698 ========================================================================
1700 Routine Description:
1708 ========================================================================
1710 VOID
RTUSBCleanUpMLMEBulkOutQueue(
1711 IN PRTMP_ADAPTER pAd
)
1713 DBGPRINT(RT_DEBUG_TRACE
, ("--->CleanUpMLMEBulkOutQueue\n"));
1715 #if 0 // Do nothing!
1716 NdisAcquireSpinLock(&pAd
->MLMEBulkOutLock
);
1717 while (pAd
->PrioRingTxCnt
> 0)
1719 pAd
->MLMEContext
[pAd
->PrioRingFirstIndex
].InUse
= FALSE
;
1721 pAd
->PrioRingFirstIndex
++;
1722 if (pAd
->PrioRingFirstIndex
>= MGMT_RING_SIZE
)
1724 pAd
->PrioRingFirstIndex
= 0;
1727 pAd
->PrioRingTxCnt
--;
1729 NdisReleaseSpinLock(&pAd
->MLMEBulkOutLock
);
1732 DBGPRINT(RT_DEBUG_TRACE
, ("<---CleanUpMLMEBulkOutQueue\n"));
1737 ========================================================================
1739 Routine Description:
1748 ========================================================================
1750 VOID
RTUSBCancelPendingIRPs(
1751 IN PRTMP_ADAPTER pAd
)
1753 RTUSBCancelPendingBulkInIRP(pAd
);
1754 RTUSBCancelPendingBulkOutIRP(pAd
);
1758 ========================================================================
1760 Routine Description:
1768 ========================================================================
1770 VOID
RTUSBCancelPendingBulkInIRP(
1771 IN PRTMP_ADAPTER pAd
)
1773 PRX_CONTEXT pRxContext
;
1776 DBGPRINT_RAW(RT_DEBUG_TRACE
, ("--->RTUSBCancelPendingBulkInIRP\n"));
1777 for ( i
= 0; i
< (RX_RING_SIZE
); i
++)
1779 pRxContext
= &(pAd
->RxContext
[i
]);
1780 if(pRxContext
->IRPPending
== TRUE
)
1782 RTUSB_UNLINK_URB(pRxContext
->pUrb
);
1783 pRxContext
->IRPPending
= FALSE
;
1784 pRxContext
->InUse
= FALSE
;
1785 //NdisInterlockedDecrement(&pAd->PendingRx);
1789 DBGPRINT_RAW(RT_DEBUG_TRACE
, ("<---RTUSBCancelPendingBulkInIRP\n"));
1794 ========================================================================
1796 Routine Description:
1804 ========================================================================
1806 VOID
RTUSBCancelPendingBulkOutIRP(
1807 IN PRTMP_ADAPTER pAd
)
1809 PHT_TX_CONTEXT pHTTXContext
;
1810 PTX_CONTEXT pMLMEContext
;
1811 PTX_CONTEXT pBeaconContext
;
1812 PTX_CONTEXT pNullContext
;
1813 PTX_CONTEXT pPsPollContext
;
1814 PTX_CONTEXT pRTSContext
;
1816 // unsigned int IrqFlags;
1817 // NDIS_SPIN_LOCK *pLock;
1818 // BOOLEAN *pPending;
1821 // pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
1822 // pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
1824 for (Idx
= 0; Idx
< 4; Idx
++)
1826 pHTTXContext
= &(pAd
->TxContext
[Idx
]);
1828 if (pHTTXContext
->IRPPending
== TRUE
)
1831 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1832 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1833 // when the last IRP on the list has been cancelled; that's how we exit this loop
1836 RTUSB_UNLINK_URB(pHTTXContext
->pUrb
);
1838 // Sleep 200 microseconds to give cancellation time to work
1842 pAd
->BulkOutPending
[Idx
] = FALSE
;
1845 //RTMP_IRQ_LOCK(pLock, IrqFlags);
1846 for (i
= 0; i
< MGMT_RING_SIZE
; i
++)
1848 pMLMEContext
= (PTX_CONTEXT
)pAd
->MgmtRing
.Cell
[i
].AllocVa
;
1849 if(pMLMEContext
&& (pMLMEContext
->IRPPending
== TRUE
))
1852 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1853 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1854 // when the last IRP on the list has been cancelled; that's how we exit this loop
1857 RTUSB_UNLINK_URB(pMLMEContext
->pUrb
);
1858 pMLMEContext
->IRPPending
= FALSE
;
1860 // Sleep 200 microsecs to give cancellation time to work
1864 pAd
->BulkOutPending
[MGMTPIPEIDX
] = FALSE
;
1865 //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
1868 for (i
= 0; i
< BEACON_RING_SIZE
; i
++)
1870 pBeaconContext
= &(pAd
->BeaconContext
[i
]);
1872 if(pBeaconContext
->IRPPending
== TRUE
)
1875 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1876 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1877 // when the last IRP on the list has been cancelled; that's how we exit this loop
1880 RTUSB_UNLINK_URB(pBeaconContext
->pUrb
);
1882 // Sleep 200 microsecs to give cancellation time to work
1887 pNullContext
= &(pAd
->NullContext
);
1888 if (pNullContext
->IRPPending
== TRUE
)
1889 RTUSB_UNLINK_URB(pNullContext
->pUrb
);
1891 pRTSContext
= &(pAd
->RTSContext
);
1892 if (pRTSContext
->IRPPending
== TRUE
)
1893 RTUSB_UNLINK_URB(pRTSContext
->pUrb
);
1895 pPsPollContext
= &(pAd
->PsPollContext
);
1896 if (pPsPollContext
->IRPPending
== TRUE
)
1897 RTUSB_UNLINK_URB(pPsPollContext
->pUrb
);
1899 for (Idx
= 0; Idx
< 4; Idx
++)
1901 NdisAcquireSpinLock(&pAd
->BulkOutLock
[Idx
]);
1902 pAd
->BulkOutPending
[Idx
] = FALSE
;
1903 NdisReleaseSpinLock(&pAd
->BulkOutLock
[Idx
]);