Staging: rt3070: remove dead NINTENDO_AP code
[linux-2.6] / drivers / staging / rt3070 / 2870_main_dev.c
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     rtmp_main.c
29
30     Abstract:
31     main initialization routines
32
33     Revision History:
34     Who         When            What
35     --------    ----------      ----------------------------------------------
36     Name        Date            Modification logs
37     Jan Lee             01-10-2005          modified
38         Sample          Jun/01/07               Merge RT2870 and RT2860 drivers.
39 */
40
41 #include "rt_config.h"
42
43
44 // Following information will be show when you run 'modinfo'
45 // *** If you have a solution for the bug in current version of driver, please mail to me.
46 // Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
47 MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
48 MODULE_DESCRIPTION("RT2870 Wireless Lan Linux Driver");
49 #ifdef CONFIG_STA_SUPPORT
50 MODULE_LICENSE("GPL");
51 #ifdef MODULE_VERSION
52 MODULE_VERSION(STA_DRIVER_VERSION);
53 #endif
54 #endif // CONFIG_STA_SUPPORT //
55
56 #ifdef MULTIPLE_CARD_SUPPORT
57 // record whether the card in the card list is used in the card file
58 extern UINT8  MC_CardUsed[];
59 #endif // MULTIPLE_CARD_SUPPORT //
60
61 /* Kernel thread and vars, which handles packets that are completed. Only
62  * packets that have a "complete" function are sent here. This way, the
63  * completion is run out of kernel context, and doesn't block the rest of
64  * the stack. */
65 //static int mlme_kill = 0;             // Mlme kernel thread
66 //static int RTUSBCmd_kill = 0; // Command kernel thread
67 //static int TimerFunc_kill = 0;        // TimerQ kernel thread
68
69 //static wait_queue_head_t      timerWaitQ;
70 //static wait_queue_t           waitQ;
71
72 extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
73                                                                         IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
74
75
76 /* module table */
77 struct usb_device_id    rtusb_usb_id[] = RT2870_USB_DEVICES;
78 INT const               rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
79 MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
80
81 #ifndef PF_NOFREEZE
82 #define PF_NOFREEZE  0
83 #endif
84
85
86 #ifdef CONFIG_PM
87 static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
88 static int rt2870_resume(struct usb_interface *intf);
89 #endif // CONFIG_PM //
90
91 /**************************************************************************/
92 /**************************************************************************/
93 //tested for kernel 2.6series
94 /**************************************************************************/
95 /**************************************************************************/
96 static int rtusb_probe (struct usb_interface *intf,
97                                                 const struct usb_device_id *id);
98 static void rtusb_disconnect(struct usb_interface *intf);
99
100 struct usb_driver rtusb_driver = {
101         .name="rt2870",
102         .probe=rtusb_probe,
103         .disconnect=rtusb_disconnect,
104         .id_table=rtusb_usb_id,
105
106 #ifdef CONFIG_PM
107         suspend:        rt2870_suspend,
108         resume:         rt2870_resume,
109 #endif
110         };
111
112 #ifdef CONFIG_PM
113
114 VOID RT2860RejectPendingPackets(
115         IN      PRTMP_ADAPTER   pAd)
116 {
117         // clear PS packets
118         // clear TxSw packets
119 }
120
121 static int rt2870_suspend(
122         struct usb_interface *intf,
123         pm_message_t state)
124 {
125         struct net_device *net_dev;
126         PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
127
128
129         DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
130         net_dev = pAd->net_dev;
131                         netif_device_detach(net_dev);
132
133         pAd->PM_FlgSuspend = 1;
134         if (netif_running(net_dev)) {
135                 RTUSBCancelPendingBulkInIRP(pAd);
136                 RTUSBCancelPendingBulkOutIRP(pAd);
137         }
138         DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
139         return 0;
140 }
141
142 static int rt2870_resume(
143         struct usb_interface *intf)
144 {
145         struct net_device *net_dev;
146         PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
147
148
149         DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
150
151         pAd->PM_FlgSuspend = 0;
152         net_dev = pAd->net_dev;
153                         netif_device_attach(net_dev);
154                         netif_start_queue(net_dev);
155                         netif_carrier_on(net_dev);
156                         netif_wake_queue(net_dev);
157
158         DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
159         return 0;
160 }
161 #endif // CONFIG_PM //
162
163
164 // Init driver module
165 INT __init rtusb_init(void)
166 {
167         printk("rtusb init --->\n");
168         return usb_register(&rtusb_driver);
169 }
170
171 // Deinit driver module
172 VOID __exit rtusb_exit(void)
173 {
174         usb_deregister(&rtusb_driver);
175         printk("<--- rtusb exit\n");
176 }
177
178 module_init(rtusb_init);
179 module_exit(rtusb_exit);
180
181
182
183
184 /*--------------------------------------------------------------------- */
185 /* function declarations                                                                                                */
186 /*--------------------------------------------------------------------- */
187
188 /*
189 ========================================================================
190 Routine Description:
191     MLME kernel thread.
192
193 Arguments:
194         *Context                        the pAd, driver control block pointer
195
196 Return Value:
197     0                                   close the thread
198
199 Note:
200 ========================================================================
201 */
202 INT MlmeThread(
203         IN void *Context)
204 {
205         PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER)Context;
206         POS_COOKIE      pObj;
207         int status;
208
209         pObj = (POS_COOKIE)pAd->OS_Cookie;
210
211         rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
212
213         while (pAd->mlme_kill == 0)
214         {
215                 /* lock the device pointers */
216                 //down(&(pAd->mlme_semaphore));
217                 status = down_interruptible(&(pAd->mlme_semaphore));
218
219                 /* lock the device pointers , need to check if required*/
220                 //down(&(pAd->usbdev_semaphore));
221
222                 if (!pAd->PM_FlgSuspend)
223                 MlmeHandler(pAd);
224
225                 /* unlock the device pointers */
226                 //up(&(pAd->usbdev_semaphore));
227                 if (status != 0)
228                 {
229                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
230                         break;
231                 }
232         }
233
234         /* notify the exit routine that we're actually exiting now
235          *
236          * complete()/wait_for_completion() is similar to up()/down(),
237          * except that complete() is safe in the case where the structure
238          * is getting deleted in a parallel mode of execution (i.e. just
239          * after the down() -- that's necessary for the thread-shutdown
240          * case.
241          *
242          * complete_and_exit() goes even further than this -- it is safe in
243          * the case that the thread of the caller is going away (not just
244          * the structure) -- this is necessary for the module-remove case.
245          * This is important in preemption kernels, which transfer the flow
246          * of execution immediately upon a complete().
247          */
248         DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
249
250         pObj->MLMEThr_pid = NULL;
251
252         complete_and_exit (&pAd->mlmeComplete, 0);
253         return 0;
254
255 }
256
257
258 /*
259 ========================================================================
260 Routine Description:
261     USB command kernel thread.
262
263 Arguments:
264         *Context                        the pAd, driver control block pointer
265
266 Return Value:
267     0                                   close the thread
268
269 Note:
270 ========================================================================
271 */
272 INT RTUSBCmdThread(
273         IN void * Context)
274 {
275         PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER)Context;
276         POS_COOKIE              pObj;
277         int status;
278
279         pObj = (POS_COOKIE)pAd->OS_Cookie;
280
281         rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
282
283         NdisAcquireSpinLock(&pAd->CmdQLock);
284         pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
285         NdisReleaseSpinLock(&pAd->CmdQLock);
286
287         while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
288         {
289                 /* lock the device pointers */
290                 //down(&(pAd->RTUSBCmd_semaphore));
291                 status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
292
293                 if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
294                         break;
295
296                 if (status != 0)
297                 {
298                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
299                         break;
300                 }
301                 /* lock the device pointers , need to check if required*/
302                 //down(&(pAd->usbdev_semaphore));
303
304                 if (!pAd->PM_FlgSuspend)
305                 CMDHandler(pAd);
306
307                 /* unlock the device pointers */
308                 //up(&(pAd->usbdev_semaphore));
309         }
310
311         if (!pAd->PM_FlgSuspend)
312         {       // Clear the CmdQElements.
313                 CmdQElmt        *pCmdQElmt = NULL;
314
315                 NdisAcquireSpinLock(&pAd->CmdQLock);
316                 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
317                 while(pAd->CmdQ.size)
318                 {
319                         RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
320                         if (pCmdQElmt)
321                         {
322                                 if (pCmdQElmt->CmdFromNdis == TRUE)
323                                 {
324                                         if (pCmdQElmt->buffer != NULL)
325                                                 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
326
327                                         NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
328                                 }
329                                 else
330                                 {
331                                         if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
332                                                 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
333                             {
334                                                 NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
335                                         }
336                                 }
337                         }
338                 }
339
340                 NdisReleaseSpinLock(&pAd->CmdQLock);
341         }
342         /* notify the exit routine that we're actually exiting now
343          *
344          * complete()/wait_for_completion() is similar to up()/down(),
345          * except that complete() is safe in the case where the structure
346          * is getting deleted in a parallel mode of execution (i.e. just
347          * after the down() -- that's necessary for the thread-shutdown
348          * case.
349          *
350          * complete_and_exit() goes even further than this -- it is safe in
351          * the case that the thread of the caller is going away (not just
352          * the structure) -- this is necessary for the module-remove case.
353          * This is important in preemption kernels, which transfer the flow
354          * of execution immediately upon a complete().
355          */
356         DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
357
358         pObj->RTUSBCmdThr_pid = NULL;
359
360         complete_and_exit (&pAd->CmdQComplete, 0);
361         return 0;
362
363 }
364
365
366 static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
367 {
368         int status;
369         RALINK_TIMER_STRUCT     *pTimer;
370         RT2870_TIMER_ENTRY      *pEntry;
371         unsigned long   irqFlag;
372
373         while(!pAd->TimerFunc_kill)
374         {
375 //              printk("waiting for event!\n");
376                 pTimer = NULL;
377
378                 status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
379
380                 if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
381                         break;
382
383                 // event happened.
384                 while(pAd->TimerQ.pQHead)
385                 {
386                         RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
387                         pEntry = pAd->TimerQ.pQHead;
388                         if (pEntry)
389                         {
390                                 pTimer = pEntry->pRaTimer;
391
392                                 // update pQHead
393                                 pAd->TimerQ.pQHead = pEntry->pNext;
394                                 if (pEntry == pAd->TimerQ.pQTail)
395                                         pAd->TimerQ.pQTail = NULL;
396
397                                 // return this queue entry to timerQFreeList.
398                                 pEntry->pNext = pAd->TimerQ.pQPollFreeList;
399                                 pAd->TimerQ.pQPollFreeList = pEntry;
400                         }
401                         RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
402
403                         if (pTimer)
404                         {
405                                 if (pTimer->handle != NULL)
406                                 if (!pAd->PM_FlgSuspend)
407                                         pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
408                                 if ((pTimer->Repeat) && (pTimer->State == FALSE))
409                                         RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
410                         }
411                 }
412
413                 if (status != 0)
414                 {
415                         pAd->TimerQ.status = RT2870_THREAD_STOPED;
416                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
417                         break;
418                 }
419         }
420 }
421
422
423 INT TimerQThread(
424         IN OUT PVOID Context)
425 {
426         PRTMP_ADAPTER   pAd;
427         POS_COOKIE      pObj;
428
429         pAd = (PRTMP_ADAPTER)Context;
430         pObj = (POS_COOKIE) pAd->OS_Cookie;
431
432         rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
433
434         RT2870_TimerQ_Handle(pAd);
435
436         /* notify the exit routine that we're actually exiting now
437          *
438          * complete()/wait_for_completion() is similar to up()/down(),
439          * except that complete() is safe in the case where the structure
440          * is getting deleted in a parallel mode of execution (i.e. just
441          * after the down() -- that's necessary for the thread-shutdown
442          * case.
443          *
444          * complete_and_exit() goes even further than this -- it is safe in
445          * the case that the thread of the caller is going away (not just
446          * the structure) -- this is necessary for the module-remove case.
447          * This is important in preemption kernels, which transfer the flow
448          * of execution immediately upon a complete().
449          */
450         DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
451
452         pObj->TimerQThr_pid = NULL;
453
454         complete_and_exit(&pAd->TimerQComplete, 0);
455         return 0;
456
457 }
458
459
460 RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
461         IN RTMP_ADAPTER *pAd,
462         IN RALINK_TIMER_STRUCT *pTimer)
463 {
464         RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
465         unsigned long irqFlags;
466
467
468         RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
469         if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
470         {
471                 if(pAd->TimerQ.pQPollFreeList)
472                 {
473                         pQNode = pAd->TimerQ.pQPollFreeList;
474                         pAd->TimerQ.pQPollFreeList = pQNode->pNext;
475
476                         pQNode->pRaTimer = pTimer;
477                         pQNode->pNext = NULL;
478
479                         pQTail = pAd->TimerQ.pQTail;
480                         if (pAd->TimerQ.pQTail != NULL)
481                                 pQTail->pNext = pQNode;
482                         pAd->TimerQ.pQTail = pQNode;
483                         if (pAd->TimerQ.pQHead == NULL)
484                                 pAd->TimerQ.pQHead = pQNode;
485                 }
486                 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
487
488                 if (pQNode)
489                         up(&pAd->RTUSBTimer_semaphore);
490                         //wake_up(&timerWaitQ);
491         }
492         else
493         {
494                 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
495         }
496         return pQNode;
497 }
498
499
500 BOOLEAN RT2870_TimerQ_Remove(
501         IN RTMP_ADAPTER *pAd,
502         IN RALINK_TIMER_STRUCT *pTimer)
503 {
504         RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
505         unsigned long irqFlags;
506
507         RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
508         if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
509         {
510                 pNode = pAd->TimerQ.pQHead;
511                 while (pNode)
512                 {
513                         if (pNode->pRaTimer == pTimer)
514                                 break;
515                         pPrev = pNode;
516                         pNode = pNode->pNext;
517                 }
518
519                 // Now move it to freeList queue.
520                 if (pNode)
521                 {
522                         if (pNode == pAd->TimerQ.pQHead)
523                                 pAd->TimerQ.pQHead = pNode->pNext;
524                         if (pNode == pAd->TimerQ.pQTail)
525                                 pAd->TimerQ.pQTail = pPrev;
526                         if (pPrev != NULL)
527                                 pPrev->pNext = pNode->pNext;
528
529                         // return this queue entry to timerQFreeList.
530                         pNode->pNext = pAd->TimerQ.pQPollFreeList;
531                         pAd->TimerQ.pQPollFreeList = pNode;
532                 }
533         }
534         RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
535
536         return TRUE;
537 }
538
539
540 void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
541 {
542         RT2870_TIMER_ENTRY *pTimerQ;
543         unsigned long irqFlags;
544
545         RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
546         while (pAd->TimerQ.pQHead)
547         {
548                 pTimerQ = pAd->TimerQ.pQHead;
549                 pAd->TimerQ.pQHead = pTimerQ->pNext;
550                 // remove the timeQ
551         }
552         pAd->TimerQ.pQPollFreeList = NULL;
553         os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
554         pAd->TimerQ.pQTail = NULL;
555         pAd->TimerQ.pQHead = NULL;
556         pAd->TimerQ.status = RT2870_THREAD_STOPED;
557         RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
558
559 }
560
561
562 void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
563 {
564         int     i;
565         RT2870_TIMER_ENTRY *pQNode, *pEntry;
566         unsigned long irqFlags;
567
568         NdisAllocateSpinLock(&pAd->TimerQLock);
569
570         RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
571         NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
572         //InterlockedExchange(&pAd->TimerQ.count, 0);
573
574         /* Initialise the wait q head */
575         //init_waitqueue_head(&timerWaitQ);
576
577         os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
578         if (pAd->TimerQ.pTimerQPoll)
579         {
580                 pEntry = NULL;
581                 pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
582                 for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
583                 {
584                         pQNode->pNext = pEntry;
585                         pEntry = pQNode;
586                         pQNode++;
587                 }
588                 pAd->TimerQ.pQPollFreeList = pEntry;
589                 pAd->TimerQ.pQHead = NULL;
590                 pAd->TimerQ.pQTail = NULL;
591                 pAd->TimerQ.status = RT2870_THREAD_INITED;
592         }
593         RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
594 }
595
596
597 VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
598 {
599         PHT_TX_CONTEXT          pHTTXContext;
600         int                                     idx;
601         ULONG                           irqFlags;
602         PURB                            pUrb;
603         BOOLEAN                         needDumpSeq = FALSE;
604         UINT32                  MACValue;
605
606
607         idx = 0;
608         RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
609         if ((MACValue & 0xff) !=0 )
610         {
611                 DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
612                 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
613                 while((MACValue &0xff) != 0 && (idx++ < 10))
614                 {
615                         RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
616                         NdisMSleep(1);
617                 }
618                 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
619         }
620
621 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
622 #ifdef CONFIG_STA_SUPPORT
623         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
624         {
625                 idx = 0;
626                 if ((MACValue & 0xff00) !=0 )
627                 {
628                         DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
629                         RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
630                         while((MACValue &0xff00) != 0 && (idx++ < 10))
631                         {
632                                 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
633                                 NdisMSleep(1);
634                         }
635                         RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
636                 }
637         }
638 #endif // CONFIG_STA_SUPPORT //
639
640         if (pAd->watchDogRxOverFlowCnt >= 2)
641         {
642                 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
643                 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
644                                                                         fRTMP_ADAPTER_BULKIN_RESET |
645                                                                         fRTMP_ADAPTER_HALT_IN_PROGRESS |
646                                                                         fRTMP_ADAPTER_NIC_NOT_EXIST))))
647                 {
648                         DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
649                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
650                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
651                         needDumpSeq = TRUE;
652                 }
653                 pAd->watchDogRxOverFlowCnt = 0;
654         }
655
656
657         for (idx = 0; idx < NUM_OF_TX_RING; idx++)
658         {
659                 pUrb = NULL;
660
661                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
662                 if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
663                 {
664                         pAd->watchDogTxPendingCnt[idx]++;
665
666                         if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
667                                  (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
668                                 )
669                         {
670                                 // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
671                                 pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
672                                 if (pHTTXContext->IRPPending)
673                                 {       // Check TxContext.
674                                         pUrb = pHTTXContext->pUrb;
675                                 }
676                                 else if (idx == MGMTPIPEIDX)
677                                 {
678                                         PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
679
680                                         //Check MgmtContext.
681                                         pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
682                                         pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
683                                         pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
684
685                                         if (pMLMEContext->IRPPending)
686                                         {
687                                                 ASSERT(pMLMEContext->IRPPending);
688                                                 pUrb = pMLMEContext->pUrb;
689                                         }
690                                         else if (pNULLContext->IRPPending)
691                                         {
692                                                 ASSERT(pNULLContext->IRPPending);
693                                                 pUrb = pNULLContext->pUrb;
694                                         }
695                                         else if (pPsPollContext->IRPPending)
696                                         {
697                                                 ASSERT(pPsPollContext->IRPPending);
698                                                 pUrb = pPsPollContext->pUrb;
699                                         }
700                                 }
701
702                                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
703
704                                 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
705                                 if (pUrb)
706                                 {
707                                         DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
708                                         // unlink it now
709                                         RTUSB_UNLINK_URB(pUrb);
710                                         // Sleep 200 microseconds to give cancellation time to work
711                                         RTMPusecDelay(200);
712                                         needDumpSeq = TRUE;
713                                 }
714                                 else
715                                 {
716                                         DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
717                                 }
718                         }
719                         else
720                         {
721                                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
722                         }
723                 }
724                 else
725                 {
726                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
727                 }
728         }
729
730 #ifdef DOT11_N_SUPPORT
731         // For Sigma debug, dump the ba_reordering sequence.
732         if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
733         {
734                 USHORT                          Idx;
735                 PBA_REC_ENTRY           pBAEntry = NULL;
736                 UCHAR                           count = 0;
737                 struct reordering_mpdu *mpdu_blk;
738
739                 Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
740
741                 pBAEntry = &pAd->BATable.BARecEntry[Idx];
742                 if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
743                 {
744                         DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
745                         NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
746                         mpdu_blk = pBAEntry->list.next;
747                         while (mpdu_blk)
748                         {
749                                 DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
750                                 mpdu_blk = mpdu_blk->next;
751                                 count++;
752                         }
753
754                         DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
755                         NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
756                 }
757         }
758 #endif // DOT11_N_SUPPORT //
759 }
760
761 /*
762 ========================================================================
763 Routine Description:
764     Release allocated resources.
765
766 Arguments:
767     *dev                                Point to the PCI or USB device
768         pAd                                     driver control block pointer
769
770 Return Value:
771     None
772
773 Note:
774 ========================================================================
775 */
776 static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
777 {
778         struct net_device       *net_dev = NULL;
779
780
781         DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
782                                 dev->bus->bus_name, dev->devpath));
783         if (!pAd)
784         {
785 #ifdef MULTIPLE_CARD_SUPPORT
786                 if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD))
787                         MC_CardUsed[pAd->MC_RowID] = 0; // not clear MAC address
788 #endif // MULTIPLE_CARD_SUPPORT //
789
790                 usb_put_dev(dev);
791
792                 printk("rtusb_disconnect: pAd == NULL!\n");
793                 return;
794         }
795         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
796
797
798
799         // for debug, wait to show some messages to /proc system
800         udelay(1);
801
802
803
804
805         net_dev = pAd->net_dev;
806         if (pAd->net_dev != NULL)
807         {
808                 printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
809                 unregister_netdev (pAd->net_dev);
810         }
811         udelay(1);
812         flush_scheduled_work();
813         udelay(1);
814
815         // free net_device memory
816         free_netdev(net_dev);
817
818         // free adapter memory
819         RTMPFreeAdapter(pAd);
820
821         // release a use of the usb device structure
822         usb_put_dev(dev);
823         udelay(1);
824
825         DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
826 }
827
828
829 /*
830 ========================================================================
831 Routine Description:
832     Probe RT28XX chipset.
833
834 Arguments:
835     *dev                                Point to the PCI or USB device
836         interface
837         *id_table                       Point to the PCI or USB device ID
838
839 Return Value:
840     None
841
842 Note:
843 ========================================================================
844 */
845 static int rtusb_probe (struct usb_interface *intf,
846                                                 const struct usb_device_id *id)
847 {
848         PRTMP_ADAPTER pAd;
849         return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
850 }
851
852
853 static void rtusb_disconnect(struct usb_interface *intf)
854 {
855         struct usb_device   *dev = interface_to_usbdev(intf);
856         PRTMP_ADAPTER       pAd;
857
858
859         pAd = usb_get_intfdata(intf);
860         usb_set_intfdata(intf, NULL);
861
862         _rtusb_disconnect(dev, pAd);
863 }
864
865
866 /*
867 ========================================================================
868 Routine Description:
869     Close kernel threads.
870
871 Arguments:
872         *pAd                            the raxx interface data pointer
873
874 Return Value:
875     NONE
876
877 Note:
878 ========================================================================
879 */
880 VOID RT28xxThreadTerminate(
881         IN RTMP_ADAPTER *pAd)
882 {
883         POS_COOKIE      pObj = (POS_COOKIE) pAd->OS_Cookie;
884         INT                     ret;
885
886
887         // Sleep 50 milliseconds so pending io might finish normally
888         RTMPusecDelay(50000);
889
890         // We want to wait until all pending receives and sends to the
891         // device object. We cancel any
892         // irps. Wait until sends and receives have stopped.
893         RTUSBCancelPendingIRPs(pAd);
894
895         // Terminate Threads
896         if (pObj->MLMEThr_pid)
897         {
898                 printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid));
899                 mb();
900                 pAd->mlme_kill = 1;
901                 //RT28XX_MLME_HANDLER(pAd);
902                 mb();
903                 ret = kill_pid(pObj->MLMEThr_pid, SIGTERM, 1);
904                 if (ret)
905                 {
906                         printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
907                                         pAd->net_dev->name, pid_nr(pObj->MLMEThr_pid), ret);
908                 }
909                 else
910                 {
911                         //wait_for_completion (&pAd->notify);
912                         wait_for_completion (&pAd->mlmeComplete);
913                         pObj->MLMEThr_pid = NULL;
914                 }
915         }
916
917         if (pObj->RTUSBCmdThr_pid >= 0)
918         {
919                 printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid));
920                 mb();
921                 NdisAcquireSpinLock(&pAd->CmdQLock);
922                 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
923                 NdisReleaseSpinLock(&pAd->CmdQLock);
924                 mb();
925                 //RTUSBCMDUp(pAd);
926                 ret = kill_pid(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
927                 if (ret)
928                 {
929                         printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
930                                         pAd->net_dev->name, pid_nr(pObj->RTUSBCmdThr_pid), ret);
931                 }
932                 else
933                 {
934                         //wait_for_completion (&pAd->notify);
935                         wait_for_completion (&pAd->CmdQComplete);
936                         pObj->RTUSBCmdThr_pid = NULL;
937                 }
938         }
939         if (pObj->TimerQThr_pid >= 0)
940         {
941                 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
942
943                 printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid));
944                 mb();
945                 pAd->TimerFunc_kill = 1;
946                 mb();
947                 ret = kill_pid(pObj->TimerQThr_pid, SIGTERM, 1);
948                 if (ret)
949                 {
950                         printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
951                                         pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret);
952                 }
953                 else
954                 {
955                         printk("wait_for_completion TimerQThr\n");
956                         wait_for_completion(&pAd->TimerQComplete);
957                         pObj->TimerQThr_pid = NULL;
958                 }
959         }
960         // Kill tasklets
961         pAd->mlme_kill = 0;
962         pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
963         pAd->TimerFunc_kill = 0;
964 }
965
966
967 void kill_thread_task(IN PRTMP_ADAPTER pAd)
968 {
969         POS_COOKIE pObj;
970
971         pObj = (POS_COOKIE) pAd->OS_Cookie;
972
973         tasklet_kill(&pObj->rx_done_task);
974         tasklet_kill(&pObj->mgmt_dma_done_task);
975         tasklet_kill(&pObj->ac0_dma_done_task);
976         tasklet_kill(&pObj->ac1_dma_done_task);
977         tasklet_kill(&pObj->ac2_dma_done_task);
978         tasklet_kill(&pObj->ac3_dma_done_task);
979         tasklet_kill(&pObj->hcca_dma_done_task);
980         tasklet_kill(&pObj->tbtt_task);
981
982 }
983
984
985 /*
986 ========================================================================
987 Routine Description:
988     Check the chipset vendor/product ID.
989
990 Arguments:
991     _dev_p                              Point to the PCI or USB device
992
993 Return Value:
994     TRUE                                Check ok
995         FALSE                           Check fail
996
997 Note:
998 ========================================================================
999 */
1000 BOOLEAN RT28XXChipsetCheck(
1001         IN void *_dev_p)
1002 {
1003         struct usb_interface *intf = (struct usb_interface *)_dev_p;
1004         struct usb_device *dev_p = interface_to_usbdev(intf);
1005         UINT32 i;
1006
1007
1008         for(i=0; i<rtusb_usb_id_len; i++)
1009         {
1010                 if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
1011                         dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
1012                 {
1013                         printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
1014                                         dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
1015                         break;
1016                 }
1017         }
1018
1019         if (i == rtusb_usb_id_len)
1020         {
1021                 printk("rt2870: Error! Device Descriptor not matching!\n");
1022                 return FALSE;
1023         }
1024
1025         return TRUE;
1026 }
1027
1028
1029 /*
1030 ========================================================================
1031 Routine Description:
1032     Init net device structure.
1033
1034 Arguments:
1035     _dev_p                              Point to the PCI or USB device
1036     *net_dev                    Point to the net device
1037         *pAd                            the raxx interface data pointer
1038
1039 Return Value:
1040     TRUE                                Init ok
1041         FALSE                           Init fail
1042
1043 Note:
1044 ========================================================================
1045 */
1046 BOOLEAN RT28XXNetDevInit(
1047         IN void                                 *_dev_p,
1048         IN struct  net_device   *net_dev,
1049         IN RTMP_ADAPTER                 *pAd)
1050 {
1051         struct usb_interface *intf = (struct usb_interface *)_dev_p;
1052         struct usb_device *dev_p = interface_to_usbdev(intf);
1053
1054
1055         pAd->config = &dev_p->config->desc;
1056         return TRUE;
1057 }
1058
1059
1060 /*
1061 ========================================================================
1062 Routine Description:
1063     Init net device structure.
1064
1065 Arguments:
1066     _dev_p                              Point to the PCI or USB device
1067         *pAd                            the raxx interface data pointer
1068
1069 Return Value:
1070     TRUE                                Config ok
1071         FALSE                           Config fail
1072
1073 Note:
1074 ========================================================================
1075 */
1076 BOOLEAN RT28XXProbePostConfig(
1077         IN void                                 *_dev_p,
1078         IN RTMP_ADAPTER                 *pAd,
1079         IN INT32                                interface)
1080 {
1081         struct usb_interface *intf = (struct usb_interface *)_dev_p;
1082         struct usb_host_interface *iface_desc;
1083         ULONG BulkOutIdx;
1084         UINT32 i;
1085
1086
1087         /* get the active interface descriptor */
1088         iface_desc = intf->cur_altsetting;
1089
1090         /* get # of enpoints  */
1091         pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
1092         DBGPRINT(RT_DEBUG_TRACE,
1093                         ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
1094
1095         /* Configure Pipes */
1096         BulkOutIdx = 0;
1097
1098         for(i=0; i<pAd->NumberOfPipes; i++)
1099         {
1100                 if ((iface_desc->endpoint[i].desc.bmAttributes ==
1101                                 USB_ENDPOINT_XFER_BULK) &&
1102                         ((iface_desc->endpoint[i].desc.bEndpointAddress &
1103                                 USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
1104                 {
1105                         pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
1106                         pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1107
1108                         DBGPRINT_RAW(RT_DEBUG_TRACE,
1109                                 ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
1110                         DBGPRINT_RAW(RT_DEBUG_TRACE,
1111                                 ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
1112                 }
1113                 else if ((iface_desc->endpoint[i].desc.bmAttributes ==
1114                                         USB_ENDPOINT_XFER_BULK) &&
1115                                 ((iface_desc->endpoint[i].desc.bEndpointAddress &
1116                                         USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
1117                 {
1118                         // there are 6 bulk out EP. EP6 highest priority.
1119                         // EP1-4 is EDCA.  EP5 is HCCA.
1120                         pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
1121                         pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1122
1123                         DBGPRINT_RAW(RT_DEBUG_TRACE,
1124                                 ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
1125                         DBGPRINT_RAW(RT_DEBUG_TRACE,
1126                                 ("EP address = 0x%2x  \n", iface_desc->endpoint[i].desc.bEndpointAddress));
1127                 }
1128         }
1129
1130         if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
1131         {
1132                 printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __func__);
1133                 return FALSE;
1134         }
1135
1136         return TRUE;
1137 }
1138
1139
1140 /*
1141 ========================================================================
1142 Routine Description:
1143     Disable DMA.
1144
1145 Arguments:
1146         *pAd                            the raxx interface data pointer
1147
1148 Return Value:
1149         None
1150
1151 Note:
1152 ========================================================================
1153 */
1154 VOID RT28XXDMADisable(
1155         IN RTMP_ADAPTER                 *pAd)
1156 {
1157         // no use
1158 }
1159
1160
1161
1162 /*
1163 ========================================================================
1164 Routine Description:
1165     Enable DMA.
1166
1167 Arguments:
1168         *pAd                            the raxx interface data pointer
1169
1170 Return Value:
1171         None
1172
1173 Note:
1174 ========================================================================
1175 */
1176 VOID RT28XXDMAEnable(
1177         IN RTMP_ADAPTER                 *pAd)
1178 {
1179         WPDMA_GLO_CFG_STRUC     GloCfg;
1180         USB_DMA_CFG_STRUC       UsbCfg;
1181         int                                     i = 0;
1182
1183
1184         RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
1185         do
1186         {
1187                 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1188                 if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
1189                         break;
1190
1191                 DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
1192                 RTMPusecDelay(1000);
1193                 i++;
1194         }while ( i <200);
1195
1196
1197         RTMPusecDelay(50);
1198         GloCfg.field.EnTXWriteBackDDONE = 1;
1199         GloCfg.field.EnableRxDMA = 1;
1200         GloCfg.field.EnableTxDMA = 1;
1201         DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
1202         RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1203
1204         UsbCfg.word = 0;
1205         UsbCfg.field.phyclear = 0;
1206         /* usb version is 1.1,do not use bulk in aggregation */
1207         if (pAd->BulkInMaxPacketSize == 512)
1208                         UsbCfg.field.RxBulkAggEn = 1;
1209         /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
1210         UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
1211         UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
1212         UsbCfg.field.RxBulkEn = 1;
1213         UsbCfg.field.TxBulkEn = 1;
1214
1215         RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
1216
1217 }
1218
1219 /*
1220 ========================================================================
1221 Routine Description:
1222     Write Beacon buffer to Asic.
1223
1224 Arguments:
1225         *pAd                            the raxx interface data pointer
1226
1227 Return Value:
1228         None
1229
1230 Note:
1231 ========================================================================
1232 */
1233 VOID RT28xx_UpdateBeaconToAsic(
1234         IN RTMP_ADAPTER         *pAd,
1235         IN INT                          apidx,
1236         IN ULONG                        FrameLen,
1237         IN ULONG                        UpdatePos)
1238 {
1239         PUCHAR          pBeaconFrame = NULL;
1240         UCHAR                   *ptr;
1241         UINT                    i, padding;
1242         BEACON_SYNC_STRUCT      *pBeaconSync = pAd->CommonCfg.pBeaconSync;
1243         UINT32                  longValue;
1244 //      USHORT                  shortValue;
1245         BOOLEAN                 bBcnReq = FALSE;
1246         UCHAR                   bcn_idx = 0;
1247
1248
1249         if (pBeaconFrame == NULL)
1250         {
1251                 DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
1252                 return;
1253         }
1254
1255         if (pBeaconSync == NULL)
1256         {
1257                 DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
1258                 return;
1259         }
1260
1261         //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
1262         //      ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
1263         //      )
1264         if (bBcnReq == FALSE)
1265         {
1266                 /* when the ra interface is down, do not send its beacon frame */
1267                 /* clear all zero */
1268                 for(i=0; i<TXWI_SIZE; i+=4) {
1269                         RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
1270                 }
1271                 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1272                 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
1273         }
1274         else
1275         {
1276                 ptr = (PUCHAR)&pAd->BeaconTxWI;
1277 #ifdef RT_BIG_ENDIAN
1278                 RTMPWIEndianChange(ptr, TYPE_TXWI);
1279 #endif
1280                 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
1281                 {       // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
1282                         pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1283                         NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
1284                 }
1285
1286                 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
1287                 {
1288                         for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
1289                         {
1290                                 longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1291                                 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
1292                                 ptr += 4;
1293                         }
1294                 }
1295
1296                 ptr = pBeaconSync->BeaconBuf[bcn_idx];
1297                 padding = (FrameLen & 0x01);
1298                 NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
1299                 FrameLen += padding;
1300                 for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
1301                 {
1302                         if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
1303                         {
1304                                 NdisMoveMemory(ptr, pBeaconFrame, 2);
1305                                 //shortValue = *ptr + (*(ptr+1)<<8);
1306                                 //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
1307                                 RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
1308                         }
1309                         ptr +=2;
1310                         pBeaconFrame += 2;
1311                 }
1312
1313                 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
1314
1315                 // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
1316         }
1317
1318 }
1319
1320
1321 VOID RT2870_BssBeaconStop(
1322         IN RTMP_ADAPTER *pAd)
1323 {
1324         BEACON_SYNC_STRUCT      *pBeaconSync;
1325         int i, offset;
1326         BOOLEAN Cancelled = TRUE;
1327
1328         pBeaconSync = pAd->CommonCfg.pBeaconSync;
1329         if (pBeaconSync && pBeaconSync->EnableBeacon)
1330         {
1331                 INT NumOfBcn;
1332
1333
1334 #ifdef CONFIG_STA_SUPPORT
1335                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1336                 {
1337                         NumOfBcn = MAX_MESH_NUM;
1338                 }
1339 #endif // CONFIG_STA_SUPPORT //
1340
1341                 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1342
1343                 for(i=0; i<NumOfBcn; i++)
1344                 {
1345                         NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1346                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1347
1348                         for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
1349                                 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
1350
1351                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1352                         pBeaconSync->TimIELocationInBeacon[i] = 0;
1353                 }
1354                 pBeaconSync->BeaconBitMap = 0;
1355                 pBeaconSync->DtimBitOn = 0;
1356         }
1357 }
1358
1359
1360 VOID RT2870_BssBeaconStart(
1361         IN RTMP_ADAPTER *pAd)
1362 {
1363         int apidx;
1364         BEACON_SYNC_STRUCT      *pBeaconSync;
1365 //      LARGE_INTEGER   tsfTime, deltaTime;
1366
1367         pBeaconSync = pAd->CommonCfg.pBeaconSync;
1368         if (pBeaconSync && pBeaconSync->EnableBeacon)
1369         {
1370                 INT NumOfBcn;
1371
1372
1373 #ifdef CONFIG_STA_SUPPORT
1374                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1375                 {
1376                         NumOfBcn = MAX_MESH_NUM;
1377                 }
1378 #endif // CONFIG_STA_SUPPORT //
1379
1380                 for(apidx=0; apidx<NumOfBcn; apidx++)
1381                 {
1382                         UCHAR CapabilityInfoLocationInBeacon = 0;
1383                         UCHAR TimIELocationInBeacon = 0;
1384
1385 #ifdef CONFIG_STA_SUPPORT
1386 #endif // CONFIG_STA_SUPPORT //
1387
1388                         NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
1389                         pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
1390                         pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
1391                         NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
1392                 }
1393                 pBeaconSync->BeaconBitMap = 0;
1394                 pBeaconSync->DtimBitOn = 0;
1395                 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
1396
1397                 pAd->CommonCfg.BeaconAdjust = 0;
1398                 pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
1399                 pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
1400                 printk("RT2870_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
1401                 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
1402
1403         }
1404 }
1405
1406
1407 VOID RT2870_BssBeaconInit(
1408         IN RTMP_ADAPTER *pAd)
1409 {
1410         BEACON_SYNC_STRUCT      *pBeaconSync;
1411         int i;
1412
1413         NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
1414         if (pAd->CommonCfg.pBeaconSync)
1415         {
1416                 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1417                 NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
1418                 for(i=0; i < HW_BEACON_MAX_COUNT; i++)
1419                 {
1420                         NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1421                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1422                         pBeaconSync->TimIELocationInBeacon[i] = 0;
1423                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1424                 }
1425                 pBeaconSync->BeaconBitMap = 0;
1426
1427                 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
1428                 pBeaconSync->EnableBeacon = TRUE;
1429         }
1430 }
1431
1432
1433 VOID RT2870_BssBeaconExit(
1434         IN RTMP_ADAPTER *pAd)
1435 {
1436         BEACON_SYNC_STRUCT      *pBeaconSync;
1437         BOOLEAN Cancelled = TRUE;
1438         int i;
1439
1440         if (pAd->CommonCfg.pBeaconSync)
1441         {
1442                 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1443                 pBeaconSync->EnableBeacon = FALSE;
1444                 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1445                 pBeaconSync->BeaconBitMap = 0;
1446
1447                 for(i=0; i<HW_BEACON_MAX_COUNT; i++)
1448                 {
1449                         NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1450                         pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1451                         pBeaconSync->TimIELocationInBeacon[i] = 0;
1452                         NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1453                 }
1454
1455                 NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
1456                 pAd->CommonCfg.pBeaconSync = NULL;
1457         }
1458 }
1459
1460 VOID BeaconUpdateExec(
1461     IN PVOID SystemSpecific1,
1462     IN PVOID FunctionContext,
1463     IN PVOID SystemSpecific2,
1464     IN PVOID SystemSpecific3)
1465 {
1466         PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER)FunctionContext;
1467         LARGE_INTEGER   tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
1468         UINT32                  delta, remain, remain_low, remain_high;
1469 //      BOOLEAN                 positive;
1470
1471         ReSyncBeaconTime(pAd);
1472
1473
1474
1475         RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1476         RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1477
1478
1479         //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1480         remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1481         remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1482         remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
1483         delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1484
1485         pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;
1486
1487 }
1488