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 
28 #ifdef RTMP_MAC_USB
29 
30 #include	"../rt_config.h"
31 
32 /*
33 ========================================================================
34 Routine Description:
35     Initialize receive data structures.
36 
37 Arguments:
38     pAd					Pointer to our adapter
39 
40 Return Value:
41 	NDIS_STATUS_SUCCESS
42 	NDIS_STATUS_RESOURCES
43 
44 Note:
45 	Initialize all receive releated private buffer, include those define
46 	in struct rt_rtmp_adapter structure and all private data structures. The mahor
47 	work is to allocate buffer for each packet and chain buffer to
48 	NDIS packet descriptor.
49 ========================================================================
50 */
NICInitRecv(struct rt_rtmp_adapter * pAd)51 int NICInitRecv(struct rt_rtmp_adapter *pAd)
52 {
53 	u8 i;
54 	int Status = NDIS_STATUS_SUCCESS;
55 	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
56 
57 	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
58 	pObj = pObj;
59 
60 	/*InterlockedExchange(&pAd->PendingRx, 0); */
61 	pAd->PendingRx = 0;
62 	pAd->NextRxBulkInReadIndex = 0;	/* Next Rx Read index */
63 	pAd->NextRxBulkInIndex = 0;	/*RX_RING_SIZE -1; // Rx Bulk pointer */
64 	pAd->NextRxBulkInPosition = 0;
65 
66 	for (i = 0; i < (RX_RING_SIZE); i++) {
67 		struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
68 
69 		/*Allocate URB */
70 		pRxContext->pUrb = RTUSB_ALLOC_URB(0);
71 		if (pRxContext->pUrb == NULL) {
72 			Status = NDIS_STATUS_RESOURCES;
73 			goto out1;
74 		}
75 		/* Allocate transfer buffer */
76 		pRxContext->TransferBuffer =
77 		    RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
78 					   &pRxContext->data_dma);
79 		if (pRxContext->TransferBuffer == NULL) {
80 			Status = NDIS_STATUS_RESOURCES;
81 			goto out1;
82 		}
83 
84 		NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
85 
86 		pRxContext->pAd = pAd;
87 		pRxContext->pIrp = NULL;
88 		pRxContext->InUse = FALSE;
89 		pRxContext->IRPPending = FALSE;
90 		pRxContext->Readable = FALSE;
91 		/*pRxContext->ReorderInUse = FALSE; */
92 		pRxContext->bRxHandling = FALSE;
93 		pRxContext->BulkInOffset = 0;
94 	}
95 
96 	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status));
97 	return Status;
98 
99 out1:
100 	for (i = 0; i < (RX_RING_SIZE); i++) {
101 		struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
102 
103 		if (NULL != pRxContext->TransferBuffer) {
104 			RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
105 					      pRxContext->TransferBuffer,
106 					      pRxContext->data_dma);
107 			pRxContext->TransferBuffer = NULL;
108 		}
109 
110 		if (NULL != pRxContext->pUrb) {
111 			RTUSB_UNLINK_URB(pRxContext->pUrb);
112 			RTUSB_FREE_URB(pRxContext->pUrb);
113 			pRxContext->pUrb = NULL;
114 		}
115 	}
116 
117 	return Status;
118 }
119 
120 /*
121 ========================================================================
122 Routine Description:
123     Initialize transmit data structures.
124 
125 Arguments:
126     pAd					Pointer to our adapter
127 
128 Return Value:
129 	NDIS_STATUS_SUCCESS
130 	NDIS_STATUS_RESOURCES
131 
132 Note:
133 ========================================================================
134 */
NICInitTransmit(struct rt_rtmp_adapter * pAd)135 int NICInitTransmit(struct rt_rtmp_adapter *pAd)
136 {
137 #define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2)	\
138 	Context->pUrb = RTUSB_ALLOC_URB(0);		\
139 	if (Context->pUrb == NULL) {			\
140 		DBGPRINT(RT_DEBUG_ERROR, msg1);		\
141 		Status = NDIS_STATUS_RESOURCES;		\
142 		goto err1; }						\
143 											\
144 	Context->TransferBuffer =				\
145 		(TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma);	\
146 	if (Context->TransferBuffer == NULL) {	\
147 		DBGPRINT(RT_DEBUG_ERROR, msg2);		\
148 		Status = NDIS_STATUS_RESOURCES;		\
149 		goto err2; }
150 
151 #define LM_URB_FREE(pObj, Context, BufferSize)				\
152 	if (NULL != Context->pUrb) {							\
153 		RTUSB_UNLINK_URB(Context->pUrb);					\
154 		RTUSB_FREE_URB(Context->pUrb);						\
155 		Context->pUrb = NULL; }								\
156 	if (NULL != Context->TransferBuffer) {				\
157 		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
158 								Context->TransferBuffer,	\
159 								Context->data_dma);			\
160 		Context->TransferBuffer = NULL; }
161 
162 	u8 i, acidx;
163 	int Status = NDIS_STATUS_SUCCESS;
164 	struct rt_tx_context *pNullContext = &(pAd->NullContext);
165 	struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext);
166 	struct rt_tx_context *pRTSContext = &(pAd->RTSContext);
167 	struct rt_tx_context *pMLMEContext = NULL;
168 /*      struct rt_ht_tx_context *pHTTXContext = NULL; */
169 	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
170 	void *RingBaseVa;
171 /*      struct rt_rtmp_tx_ring *pTxRing; */
172 	struct rt_rtmp_mgmt_ring *pMgmtRing;
173 
174 	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
175 	pObj = pObj;
176 
177 	/* Init 4 set of Tx parameters */
178 	for (acidx = 0; acidx < NUM_OF_TX_RING; acidx++) {
179 		/* Initialize all Transmit releated queues */
180 		InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
181 
182 		/* Next Local tx ring pointer waiting for buck out */
183 		pAd->NextBulkOutIndex[acidx] = acidx;
184 		pAd->BulkOutPending[acidx] = FALSE;	/* Buck Out control flag */
185 		/*pAd->DataBulkDoneIdx[acidx] = 0; */
186 	}
187 
188 	/*pAd->NextMLMEIndex    = 0; */
189 	/*pAd->PushMgmtIndex    = 0; */
190 	/*pAd->PopMgmtIndex     = 0; */
191 	/*InterlockedExchange(&pAd->MgmtQueueSize, 0); */
192 	/*InterlockedExchange(&pAd->TxCount, 0); */
193 
194 	/*pAd->PrioRingFirstIndex       = 0; */
195 	/*pAd->PrioRingTxCnt            = 0; */
196 
197 	do {
198 		/* */
199 		/* TX_RING_SIZE, 4 ACs */
200 		/* */
201 		for (acidx = 0; acidx < 4; acidx++) {
202 			struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
203 
204 			NdisZeroMemory(pHTTXContext, sizeof(struct rt_ht_tx_context));
205 			/*Allocate URB */
206 			LM_USB_ALLOC(pObj, pHTTXContext, struct rt_httx_buffer *,
207 				     sizeof(struct rt_httx_buffer), Status,
208 				     ("<-- ERROR in Alloc TX TxContext[%d] urb!\n",
209 				      acidx), done,
210 				     ("<-- ERROR in Alloc TX TxContext[%d] struct rt_httx_buffer!\n",
211 				      acidx), out1);
212 
213 			NdisZeroMemory(pHTTXContext->TransferBuffer->
214 				       Aggregation, 4);
215 			pHTTXContext->pAd = pAd;
216 			pHTTXContext->pIrp = NULL;
217 			pHTTXContext->IRPPending = FALSE;
218 			pHTTXContext->NextBulkOutPosition = 0;
219 			pHTTXContext->ENextBulkOutPosition = 0;
220 			pHTTXContext->CurWritePosition = 0;
221 			pHTTXContext->CurWriteRealPos = 0;
222 			pHTTXContext->BulkOutSize = 0;
223 			pHTTXContext->BulkOutPipeId = acidx;
224 			pHTTXContext->bRingEmpty = TRUE;
225 			pHTTXContext->bCopySavePad = FALSE;
226 			pAd->BulkOutPending[acidx] = FALSE;
227 		}
228 
229 		/* */
230 		/* MGMT_RING_SIZE */
231 		/* */
232 
233 		/* Allocate MGMT ring descriptor's memory */
234 		pAd->MgmtDescRing.AllocSize =
235 		    MGMT_RING_SIZE * sizeof(struct rt_tx_context);
236 		os_alloc_mem(pAd, (u8 **) (&pAd->MgmtDescRing.AllocVa),
237 			     pAd->MgmtDescRing.AllocSize);
238 		if (pAd->MgmtDescRing.AllocVa == NULL) {
239 			DBGPRINT_ERR("Failed to allocate a big buffer for MgmtDescRing!\n");
240 			Status = NDIS_STATUS_RESOURCES;
241 			goto out1;
242 		}
243 		NdisZeroMemory(pAd->MgmtDescRing.AllocVa,
244 			       pAd->MgmtDescRing.AllocSize);
245 		RingBaseVa = pAd->MgmtDescRing.AllocVa;
246 
247 		/* Initialize MGMT Ring and associated buffer memory */
248 		pMgmtRing = &pAd->MgmtRing;
249 		for (i = 0; i < MGMT_RING_SIZE; i++) {
250 			/* link the pre-allocated Mgmt buffer to MgmtRing.Cell */
251 			pMgmtRing->Cell[i].AllocSize = sizeof(struct rt_tx_context);
252 			pMgmtRing->Cell[i].AllocVa = RingBaseVa;
253 			pMgmtRing->Cell[i].pNdisPacket = NULL;
254 			pMgmtRing->Cell[i].pNextNdisPacket = NULL;
255 
256 			/*Allocate URB for MLMEContext */
257 			pMLMEContext =
258 			    (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
259 			pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
260 			if (pMLMEContext->pUrb == NULL) {
261 				DBGPRINT(RT_DEBUG_ERROR,
262 					 ("<-- ERROR in Alloc TX MLMEContext[%d] urb!\n",
263 					  i));
264 				Status = NDIS_STATUS_RESOURCES;
265 				goto out2;
266 			}
267 			pMLMEContext->pAd = pAd;
268 			pMLMEContext->pIrp = NULL;
269 			pMLMEContext->TransferBuffer = NULL;
270 			pMLMEContext->InUse = FALSE;
271 			pMLMEContext->IRPPending = FALSE;
272 			pMLMEContext->bWaitingBulkOut = FALSE;
273 			pMLMEContext->BulkOutSize = 0;
274 			pMLMEContext->SelfIdx = i;
275 
276 			/* Offset to next ring descriptor address */
277 			RingBaseVa = (u8 *)RingBaseVa + sizeof(struct rt_tx_context);
278 		}
279 		DBGPRINT(RT_DEBUG_TRACE,
280 			 ("MGMT Ring: total %d entry allocated\n", i));
281 
282 		/*pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1); */
283 		pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
284 		pAd->MgmtRing.TxCpuIdx = 0;
285 		pAd->MgmtRing.TxDmaIdx = 0;
286 
287 		/* */
288 		/* BEACON_RING_SIZE */
289 		/* */
290 		for (i = 0; i < BEACON_RING_SIZE; i++)	/* 2 */
291 		{
292 			struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
293 
294 			NdisZeroMemory(pBeaconContext, sizeof(struct rt_tx_context));
295 
296 			/*Allocate URB */
297 			LM_USB_ALLOC(pObj, pBeaconContext, struct rt_tx_buffer *,
298 				     sizeof(struct rt_tx_buffer), Status,
299 				     ("<-- ERROR in Alloc TX BeaconContext[%d] urb!\n",
300 				      i), out2,
301 				     ("<-- ERROR in Alloc TX BeaconContext[%d] struct rt_tx_buffer!\n",
302 				      i), out3);
303 
304 			pBeaconContext->pAd = pAd;
305 			pBeaconContext->pIrp = NULL;
306 			pBeaconContext->InUse = FALSE;
307 			pBeaconContext->IRPPending = FALSE;
308 		}
309 
310 		/* */
311 		/* NullContext */
312 		/* */
313 		NdisZeroMemory(pNullContext, sizeof(struct rt_tx_context));
314 
315 		/*Allocate URB */
316 		LM_USB_ALLOC(pObj, pNullContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
317 			     Status,
318 			     ("<-- ERROR in Alloc TX NullContext urb!\n"),
319 			     out3,
320 			     ("<-- ERROR in Alloc TX NullContext struct rt_tx_buffer!\n"),
321 			     out4);
322 
323 		pNullContext->pAd = pAd;
324 		pNullContext->pIrp = NULL;
325 		pNullContext->InUse = FALSE;
326 		pNullContext->IRPPending = FALSE;
327 
328 		/* */
329 		/* RTSContext */
330 		/* */
331 		NdisZeroMemory(pRTSContext, sizeof(struct rt_tx_context));
332 
333 		/*Allocate URB */
334 		LM_USB_ALLOC(pObj, pRTSContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
335 			     Status,
336 			     ("<-- ERROR in Alloc TX RTSContext urb!\n"),
337 			     out4,
338 			     ("<-- ERROR in Alloc TX RTSContext struct rt_tx_buffer!\n"),
339 			     out5);
340 
341 		pRTSContext->pAd = pAd;
342 		pRTSContext->pIrp = NULL;
343 		pRTSContext->InUse = FALSE;
344 		pRTSContext->IRPPending = FALSE;
345 
346 		/* */
347 		/* PsPollContext */
348 		/* */
349 		/*NdisZeroMemory(pPsPollContext, sizeof(struct rt_tx_context)); */
350 		/*Allocate URB */
351 		LM_USB_ALLOC(pObj, pPsPollContext, struct rt_tx_buffer *,
352 			     sizeof(struct rt_tx_buffer), Status,
353 			     ("<-- ERROR in Alloc TX PsPollContext urb!\n"),
354 			     out5,
355 			     ("<-- ERROR in Alloc TX PsPollContext struct rt_tx_buffer!\n"),
356 			     out6);
357 
358 		pPsPollContext->pAd = pAd;
359 		pPsPollContext->pIrp = NULL;
360 		pPsPollContext->InUse = FALSE;
361 		pPsPollContext->IRPPending = FALSE;
362 		pPsPollContext->bAggregatible = FALSE;
363 		pPsPollContext->LastOne = TRUE;
364 
365 	} while (FALSE);
366 
367 done:
368 	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status));
369 
370 	return Status;
371 
372 	/* --------------------------- ERROR HANDLE --------------------------- */
373 out6:
374 	LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer));
375 
376 out5:
377 	LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
378 
379 out4:
380 	LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
381 
382 out3:
383 	for (i = 0; i < BEACON_RING_SIZE; i++) {
384 		struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
385 		if (pBeaconContext)
386 			LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
387 	}
388 
389 out2:
390 	if (pAd->MgmtDescRing.AllocVa) {
391 		pMgmtRing = &pAd->MgmtRing;
392 		for (i = 0; i < MGMT_RING_SIZE; i++) {
393 			pMLMEContext =
394 			    (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
395 			if (pMLMEContext)
396 				LM_URB_FREE(pObj, pMLMEContext,
397 					    sizeof(struct rt_tx_buffer));
398 		}
399 		os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
400 		pAd->MgmtDescRing.AllocVa = NULL;
401 	}
402 
403 out1:
404 	for (acidx = 0; acidx < 4; acidx++) {
405 		struct rt_ht_tx_context *pTxContext = &(pAd->TxContext[acidx]);
406 		if (pTxContext)
407 			LM_URB_FREE(pObj, pTxContext, sizeof(struct rt_httx_buffer));
408 	}
409 
410 	/* Here we didn't have any pre-allocated memory need to free. */
411 
412 	return Status;
413 }
414 
415 /*
416 ========================================================================
417 Routine Description:
418     Allocate DMA memory blocks for send, receive.
419 
420 Arguments:
421     pAd					Pointer to our adapter
422 
423 Return Value:
424 	NDIS_STATUS_SUCCESS
425 	NDIS_STATUS_FAILURE
426 	NDIS_STATUS_RESOURCES
427 
428 Note:
429 ========================================================================
430 */
RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter * pAd)431 int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd)
432 {
433 /*      struct rt_counter_802_11  pCounter = &pAd->WlanCounters; */
434 	int Status;
435 	int num;
436 
437 	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
438 
439 	do {
440 		/* Init the struct rt_cmdq and CmdQLock */
441 		NdisAllocateSpinLock(&pAd->CmdQLock);
442 		NdisAcquireSpinLock(&pAd->CmdQLock);
443 		RTUSBInitializeCmdQ(&pAd->CmdQ);
444 		NdisReleaseSpinLock(&pAd->CmdQLock);
445 
446 		NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
447 		/*NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock); */
448 		NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
449 		NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
450 		NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
451 		NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
452 		NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
453 		NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
454 		NdisAllocateSpinLock(&pAd->BulkInLock);
455 
456 		for (num = 0; num < NUM_OF_TX_RING; num++) {
457 			NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
458 		}
459 
460 /*              NdisAllocateSpinLock(&pAd->MemLock);    // Not used in RT28XX */
461 
462 /*              NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit() */
463 /*              NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit() */
464 
465 /*              for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++) */
466 /*              { */
467 /*                      NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock); */
468 /*              } */
469 
470 		/* */
471 		/* Init Mac Table */
472 		/* */
473 /*              MacTableInitialize(pAd); */
474 
475 		/* */
476 		/* Init send data structures and related parameters */
477 		/* */
478 		Status = NICInitTransmit(pAd);
479 		if (Status != NDIS_STATUS_SUCCESS)
480 			break;
481 
482 		/* */
483 		/* Init receive data structures and related parameters */
484 		/* */
485 		Status = NICInitRecv(pAd);
486 		if (Status != NDIS_STATUS_SUCCESS)
487 			break;
488 
489 		pAd->PendingIoCount = 1;
490 
491 	} while (FALSE);
492 
493 	NdisZeroMemory(&pAd->FragFrame, sizeof(struct rt_fragment_frame));
494 	pAd->FragFrame.pFragPacket =
495 	    RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
496 
497 	if (pAd->FragFrame.pFragPacket == NULL) {
498 		Status = NDIS_STATUS_RESOURCES;
499 	}
500 
501 	DBGPRINT_S(Status,
502 		   ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
503 	return Status;
504 }
505 
506 /*
507 ========================================================================
508 Routine Description:
509 	Calls USB_InterfaceStop and frees memory allocated for the URBs
510     calls NdisMDeregisterDevice and frees the memory
511     allocated in VNetInitialize for the Adapter Object
512 
513 Arguments:
514 	*pAd				the raxx interface data pointer
515 
516 Return Value:
517 	None
518 
519 Note:
520 ========================================================================
521 */
RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter * pAd)522 void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd)
523 {
524 #define LM_URB_FREE(pObj, Context, BufferSize)				\
525 	if (NULL != Context->pUrb) {							\
526 		RTUSB_UNLINK_URB(Context->pUrb);					\
527 		RTUSB_FREE_URB(Context->pUrb);						\
528 		Context->pUrb = NULL; }								\
529 	if (NULL != Context->TransferBuffer) {					\
530 		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
531 								Context->TransferBuffer,	\
532 								Context->data_dma);			\
533 		Context->TransferBuffer = NULL; }
534 
535 	u32 i, acidx;
536 	struct rt_tx_context *pNullContext = &pAd->NullContext;
537 	struct rt_tx_context *pPsPollContext = &pAd->PsPollContext;
538 	struct rt_tx_context *pRTSContext = &pAd->RTSContext;
539 /*      struct rt_ht_tx_context *pHTTXContext; */
540 	/*PRTMP_REORDERBUF      pReorderBuf; */
541 	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
542 /*      struct rt_rtmp_tx_ring *pTxRing; */
543 
544 	DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
545 	pObj = pObj;
546 
547 	/* Free all resources for the RECEIVE buffer queue. */
548 	for (i = 0; i < (RX_RING_SIZE); i++) {
549 		struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
550 		if (pRxContext)
551 			LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
552 	}
553 
554 	/* Free PsPoll frame resource */
555 	LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer));
556 
557 	/* Free NULL frame resource */
558 	LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
559 
560 	/* Free RTS frame resource */
561 	LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
562 
563 	/* Free beacon frame resource */
564 	for (i = 0; i < BEACON_RING_SIZE; i++) {
565 		struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
566 		if (pBeaconContext)
567 			LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
568 	}
569 
570 	/* Free mgmt frame resource */
571 	for (i = 0; i < MGMT_RING_SIZE; i++) {
572 		struct rt_tx_context *pMLMEContext =
573 		    (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
574 		/*LM_URB_FREE(pObj, pMLMEContext, sizeof(struct rt_tx_buffer)); */
575 		if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) {
576 			RTMPFreeNdisPacket(pAd,
577 					   pAd->MgmtRing.Cell[i].pNdisPacket);
578 			pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
579 			pMLMEContext->TransferBuffer = NULL;
580 		}
581 
582 		if (pMLMEContext) {
583 			if (NULL != pMLMEContext->pUrb) {
584 				RTUSB_UNLINK_URB(pMLMEContext->pUrb);
585 				RTUSB_FREE_URB(pMLMEContext->pUrb);
586 				pMLMEContext->pUrb = NULL;
587 			}
588 		}
589 	}
590 	if (pAd->MgmtDescRing.AllocVa)
591 		os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
592 
593 	/* Free Tx frame resource */
594 	for (acidx = 0; acidx < 4; acidx++) {
595 		struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
596 		if (pHTTXContext)
597 			LM_URB_FREE(pObj, pHTTXContext, sizeof(struct rt_httx_buffer));
598 	}
599 
600 	if (pAd->FragFrame.pFragPacket)
601 		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket,
602 				    NDIS_STATUS_SUCCESS);
603 
604 	for (i = 0; i < 6; i++) {
605 		NdisFreeSpinLock(&pAd->BulkOutLock[i]);
606 	}
607 
608 	NdisFreeSpinLock(&pAd->BulkInLock);
609 	NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
610 
611 	NdisFreeSpinLock(&pAd->CmdQLock);
612 	/* Clear all pending bulk-out request flags. */
613 	RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
614 
615 /*      NdisFreeSpinLock(&pAd->MacTabLock); */
616 
617 /*      for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++) */
618 /*      { */
619 /*              NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock); */
620 /*      } */
621 
622 	DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n"));
623 }
624 
625 /*
626 ========================================================================
627 Routine Description:
628     Write WLAN MAC address to USB 2870.
629 
630 Arguments:
631     pAd					Pointer to our adapter
632 
633 Return Value:
634 	NDIS_STATUS_SUCCESS
635 
636 Note:
637 ========================================================================
638 */
RTUSBWriteHWMACAddress(struct rt_rtmp_adapter * pAd)639 int RTUSBWriteHWMACAddress(struct rt_rtmp_adapter *pAd)
640 {
641 	MAC_DW0_STRUC StaMacReg0;
642 	MAC_DW1_STRUC StaMacReg1;
643 	int Status = NDIS_STATUS_SUCCESS;
644 	LARGE_INTEGER NOW;
645 
646 	/* initialize the random number generator */
647 	RTMP_GetCurrentSystemTime(&NOW);
648 
649 	if (pAd->bLocalAdminMAC != TRUE) {
650 		pAd->CurrentAddress[0] = pAd->PermanentAddress[0];
651 		pAd->CurrentAddress[1] = pAd->PermanentAddress[1];
652 		pAd->CurrentAddress[2] = pAd->PermanentAddress[2];
653 		pAd->CurrentAddress[3] = pAd->PermanentAddress[3];
654 		pAd->CurrentAddress[4] = pAd->PermanentAddress[4];
655 		pAd->CurrentAddress[5] = pAd->PermanentAddress[5];
656 	}
657 	/* Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC */
658 	StaMacReg0.field.Byte0 = pAd->CurrentAddress[0];
659 	StaMacReg0.field.Byte1 = pAd->CurrentAddress[1];
660 	StaMacReg0.field.Byte2 = pAd->CurrentAddress[2];
661 	StaMacReg0.field.Byte3 = pAd->CurrentAddress[3];
662 	StaMacReg1.field.Byte4 = pAd->CurrentAddress[4];
663 	StaMacReg1.field.Byte5 = pAd->CurrentAddress[5];
664 	StaMacReg1.field.U2MeMask = 0xff;
665 	DBGPRINT_RAW(RT_DEBUG_TRACE,
666 		("Local MAC = %pM\n", pAd->CurrentAddress));
667 
668 	RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word);
669 	RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word);
670 	return Status;
671 }
672 
673 /*
674 ========================================================================
675 Routine Description:
676     Disable DMA.
677 
678 Arguments:
679 	*pAd				the raxx interface data pointer
680 
681 Return Value:
682 	None
683 
684 Note:
685 ========================================================================
686 */
RT28XXDMADisable(struct rt_rtmp_adapter * pAd)687 void RT28XXDMADisable(struct rt_rtmp_adapter *pAd)
688 {
689 	/* no use */
690 }
691 
692 /*
693 ========================================================================
694 Routine Description:
695     Enable DMA.
696 
697 Arguments:
698 	*pAd				the raxx interface data pointer
699 
700 Return Value:
701 	None
702 
703 Note:
704 ========================================================================
705 */
RT28XXDMAEnable(struct rt_rtmp_adapter * pAd)706 void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd)
707 {
708 	WPDMA_GLO_CFG_STRUC GloCfg;
709 	USB_DMA_CFG_STRUC UsbCfg;
710 	int i = 0;
711 
712 	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
713 	do {
714 		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
715 		if ((GloCfg.field.TxDMABusy == 0)
716 		    && (GloCfg.field.RxDMABusy == 0))
717 			break;
718 
719 		DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
720 		RTMPusecDelay(1000);
721 		i++;
722 	} while (i < 200);
723 
724 	RTMPusecDelay(50);
725 	GloCfg.field.EnTXWriteBackDDONE = 1;
726 	GloCfg.field.EnableRxDMA = 1;
727 	GloCfg.field.EnableTxDMA = 1;
728 	DBGPRINT(RT_DEBUG_TRACE,
729 		 ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
730 	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
731 
732 	UsbCfg.word = 0;
733 	UsbCfg.field.phyclear = 0;
734 	/* usb version is 1.1,do not use bulk in aggregation */
735 	if (pAd->BulkInMaxPacketSize == 512)
736 		UsbCfg.field.RxBulkAggEn = 1;
737 	/* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
738 	UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE / 1024) - 3;
739 	UsbCfg.field.RxBulkAggTOut = 0x80;	/* 2006-10-18 */
740 	UsbCfg.field.RxBulkEn = 1;
741 	UsbCfg.field.TxBulkEn = 1;
742 
743 	RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
744 
745 }
746 
747 /********************************************************************
748   *
749   *	2870 Beacon Update Related functions.
750   *
751   ********************************************************************/
752 
753 /*
754 ========================================================================
755 Routine Description:
756     Write Beacon buffer to Asic.
757 
758 Arguments:
759 	*pAd				the raxx interface data pointer
760 
761 Return Value:
762 	None
763 
764 Note:
765 ========================================================================
766 */
RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter * pAd,int apidx,unsigned long FrameLen,unsigned long UpdatePos)767 void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd,
768 			       int apidx,
769 			       unsigned long FrameLen, unsigned long UpdatePos)
770 {
771 	u8 *pBeaconFrame = NULL;
772 	u8 *ptr;
773 	u32 i, padding;
774 	struct rt_beacon_sync *pBeaconSync = pAd->CommonCfg.pBeaconSync;
775 	u32 longValue;
776 /*      u16                  shortValue; */
777 	BOOLEAN bBcnReq = FALSE;
778 	u8 bcn_idx = 0;
779 
780 	if (pBeaconFrame == NULL) {
781 		DBGPRINT(RT_DEBUG_ERROR, ("pBeaconFrame is NULL!\n"));
782 		return;
783 	}
784 
785 	if (pBeaconSync == NULL) {
786 		DBGPRINT(RT_DEBUG_ERROR, ("pBeaconSync is NULL!\n"));
787 		return;
788 	}
789 	/*if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) || */
790 	/*      ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) */
791 	/*      ) */
792 	if (bBcnReq == FALSE) {
793 		/* when the ra interface is down, do not send its beacon frame */
794 		/* clear all zero */
795 		for (i = 0; i < TXWI_SIZE; i += 4) {
796 			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
797 					0x00);
798 		}
799 		pBeaconSync->BeaconBitMap &=
800 		    (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
801 		NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
802 	} else {
803 		ptr = (u8 *)& pAd->BeaconTxWI;
804 		if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) {	/* If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames. */
805 			pBeaconSync->BeaconBitMap &=
806 			    (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
807 			NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx],
808 				       &pAd->BeaconTxWI, TXWI_SIZE);
809 		}
810 
811 		if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) !=
812 		    (1 << bcn_idx)) {
813 			for (i = 0; i < TXWI_SIZE; i += 4)	/* 16-byte TXWI field */
814 			{
815 				longValue =
816 				    *ptr + (*(ptr + 1) << 8) +
817 				    (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
818 				RTMP_IO_WRITE32(pAd,
819 						pAd->BeaconOffset[bcn_idx] + i,
820 						longValue);
821 				ptr += 4;
822 			}
823 		}
824 
825 		ptr = pBeaconSync->BeaconBuf[bcn_idx];
826 		padding = (FrameLen & 0x01);
827 		NdisZeroMemory((u8 *)(pBeaconFrame + FrameLen), padding);
828 		FrameLen += padding;
829 		for (i = 0; i < FrameLen /*HW_BEACON_OFFSET */ ; i += 2) {
830 			if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE) {
831 				NdisMoveMemory(ptr, pBeaconFrame, 2);
832 				/*shortValue = *ptr + (*(ptr+1)<<8); */
833 				/*RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue); */
834 				RTUSBMultiWrite(pAd,
835 						pAd->BeaconOffset[bcn_idx] +
836 						TXWI_SIZE + i, ptr, 2);
837 			}
838 			ptr += 2;
839 			pBeaconFrame += 2;
840 		}
841 
842 		pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
843 
844 		/* For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame. */
845 	}
846 
847 }
848 
RTUSBBssBeaconStop(struct rt_rtmp_adapter * pAd)849 void RTUSBBssBeaconStop(struct rt_rtmp_adapter *pAd)
850 {
851 	struct rt_beacon_sync *pBeaconSync;
852 	int i, offset;
853 	BOOLEAN Cancelled = TRUE;
854 
855 	pBeaconSync = pAd->CommonCfg.pBeaconSync;
856 	if (pBeaconSync && pBeaconSync->EnableBeacon) {
857 		int NumOfBcn;
858 
859 		{
860 			NumOfBcn = MAX_MESH_NUM;
861 		}
862 
863 		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
864 
865 		for (i = 0; i < NumOfBcn; i++) {
866 			NdisZeroMemory(pBeaconSync->BeaconBuf[i],
867 				       HW_BEACON_OFFSET);
868 			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
869 
870 			for (offset = 0; offset < HW_BEACON_OFFSET; offset += 4)
871 				RTMP_IO_WRITE32(pAd,
872 						pAd->BeaconOffset[i] + offset,
873 						0x00);
874 
875 			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
876 			pBeaconSync->TimIELocationInBeacon[i] = 0;
877 		}
878 		pBeaconSync->BeaconBitMap = 0;
879 		pBeaconSync->DtimBitOn = 0;
880 	}
881 }
882 
RTUSBBssBeaconStart(struct rt_rtmp_adapter * pAd)883 void RTUSBBssBeaconStart(struct rt_rtmp_adapter *pAd)
884 {
885 	int apidx;
886 	struct rt_beacon_sync *pBeaconSync;
887 /*      LARGE_INTEGER   tsfTime, deltaTime; */
888 
889 	pBeaconSync = pAd->CommonCfg.pBeaconSync;
890 	if (pBeaconSync && pBeaconSync->EnableBeacon) {
891 		int NumOfBcn;
892 
893 		{
894 			NumOfBcn = MAX_MESH_NUM;
895 		}
896 
897 		for (apidx = 0; apidx < NumOfBcn; apidx++) {
898 			u8 CapabilityInfoLocationInBeacon = 0;
899 			u8 TimIELocationInBeacon = 0;
900 
901 			NdisZeroMemory(pBeaconSync->BeaconBuf[apidx],
902 				       HW_BEACON_OFFSET);
903 			pBeaconSync->CapabilityInfoLocationInBeacon[apidx] =
904 			    CapabilityInfoLocationInBeacon;
905 			pBeaconSync->TimIELocationInBeacon[apidx] =
906 			    TimIELocationInBeacon;
907 			NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx],
908 				       TXWI_SIZE);
909 		}
910 		pBeaconSync->BeaconBitMap = 0;
911 		pBeaconSync->DtimBitOn = 0;
912 		pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
913 
914 		pAd->CommonCfg.BeaconAdjust = 0;
915 		pAd->CommonCfg.BeaconFactor =
916 		    0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
917 		pAd->CommonCfg.BeaconRemain =
918 		    (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
919 		DBGPRINT(RT_DEBUG_TRACE,
920 			 ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n",
921 			  pAd->CommonCfg.BeaconFactor,
922 			  pAd->CommonCfg.BeaconRemain));
923 		RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer,
924 			     10 /*pAd->CommonCfg.BeaconPeriod */ );
925 
926 	}
927 }
928 
RTUSBBssBeaconInit(struct rt_rtmp_adapter * pAd)929 void RTUSBBssBeaconInit(struct rt_rtmp_adapter *pAd)
930 {
931 	struct rt_beacon_sync *pBeaconSync;
932 	int i;
933 
934 	os_alloc_mem(pAd, (u8 **) (&pAd->CommonCfg.pBeaconSync),
935 		     sizeof(struct rt_beacon_sync));
936 	/*NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(struct rt_beacon_sync), MEM_ALLOC_FLAG); */
937 	if (pAd->CommonCfg.pBeaconSync) {
938 		pBeaconSync = pAd->CommonCfg.pBeaconSync;
939 		NdisZeroMemory(pBeaconSync, sizeof(struct rt_beacon_sync));
940 		for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
941 			NdisZeroMemory(pBeaconSync->BeaconBuf[i],
942 				       HW_BEACON_OFFSET);
943 			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
944 			pBeaconSync->TimIELocationInBeacon[i] = 0;
945 			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
946 		}
947 		pBeaconSync->BeaconBitMap = 0;
948 
949 		/*RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE); */
950 		pBeaconSync->EnableBeacon = TRUE;
951 	}
952 }
953 
RTUSBBssBeaconExit(struct rt_rtmp_adapter * pAd)954 void RTUSBBssBeaconExit(struct rt_rtmp_adapter *pAd)
955 {
956 	struct rt_beacon_sync *pBeaconSync;
957 	BOOLEAN Cancelled = TRUE;
958 	int i;
959 
960 	if (pAd->CommonCfg.pBeaconSync) {
961 		pBeaconSync = pAd->CommonCfg.pBeaconSync;
962 		pBeaconSync->EnableBeacon = FALSE;
963 		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
964 		pBeaconSync->BeaconBitMap = 0;
965 
966 		for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
967 			NdisZeroMemory(pBeaconSync->BeaconBuf[i],
968 				       HW_BEACON_OFFSET);
969 			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
970 			pBeaconSync->TimIELocationInBeacon[i] = 0;
971 			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
972 		}
973 
974 		os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
975 		pAd->CommonCfg.pBeaconSync = NULL;
976 	}
977 }
978 
979 /*
980     ========================================================================
981     Routine Description:
982         For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism
983         to update the beacon context in each Beacon interval. Here we use a periodical timer
984         to simulate the TBTT interrupt to handle the beacon context update.
985 
986     Arguments:
987         SystemSpecific1         - Not used.
988         FunctionContext         - Pointer to our Adapter context.
989         SystemSpecific2         - Not used.
990         SystemSpecific3         - Not used.
991 
992     Return Value:
993         None
994 
995     ========================================================================
996 */
BeaconUpdateExec(void * SystemSpecific1,void * FunctionContext,void * SystemSpecific2,void * SystemSpecific3)997 void BeaconUpdateExec(void *SystemSpecific1,
998 		      void *FunctionContext,
999 		      void *SystemSpecific2, void *SystemSpecific3)
1000 {
1001 	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
1002 	LARGE_INTEGER tsfTime_a;	/*, tsfTime_b, deltaTime_exp, deltaTime_ab; */
1003 	u32 delta, delta2MS, period2US, remain, remain_low, remain_high;
1004 /*      BOOLEAN                 positive; */
1005 
1006 	if (pAd->CommonCfg.IsUpdateBeacon == TRUE) {
1007 		ReSyncBeaconTime(pAd);
1008 
1009 	}
1010 
1011 	RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1012 	RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1013 
1014 	/*positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp); */
1015 	period2US = (pAd->CommonCfg.BeaconPeriod << 10);
1016 	remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1017 	remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1018 	remain =
1019 	    (remain_high + remain_low) % (pAd->CommonCfg.BeaconPeriod << 10);
1020 	delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1021 
1022 	delta2MS = (delta >> 10);
1023 	if (delta2MS > 150) {
1024 		pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100;
1025 		pAd->CommonCfg.IsUpdateBeacon = FALSE;
1026 	} else {
1027 		pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10;
1028 		pAd->CommonCfg.IsUpdateBeacon = TRUE;
1029 	}
1030 
1031 }
1032 
1033 /********************************************************************
1034   *
1035   *	2870 Radio on/off Related functions.
1036   *
1037   ********************************************************************/
RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter * pAd)1038 void RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter *pAd)
1039 {
1040 	struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
1041 
1042 	DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOn()\n"));
1043 
1044 	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1045 		return;
1046 
1047 	{
1048 		AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
1049 		RTMPusecDelay(10000);
1050 	}
1051 	/*NICResetFromError(pAd); */
1052 
1053 	/* Enable Tx/Rx */
1054 	RTMPEnableRxTx(pAd);
1055 
1056 	if (pChipOps->AsicReverseRfFromSleepMode)
1057 		pChipOps->AsicReverseRfFromSleepMode(pAd);
1058 
1059 	/* Clear Radio off flag */
1060 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1061 
1062 	RTUSBBulkReceive(pAd);
1063 
1064 	/* Set LED */
1065 	RTMPSetLED(pAd, LED_RADIO_ON);
1066 }
1067 
RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter * pAd)1068 void RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter *pAd)
1069 {
1070 	WPDMA_GLO_CFG_STRUC GloCfg;
1071 	u32 Value, i;
1072 
1073 	DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOFF()\n"));
1074 
1075 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1076 		return;
1077 
1078 	/* Clear PMKID cache. */
1079 	pAd->StaCfg.SavedPMKNum = 0;
1080 	RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(struct rt_bssid_info)));
1081 
1082 	/* Link down first if any association exists */
1083 	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
1084 		if (INFRA_ON(pAd) || ADHOC_ON(pAd)) {
1085 			struct rt_mlme_disassoc_req DisReq;
1086 			struct rt_mlme_queue_elem *pMsgElem =
1087 			    kmalloc(sizeof(struct rt_mlme_queue_elem),
1088 							MEM_ALLOC_FLAG);
1089 
1090 			if (pMsgElem) {
1091 				COPY_MAC_ADDR(&DisReq.Addr,
1092 					      pAd->CommonCfg.Bssid);
1093 				DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
1094 
1095 				pMsgElem->Machine = ASSOC_STATE_MACHINE;
1096 				pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
1097 				pMsgElem->MsgLen =
1098 				    sizeof(struct rt_mlme_disassoc_req);
1099 				NdisMoveMemory(pMsgElem->Msg, &DisReq,
1100 					       sizeof
1101 					       (struct rt_mlme_disassoc_req));
1102 
1103 				MlmeDisassocReqAction(pAd, pMsgElem);
1104 				kfree(pMsgElem);
1105 
1106 				RTMPusecDelay(1000);
1107 			}
1108 		}
1109 	}
1110 	/* Set Radio off flag */
1111 	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1112 
1113 	{
1114 		/* Link down first if any association exists */
1115 		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1116 			LinkDown(pAd, FALSE);
1117 		RTMPusecDelay(10000);
1118 
1119 		/*========================================== */
1120 		/* Clean up old bss table */
1121 		BssTableInit(&pAd->ScanTab);
1122 	}
1123 
1124 	/* Set LED */
1125 	RTMPSetLED(pAd, LED_RADIO_OFF);
1126 
1127 	if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
1128 		/* Must using 40MHz. */
1129 		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
1130 	} else {
1131 		/* Must using 20MHz. */
1132 		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
1133 	}
1134 
1135 	/* Disable Tx/Rx DMA */
1136 	RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word);	/* disable DMA */
1137 	GloCfg.field.EnableTxDMA = 0;
1138 	GloCfg.field.EnableRxDMA = 0;
1139 	RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word);	/* abort all TX rings */
1140 
1141 	/* Waiting for DMA idle */
1142 	i = 0;
1143 	do {
1144 		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1145 		if ((GloCfg.field.TxDMABusy == 0)
1146 		    && (GloCfg.field.RxDMABusy == 0))
1147 			break;
1148 
1149 		RTMPusecDelay(1000);
1150 	} while (i++ < 100);
1151 
1152 	/* Disable MAC Tx/Rx */
1153 	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1154 	Value &= (0xfffffff3);
1155 	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1156 
1157 	{
1158 		AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1159 	}
1160 }
1161 
1162 #endif /* RTMP_MAC_USB // */
1163