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