Commit | Line | Data |
---|---|---|
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 | 44 | u8 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 |
49 | void 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 |
61 | void 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 |
99 | void 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 | 131 | void 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 | 182 | void 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 BZ |
300 | /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ |
301 | /* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */ | |
66cd8d6e BZ |
302 | pHTTXContext->ENextBulkOutPosition = |
303 | TmpBulkEndPos; | |
c55519ff GKH |
304 | break; |
305 | } | |
306 | } | |
9f548a2a | 307 | /* end Iverson */ |
66cd8d6e | 308 | else { |
9f548a2a | 309 | if (((ThisBulkSize & 0xffff8000) != 0) || ((ThisBulkSize & 0x6000) == 0x6000)) { /* Limit BulkOut size to about 24k bytes. */ |
66cd8d6e BZ |
310 | pHTTXContext->ENextBulkOutPosition = |
311 | TmpBulkEndPos; | |
c55519ff | 312 | break; |
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. */ |
9f548a2a | 314 | /* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */ |
66cd8d6e BZ |
315 | pHTTXContext->ENextBulkOutPosition = |
316 | TmpBulkEndPos; | |
c55519ff GKH |
317 | break; |
318 | } | |
319 | } | |
320 | ||
66cd8d6e | 321 | if (TmpBulkEndPos == pHTTXContext->CurWritePosition) { |
c55519ff GKH |
322 | pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; |
323 | break; | |
324 | } | |
325 | ||
66cd8d6e BZ |
326 | if (pTxInfo->QSEL != FIFO_EDCA) { |
327 | DBGPRINT(RT_DEBUG_ERROR, | |
328 | ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", | |
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; | |
66cd8d6e BZ |
477 | if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { |
478 | DBGPRINT(RT_DEBUG_ERROR, | |
479 | ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", | |
480 | ret)); | |
c55519ff GKH |
481 | |
482 | BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
483 | pAd->BulkOutPending[BulkOutPipeId] = FALSE; | |
484 | pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; | |
485 | BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
486 | ||
487 | return; | |
488 | } | |
489 | ||
490 | BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
491 | pHTTXContext->IRPPending = TRUE; | |
492 | BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
493 | pAd->BulkOutReq++; | |
494 | ||
495 | } | |
496 | ||
8a10a546 | 497 | void RTUSBBulkOutDataPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs) |
c55519ff | 498 | { |
62eb734b BZ |
499 | struct rt_ht_tx_context *pHTTXContext; |
500 | struct rt_rtmp_adapter *pAd; | |
8a10a546 | 501 | struct os_cookie *pObj; |
51126deb | 502 | u8 BulkOutPipeId; |
c55519ff | 503 | |
62eb734b | 504 | pHTTXContext = (struct rt_ht_tx_context *)pUrb->context; |
66cd8d6e | 505 | pAd = pHTTXContext->pAd; |
8a10a546 | 506 | pObj = (struct os_cookie *)pAd->OS_Cookie; |
c55519ff | 507 | |
9f548a2a | 508 | /* Store BulkOut PipeId */ |
66cd8d6e | 509 | BulkOutPipeId = pHTTXContext->BulkOutPipeId; |
c55519ff GKH |
510 | pAd->BulkOutDataOneSecCount++; |
511 | ||
66cd8d6e BZ |
512 | switch (BulkOutPipeId) { |
513 | case 0: | |
514 | pObj->ac0_dma_done_task.data = (unsigned long)pUrb; | |
515 | tasklet_hi_schedule(&pObj->ac0_dma_done_task); | |
516 | break; | |
517 | case 1: | |
518 | pObj->ac1_dma_done_task.data = (unsigned long)pUrb; | |
519 | tasklet_hi_schedule(&pObj->ac1_dma_done_task); | |
520 | break; | |
521 | case 2: | |
522 | pObj->ac2_dma_done_task.data = (unsigned long)pUrb; | |
523 | tasklet_hi_schedule(&pObj->ac2_dma_done_task); | |
524 | break; | |
525 | case 3: | |
526 | pObj->ac3_dma_done_task.data = (unsigned long)pUrb; | |
527 | tasklet_hi_schedule(&pObj->ac3_dma_done_task); | |
528 | break; | |
c55519ff | 529 | } |
ca97b838 | 530 | |
c55519ff | 531 | } |
c55519ff | 532 | |
c55519ff GKH |
533 | /* |
534 | ======================================================================== | |
535 | ||
536 | Routine Description: | |
537 | ||
538 | Arguments: | |
539 | ||
540 | Return Value: | |
541 | ||
542 | Note: NULL frame use BulkOutPipeId = 0 | |
543 | ||
544 | ======================================================================== | |
545 | */ | |
62eb734b | 546 | void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd) |
c55519ff | 547 | { |
62eb734b | 548 | struct rt_tx_context *pNullContext = &(pAd->NullContext); |
66cd8d6e BZ |
549 | PURB pUrb; |
550 | int ret = 0; | |
551 | unsigned long IrqFlags; | |
c55519ff GKH |
552 | |
553 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); | |
66cd8d6e BZ |
554 | if ((pAd->BulkOutPending[0] == TRUE) |
555 | || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { | |
c55519ff GKH |
556 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); |
557 | return; | |
558 | } | |
559 | pAd->BulkOutPending[0] = TRUE; | |
560 | pAd->watchDogTxPendingCnt[0] = 1; | |
561 | pNullContext->IRPPending = TRUE; | |
562 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); | |
563 | ||
9f548a2a | 564 | /* Increase Total transmit byte counter */ |
66cd8d6e | 565 | pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize; |
c55519ff | 566 | |
9f548a2a | 567 | /* Clear Null frame bulk flag */ |
c55519ff GKH |
568 | RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); |
569 | ||
9f548a2a | 570 | /* Init Tx context descriptor */ |
66cd8d6e BZ |
571 | RTUSBInitTxDesc(pAd, pNullContext, 0, |
572 | (usb_complete_t) RTUSBBulkOutNullFrameComplete); | |
c55519ff GKH |
573 | |
574 | pUrb = pNullContext->pUrb; | |
66cd8d6e | 575 | if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { |
c55519ff GKH |
576 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); |
577 | pAd->BulkOutPending[0] = FALSE; | |
578 | pAd->watchDogTxPendingCnt[0] = 0; | |
579 | pNullContext->IRPPending = FALSE; | |
580 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); | |
581 | ||
66cd8d6e BZ |
582 | DBGPRINT(RT_DEBUG_ERROR, |
583 | ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", | |
584 | ret)); | |
c55519ff GKH |
585 | return; |
586 | } | |
587 | ||
588 | } | |
589 | ||
9f548a2a | 590 | /* NULL frame use BulkOutPipeId = 0 */ |
8a10a546 | 591 | void RTUSBBulkOutNullFrameComplete(struct urb *pUrb, struct pt_regs * pt_regs) |
c55519ff | 592 | { |
62eb734b BZ |
593 | struct rt_rtmp_adapter *pAd; |
594 | struct rt_tx_context *pNullContext; | |
51126deb | 595 | int Status; |
8a10a546 | 596 | struct os_cookie *pObj; |
c55519ff | 597 | |
62eb734b | 598 | pNullContext = (struct rt_tx_context *)pUrb->context; |
66cd8d6e BZ |
599 | pAd = pNullContext->pAd; |
600 | Status = pUrb->status; | |
c55519ff | 601 | |
8a10a546 | 602 | pObj = (struct os_cookie *)pAd->OS_Cookie; |
c55519ff GKH |
603 | pObj->null_frame_complete_task.data = (unsigned long)pUrb; |
604 | tasklet_hi_schedule(&pObj->null_frame_complete_task); | |
c55519ff GKH |
605 | } |
606 | ||
c55519ff GKH |
607 | /* |
608 | ======================================================================== | |
609 | ||
610 | Routine Description: | |
611 | ||
612 | Arguments: | |
613 | ||
614 | Return Value: | |
615 | ||
616 | Note: MLME use BulkOutPipeId = 0 | |
617 | ||
618 | ======================================================================== | |
619 | */ | |
62eb734b | 620 | void RTUSBBulkOutMLMEPacket(struct rt_rtmp_adapter *pAd, u8 Index) |
c55519ff | 621 | { |
62eb734b | 622 | struct rt_tx_context *pMLMEContext; |
66cd8d6e BZ |
623 | PURB pUrb; |
624 | int ret = 0; | |
625 | unsigned long IrqFlags; | |
c55519ff | 626 | |
66cd8d6e | 627 | pMLMEContext = |
62eb734b | 628 | (struct rt_tx_context *)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa; |
c55519ff GKH |
629 | pUrb = pMLMEContext->pUrb; |
630 | ||
631 | if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) || | |
66cd8d6e BZ |
632 | (pMLMEContext->InUse == FALSE) || |
633 | (pMLMEContext->bWaitingBulkOut == FALSE)) { | |
c55519ff | 634 | |
9f548a2a | 635 | /* Clear MLME bulk flag */ |
c55519ff GKH |
636 | RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); |
637 | ||
638 | return; | |
639 | } | |
640 | ||
c55519ff | 641 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); |
66cd8d6e BZ |
642 | if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) |
643 | || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { | |
c55519ff GKH |
644 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); |
645 | return; | |
646 | } | |
647 | ||
648 | pAd->BulkOutPending[MGMTPIPEIDX] = TRUE; | |
649 | pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1; | |
650 | pMLMEContext->IRPPending = TRUE; | |
651 | pMLMEContext->bWaitingBulkOut = FALSE; | |
652 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); | |
653 | ||
9f548a2a | 654 | /* Increase Total transmit byte counter */ |
66cd8d6e | 655 | pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize; |
c55519ff | 656 | |
9f548a2a | 657 | /* Clear MLME bulk flag */ |
c55519ff GKH |
658 | RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); |
659 | ||
9f548a2a | 660 | /* Init Tx context descriptor */ |
66cd8d6e BZ |
661 | RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, |
662 | (usb_complete_t) RTUSBBulkOutMLMEPacketComplete); | |
c55519ff | 663 | |
9f548a2a | 664 | /*For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping. */ |
66cd8d6e | 665 | pUrb->transfer_dma = 0; |
c55519ff | 666 | pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP); |
c55519ff GKH |
667 | |
668 | pUrb = pMLMEContext->pUrb; | |
66cd8d6e BZ |
669 | if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { |
670 | DBGPRINT(RT_DEBUG_ERROR, | |
671 | ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", | |
672 | ret)); | |
c55519ff GKH |
673 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); |
674 | pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; | |
675 | pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0; | |
676 | pMLMEContext->IRPPending = FALSE; | |
677 | pMLMEContext->bWaitingBulkOut = TRUE; | |
678 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); | |
679 | ||
680 | return; | |
681 | } | |
9f548a2a BZ |
682 | /*DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n")); */ |
683 | /* printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx); */ | |
c55519ff GKH |
684 | } |
685 | ||
8a10a546 | 686 | void RTUSBBulkOutMLMEPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs) |
c55519ff | 687 | { |
62eb734b BZ |
688 | struct rt_tx_context *pMLMEContext; |
689 | struct rt_rtmp_adapter *pAd; | |
51126deb | 690 | int Status; |
8a10a546 | 691 | struct os_cookie *pObj; |
66cd8d6e | 692 | int index; |
c55519ff | 693 | |
9f548a2a | 694 | /*DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n")); */ |
62eb734b | 695 | pMLMEContext = (struct rt_tx_context *)pUrb->context; |
66cd8d6e | 696 | pAd = pMLMEContext->pAd; |
8a10a546 | 697 | pObj = (struct os_cookie *)pAd->OS_Cookie; |
66cd8d6e BZ |
698 | Status = pUrb->status; |
699 | index = pMLMEContext->SelfIdx; | |
c55519ff | 700 | |
c55519ff GKH |
701 | pObj->mgmt_dma_done_task.data = (unsigned long)pUrb; |
702 | tasklet_hi_schedule(&pObj->mgmt_dma_done_task); | |
c55519ff GKH |
703 | } |
704 | ||
c55519ff GKH |
705 | /* |
706 | ======================================================================== | |
707 | ||
708 | Routine Description: | |
709 | ||
710 | Arguments: | |
711 | ||
712 | Return Value: | |
713 | ||
714 | Note: PsPoll use BulkOutPipeId = 0 | |
715 | ||
716 | ======================================================================== | |
717 | */ | |
62eb734b | 718 | void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd) |
c55519ff | 719 | { |
62eb734b | 720 | struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext); |
66cd8d6e BZ |
721 | PURB pUrb; |
722 | int ret = 0; | |
723 | unsigned long IrqFlags; | |
c55519ff GKH |
724 | |
725 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); | |
66cd8d6e BZ |
726 | if ((pAd->BulkOutPending[0] == TRUE) |
727 | || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { | |
c55519ff GKH |
728 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); |
729 | return; | |
730 | } | |
731 | pAd->BulkOutPending[0] = TRUE; | |
732 | pAd->watchDogTxPendingCnt[0] = 1; | |
733 | pPsPollContext->IRPPending = TRUE; | |
734 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); | |
735 | ||
9f548a2a | 736 | /* Clear PS-Poll bulk flag */ |
c55519ff GKH |
737 | RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); |
738 | ||
9f548a2a | 739 | /* Init Tx context descriptor */ |
66cd8d6e BZ |
740 | RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, |
741 | (usb_complete_t) RTUSBBulkOutPsPollComplete); | |
c55519ff GKH |
742 | |
743 | pUrb = pPsPollContext->pUrb; | |
66cd8d6e | 744 | if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { |
c55519ff GKH |
745 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); |
746 | pAd->BulkOutPending[0] = FALSE; | |
747 | pAd->watchDogTxPendingCnt[0] = 0; | |
748 | pPsPollContext->IRPPending = FALSE; | |
749 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); | |
750 | ||
66cd8d6e BZ |
751 | DBGPRINT(RT_DEBUG_ERROR, |
752 | ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", | |
753 | ret)); | |
c55519ff GKH |
754 | return; |
755 | } | |
756 | ||
757 | } | |
758 | ||
9f548a2a | 759 | /* PS-Poll frame use BulkOutPipeId = 0 */ |
8a10a546 | 760 | void RTUSBBulkOutPsPollComplete(struct urb *pUrb, struct pt_regs * pt_regs) |
c55519ff | 761 | { |
62eb734b BZ |
762 | struct rt_rtmp_adapter *pAd; |
763 | struct rt_tx_context *pPsPollContext; | |
51126deb | 764 | int Status; |
8a10a546 | 765 | struct os_cookie *pObj; |
c55519ff | 766 | |
62eb734b | 767 | pPsPollContext = (struct rt_tx_context *)pUrb->context; |
c55519ff GKH |
768 | pAd = pPsPollContext->pAd; |
769 | Status = pUrb->status; | |
770 | ||
8a10a546 | 771 | pObj = (struct os_cookie *)pAd->OS_Cookie; |
c55519ff GKH |
772 | pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb; |
773 | tasklet_hi_schedule(&pObj->pspoll_frame_complete_task); | |
c55519ff GKH |
774 | } |
775 | ||
62eb734b | 776 | void DoBulkIn(struct rt_rtmp_adapter *pAd) |
c55519ff | 777 | { |
62eb734b | 778 | struct rt_rx_context *pRxContext; |
66cd8d6e BZ |
779 | PURB pUrb; |
780 | int ret = 0; | |
781 | unsigned long IrqFlags; | |
c55519ff GKH |
782 | |
783 | RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); | |
784 | pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]); | |
66cd8d6e BZ |
785 | if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) |
786 | || (pRxContext->InUse == TRUE)) { | |
c55519ff GKH |
787 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); |
788 | return; | |
789 | } | |
790 | pRxContext->InUse = TRUE; | |
791 | pRxContext->IRPPending = TRUE; | |
792 | pAd->PendingRx++; | |
793 | pAd->BulkInReq++; | |
794 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); | |
795 | ||
9f548a2a | 796 | /* Init Rx context descriptor */ |
c55519ff GKH |
797 | NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset); |
798 | RTUSBInitRxDesc(pAd, pRxContext); | |
799 | ||
800 | pUrb = pRxContext->pUrb; | |
9f548a2a | 801 | if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { /* fail */ |
c55519ff GKH |
802 | |
803 | RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); | |
804 | pRxContext->InUse = FALSE; | |
805 | pRxContext->IRPPending = FALSE; | |
806 | pAd->PendingRx--; | |
807 | pAd->BulkInReq--; | |
808 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); | |
66cd8d6e BZ |
809 | DBGPRINT(RT_DEBUG_ERROR, |
810 | ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret)); | |
9f548a2a | 811 | } else { /* success */ |
c55519ff | 812 | ASSERT((pRxContext->InUse == pRxContext->IRPPending)); |
9f548a2a | 813 | /*printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex); */ |
c55519ff GKH |
814 | } |
815 | } | |
816 | ||
c55519ff GKH |
817 | /* |
818 | ======================================================================== | |
819 | ||
820 | Routine Description: | |
821 | USB_RxPacket initializes a URB and uses the Rx IRP to submit it | |
822 | to USB. It checks if an Rx Descriptor is available and passes the | |
823 | the coresponding buffer to be filled. If no descriptor is available | |
824 | fails the request. When setting the completion routine we pass our | |
825 | Adapter Object as Context. | |
826 | ||
827 | Arguments: | |
828 | ||
829 | Return Value: | |
830 | TRUE found matched tuple cache | |
831 | FALSE no matched found | |
832 | ||
833 | Note: | |
834 | ||
835 | ======================================================================== | |
836 | */ | |
837 | #define fRTMP_ADAPTER_NEED_STOP_RX \ | |
838 | (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \ | |
839 | fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \ | |
840 | fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET) | |
841 | ||
842 | #define fRTMP_ADAPTER_NEED_STOP_HANDLE_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) | |
846 | ||
62eb734b | 847 | void RTUSBBulkReceive(struct rt_rtmp_adapter *pAd) |
c55519ff | 848 | { |
62eb734b | 849 | struct rt_rx_context *pRxContext; |
66cd8d6e | 850 | unsigned long IrqFlags; |
c55519ff GKH |
851 | |
852 | /* sanity check */ | |
853 | if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX)) | |
854 | return; | |
855 | ||
66cd8d6e | 856 | while (1) { |
c55519ff GKH |
857 | |
858 | RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); | |
859 | pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]); | |
66cd8d6e BZ |
860 | if (((pRxContext->InUse == FALSE) |
861 | && (pRxContext->Readable == TRUE)) | |
862 | && (pRxContext->bRxHandling == FALSE)) { | |
c55519ff GKH |
863 | pRxContext->bRxHandling = TRUE; |
864 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); | |
865 | ||
9f548a2a | 866 | /* read RxContext, Since not */ |
303ee97d | 867 | STARxDoneInterruptHandle(pAd, TRUE); |
c55519ff | 868 | |
9f548a2a | 869 | /* Finish to handle this bulkIn buffer. */ |
c55519ff GKH |
870 | RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); |
871 | pRxContext->BulkInOffset = 0; | |
872 | pRxContext->Readable = FALSE; | |
873 | pRxContext->bRxHandling = FALSE; | |
874 | pAd->ReadPosition = 0; | |
875 | pAd->TransferBufferLength = 0; | |
66cd8d6e BZ |
876 | INC_RING_INDEX(pAd->NextRxBulkInReadIndex, |
877 | RX_RING_SIZE); | |
c55519ff GKH |
878 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); |
879 | ||
66cd8d6e | 880 | } else { |
c55519ff GKH |
881 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); |
882 | break; | |
883 | } | |
884 | } | |
885 | ||
886 | if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX))) | |
887 | DoBulkIn(pAd); | |
888 | ||
889 | } | |
890 | ||
c55519ff GKH |
891 | /* |
892 | ======================================================================== | |
893 | ||
894 | Routine Description: | |
895 | This routine process Rx Irp and call rx complete function. | |
896 | ||
897 | Arguments: | |
898 | DeviceObject Pointer to the device object for next lower | |
899 | device. DeviceObject passed in here belongs to | |
900 | the next lower driver in the stack because we | |
901 | were invoked via IoCallDriver in USB_RxPacket | |
902 | AND it is not OUR device object | |
903 | Irp Ptr to completed IRP | |
904 | Context Ptr to our Adapter object (context specified | |
905 | in IoSetCompletionRoutine | |
906 | ||
907 | Return Value: | |
908 | Always returns STATUS_MORE_PROCESSING_REQUIRED | |
909 | ||
910 | Note: | |
911 | Always returns STATUS_MORE_PROCESSING_REQUIRED | |
912 | ======================================================================== | |
913 | */ | |
8a10a546 | 914 | void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs) |
c55519ff | 915 | { |
9f548a2a BZ |
916 | /* use a receive tasklet to handle received packets; */ |
917 | /* or sometimes hardware IRQ will be disabled here, so we can not */ | |
918 | /* use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :< */ | |
62eb734b BZ |
919 | struct rt_rx_context *pRxContext; |
920 | struct rt_rtmp_adapter *pAd; | |
8a10a546 | 921 | struct os_cookie *pObj; |
c55519ff | 922 | |
62eb734b | 923 | pRxContext = (struct rt_rx_context *)pUrb->context; |
66cd8d6e | 924 | pAd = pRxContext->pAd; |
8a10a546 | 925 | pObj = (struct os_cookie *)pAd->OS_Cookie; |
c55519ff GKH |
926 | |
927 | pObj->rx_done_task.data = (unsigned long)pUrb; | |
928 | tasklet_hi_schedule(&pObj->rx_done_task); | |
929 | ||
930 | } | |
931 | ||
c55519ff GKH |
932 | /* |
933 | ======================================================================== | |
934 | ||
935 | Routine Description: | |
936 | ||
937 | Arguments: | |
938 | ||
939 | Return Value: | |
940 | ||
941 | Note: | |
942 | ||
943 | ======================================================================== | |
944 | */ | |
62eb734b | 945 | void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd) |
c55519ff | 946 | { |
9f548a2a | 947 | /* BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged. */ |
66cd8d6e BZ |
948 | if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX) |
949 | ) { | |
9f548a2a | 950 | /* 2. PS-Poll frame is next */ |
d24e4497 | 951 | if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL)) |
c55519ff | 952 | RTUSBBulkOutPsPoll(pAd); |
9f548a2a | 953 | /* 5. Mlme frame is next */ |
ca97b838 | 954 | else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) || |
66cd8d6e | 955 | (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) { |
c55519ff GKH |
956 | RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx); |
957 | } | |
9f548a2a | 958 | /* 6. Data frame normal is next */ |
66cd8d6e BZ |
959 | if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL)) { |
960 | if (((!RTMP_TEST_FLAG | |
961 | (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) | |
962 | || | |
963 | (!OPSTATUS_TEST_FLAG | |
964 | (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) | |
965 | )) { | |
966 | RTUSBBulkOutDataPacket(pAd, 0, | |
967 | pAd-> | |
968 | NextBulkOutIndex[0]); | |
c55519ff GKH |
969 | } |
970 | } | |
66cd8d6e BZ |
971 | if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2)) { |
972 | if (((!RTMP_TEST_FLAG | |
973 | (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) | |
974 | || | |
975 | (!OPSTATUS_TEST_FLAG | |
976 | (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) | |
977 | )) { | |
978 | RTUSBBulkOutDataPacket(pAd, 1, | |
979 | pAd-> | |
980 | NextBulkOutIndex[1]); | |
c55519ff GKH |
981 | } |
982 | } | |
66cd8d6e BZ |
983 | if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3)) { |
984 | if (((!RTMP_TEST_FLAG | |
985 | (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) | |
986 | || | |
987 | (!OPSTATUS_TEST_FLAG | |
988 | (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) | |
989 | )) { | |
990 | RTUSBBulkOutDataPacket(pAd, 2, | |
991 | pAd-> | |
992 | NextBulkOutIndex[2]); | |
c55519ff GKH |
993 | } |
994 | } | |
66cd8d6e BZ |
995 | if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4)) { |
996 | if (((!RTMP_TEST_FLAG | |
997 | (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) | |
998 | || | |
999 | (!OPSTATUS_TEST_FLAG | |
1000 | (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) | |
1001 | )) { | |
1002 | RTUSBBulkOutDataPacket(pAd, 3, | |
1003 | pAd-> | |
1004 | NextBulkOutIndex[3]); | |
c55519ff GKH |
1005 | } |
1006 | } | |
9f548a2a | 1007 | /* 7. Null frame is the last */ |
66cd8d6e BZ |
1008 | else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) { |
1009 | if (!RTMP_TEST_FLAG | |
1010 | (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { | |
c55519ff GKH |
1011 | RTUSBBulkOutNullFrame(pAd); |
1012 | } | |
1013 | } | |
9f548a2a | 1014 | /* 8. No data avaliable */ |
d24e4497 AG |
1015 | else |
1016 | ; | |
c55519ff | 1017 | } |
c55519ff GKH |
1018 | } |
1019 | ||
1020 | /* | |
1021 | ======================================================================== | |
1022 | ||
1023 | Routine Description: | |
1024 | Call from Reset action after BulkOut failed. | |
1025 | Arguments: | |
1026 | ||
1027 | Return Value: | |
1028 | ||
1029 | Note: | |
1030 | ||
1031 | ======================================================================== | |
1032 | */ | |
62eb734b | 1033 | void RTUSBCleanUpDataBulkOutQueue(struct rt_rtmp_adapter *pAd) |
c55519ff | 1034 | { |
51126deb | 1035 | u8 Idx; |
62eb734b | 1036 | struct rt_ht_tx_context *pTxContext; |
c55519ff GKH |
1037 | |
1038 | DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n")); | |
1039 | ||
66cd8d6e | 1040 | for (Idx = 0; Idx < 4; Idx++) { |
c55519ff GKH |
1041 | pTxContext = &pAd->TxContext[Idx]; |
1042 | ||
1043 | pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition; | |
1044 | pTxContext->LastOne = FALSE; | |
1045 | NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); | |
1046 | pAd->BulkOutPending[Idx] = FALSE; | |
1047 | NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); | |
1048 | } | |
1049 | ||
1050 | DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n")); | |
1051 | } | |
1052 | ||
1053 | /* | |
1054 | ======================================================================== | |
1055 | ||
1056 | Routine Description: | |
1057 | ||
1058 | Arguments: | |
1059 | ||
1060 | Return Value: | |
1061 | ||
1062 | Note: | |
1063 | ||
1064 | ======================================================================== | |
1065 | */ | |
62eb734b | 1066 | void RTUSBCleanUpMLMEBulkOutQueue(struct rt_rtmp_adapter *pAd) |
c55519ff GKH |
1067 | { |
1068 | DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n")); | |
c55519ff GKH |
1069 | DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n")); |
1070 | } | |
1071 | ||
c55519ff GKH |
1072 | /* |
1073 | ======================================================================== | |
1074 | ||
1075 | Routine Description: | |
1076 | ||
1077 | Arguments: | |
1078 | ||
1079 | Return Value: | |
1080 | ||
c55519ff GKH |
1081 | Note: |
1082 | ||
1083 | ======================================================================== | |
1084 | */ | |
62eb734b | 1085 | void RTUSBCancelPendingIRPs(struct rt_rtmp_adapter *pAd) |
c55519ff GKH |
1086 | { |
1087 | RTUSBCancelPendingBulkInIRP(pAd); | |
1088 | RTUSBCancelPendingBulkOutIRP(pAd); | |
1089 | } | |
1090 | ||
1091 | /* | |
1092 | ======================================================================== | |
1093 | ||
1094 | Routine Description: | |
1095 | ||
1096 | Arguments: | |
1097 | ||
1098 | Return Value: | |
1099 | ||
1100 | Note: | |
1101 | ||
1102 | ======================================================================== | |
1103 | */ | |
62eb734b | 1104 | void RTUSBCancelPendingBulkInIRP(struct rt_rtmp_adapter *pAd) |
c55519ff | 1105 | { |
62eb734b | 1106 | struct rt_rx_context *pRxContext; |
51126deb | 1107 | u32 i; |
c55519ff GKH |
1108 | |
1109 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n")); | |
66cd8d6e | 1110 | for (i = 0; i < (RX_RING_SIZE); i++) { |
c55519ff | 1111 | pRxContext = &(pAd->RxContext[i]); |
66cd8d6e | 1112 | if (pRxContext->IRPPending == TRUE) { |
c55519ff GKH |
1113 | RTUSB_UNLINK_URB(pRxContext->pUrb); |
1114 | pRxContext->IRPPending = FALSE; | |
1115 | pRxContext->InUse = FALSE; | |
9f548a2a BZ |
1116 | /*NdisInterlockedDecrement(&pAd->PendingRx); */ |
1117 | /*pAd->PendingRx--; */ | |
c55519ff GKH |
1118 | } |
1119 | } | |
1120 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n")); | |
1121 | } | |
1122 | ||
c55519ff GKH |
1123 | /* |
1124 | ======================================================================== | |
1125 | ||
1126 | Routine Description: | |
1127 | ||
1128 | Arguments: | |
1129 | ||
1130 | Return Value: | |
1131 | ||
1132 | Note: | |
1133 | ||
1134 | ======================================================================== | |
1135 | */ | |
62eb734b | 1136 | void RTUSBCancelPendingBulkOutIRP(struct rt_rtmp_adapter *pAd) |
c55519ff | 1137 | { |
62eb734b BZ |
1138 | struct rt_ht_tx_context *pHTTXContext; |
1139 | struct rt_tx_context *pMLMEContext; | |
1140 | struct rt_tx_context *pBeaconContext; | |
1141 | struct rt_tx_context *pNullContext; | |
1142 | struct rt_tx_context *pPsPollContext; | |
1143 | struct rt_tx_context *pRTSContext; | |
51126deb | 1144 | u32 i, Idx; |
9f548a2a | 1145 | /* unsigned int IrqFlags; */ |
8a10a546 | 1146 | /* spinlock_t *pLock; */ |
9f548a2a | 1147 | /* BOOLEAN *pPending; */ |
66cd8d6e | 1148 | |
9f548a2a BZ |
1149 | /* pLock = &pAd->BulkOutLock[MGMTPIPEIDX]; */ |
1150 | /* pPending = &pAd->BulkOutPending[MGMTPIPEIDX]; */ | |
66cd8d6e BZ |
1151 | |
1152 | for (Idx = 0; Idx < 4; Idx++) { | |
c55519ff GKH |
1153 | pHTTXContext = &(pAd->TxContext[Idx]); |
1154 | ||
66cd8d6e | 1155 | if (pHTTXContext->IRPPending == TRUE) { |
c55519ff | 1156 | |
9f548a2a BZ |
1157 | /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ |
1158 | /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ | |
1159 | /* when the last IRP on the list has been cancelled; that's how we exit this loop */ | |
1160 | /* */ | |
c55519ff GKH |
1161 | |
1162 | RTUSB_UNLINK_URB(pHTTXContext->pUrb); | |
1163 | ||
9f548a2a | 1164 | /* Sleep 200 microseconds to give cancellation time to work */ |
c55519ff GKH |
1165 | RTMPusecDelay(200); |
1166 | } | |
1167 | ||
c55519ff GKH |
1168 | pAd->BulkOutPending[Idx] = FALSE; |
1169 | } | |
1170 | ||
9f548a2a | 1171 | /*RTMP_IRQ_LOCK(pLock, IrqFlags); */ |
66cd8d6e | 1172 | for (i = 0; i < MGMT_RING_SIZE; i++) { |
62eb734b | 1173 | pMLMEContext = (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa; |
66cd8d6e | 1174 | if (pMLMEContext && (pMLMEContext->IRPPending == TRUE)) { |
c55519ff | 1175 | |
9f548a2a BZ |
1176 | /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ |
1177 | /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ | |
1178 | /* when the last IRP on the list has been cancelled; that's how we exit this loop */ | |
1179 | /* */ | |
c55519ff GKH |
1180 | |
1181 | RTUSB_UNLINK_URB(pMLMEContext->pUrb); | |
1182 | pMLMEContext->IRPPending = FALSE; | |
1183 | ||
9f548a2a | 1184 | /* Sleep 200 microsecs to give cancellation time to work */ |
c55519ff GKH |
1185 | RTMPusecDelay(200); |
1186 | } | |
1187 | } | |
1188 | pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; | |
9f548a2a | 1189 | /*RTMP_IRQ_UNLOCK(pLock, IrqFlags); */ |
c55519ff | 1190 | |
66cd8d6e | 1191 | for (i = 0; i < BEACON_RING_SIZE; i++) { |
c55519ff GKH |
1192 | pBeaconContext = &(pAd->BeaconContext[i]); |
1193 | ||
66cd8d6e | 1194 | if (pBeaconContext->IRPPending == TRUE) { |
c55519ff | 1195 | |
9f548a2a BZ |
1196 | /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ |
1197 | /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ | |
1198 | /* when the last IRP on the list has been cancelled; that's how we exit this loop */ | |
1199 | /* */ | |
c55519ff GKH |
1200 | |
1201 | RTUSB_UNLINK_URB(pBeaconContext->pUrb); | |
1202 | ||
9f548a2a | 1203 | /* Sleep 200 microsecs to give cancellation time to work */ |
c55519ff GKH |
1204 | RTMPusecDelay(200); |
1205 | } | |
1206 | } | |
1207 | ||
1208 | pNullContext = &(pAd->NullContext); | |
1209 | if (pNullContext->IRPPending == TRUE) | |
1210 | RTUSB_UNLINK_URB(pNullContext->pUrb); | |
1211 | ||
1212 | pRTSContext = &(pAd->RTSContext); | |
1213 | if (pRTSContext->IRPPending == TRUE) | |
1214 | RTUSB_UNLINK_URB(pRTSContext->pUrb); | |
1215 | ||
1216 | pPsPollContext = &(pAd->PsPollContext); | |
1217 | if (pPsPollContext->IRPPending == TRUE) | |
1218 | RTUSB_UNLINK_URB(pPsPollContext->pUrb); | |
1219 | ||
66cd8d6e | 1220 | for (Idx = 0; Idx < 4; Idx++) { |
c55519ff GKH |
1221 | NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); |
1222 | pAd->BulkOutPending[Idx] = FALSE; | |
1223 | NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); | |
1224 | } | |
1225 | } | |
1226 | ||
9f548a2a | 1227 | #endif /* RTMP_MAC_USB // */ |